History

Harden release workflow refs

Rhys Sullivan committed 6 months ago

Commit e360eb81 parent 82e014c6 files · +212 −22Browse files

Showing the changes to scripts (1 of 6 files). Show all

Unified · Split

scripts/validate-release-ref.ts+70−0
@@ -0,0 +1,70 @@
1#!/usr/bin/env bun
2import { appendFileSync } from "node:fs";
3
4const RELEASE_VERSION_PATTERN =
5 /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/u;
6
7export const validateReleaseVersion = (value: string): string => {
8 if (!RELEASE_VERSION_PATTERN.test(value)) {
9 throw new Error(`Invalid release version: ${value}`);
10 }
11 return value;
12};
13
14export const validateReleaseTag = (value: string): string => {
15 if (!value.startsWith("v")) {
16 throw new Error(`Invalid release tag: ${value}`);
17 }
18 validateReleaseVersion(value.slice(1));
19 return value;
20};
21
22const readEnv = (name: string): string => {
23 const value = process.env[name];
24 if (!value) {
25 throw new Error(`Missing environment variable: ${name}`);
26 }
27 return value;
28};
29
30const appendGitHubFile = (path: string | undefined, line: string): void => {
31 if (!path || !line) return;
32 appendFileSync(path, `${line}\n`, "utf8");
33};
34
35const run = (): void => {
36 const args = process.argv.slice(2);
37 const tagEnv = readOption(args, "--tag-env");
38 const versionEnv = readOption(args, "--version-env");
39 const writeEnv = readOption(args, "--write-env");
40 const outputName = readOption(args, "--output");
41
42 if (tagEnv && versionEnv) {
43 throw new Error("Use either --tag-env or --version-env, not both");
44 }
45 if (!tagEnv && !versionEnv) {
46 throw new Error("Expected --tag-env or --version-env");
47 }
48
49 const tag = tagEnv
50 ? validateReleaseTag(readEnv(tagEnv))
51 : `v${validateReleaseVersion(readEnv(versionEnv!))}`;
52
53 appendGitHubFile(process.env.GITHUB_ENV, writeEnv ? `${writeEnv}=${tag}` : "");
54 appendGitHubFile(process.env.GITHUB_OUTPUT, outputName ? `${outputName}=${tag}` : "");
55 console.log(`Validated release tag ${tag}`);
56};
57
58const readOption = (args: ReadonlyArray<string>, name: string): string | undefined => {
59 const index = args.indexOf(name);
60 if (index === -1) return undefined;
61 const value = args[index + 1];
62 if (!value || value.startsWith("--")) {
63 throw new Error(`Missing value for ${name}`);
64 }
65 return value;
66};
67
68if (import.meta.main) {
69 run();
70}