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
2+import { appendFileSync } from "node:fs";
3+
4+const 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+
7+export 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+
14+export 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+
22+const 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+
30+const appendGitHubFile = (path: string | undefined, line: string): void => {
31+ if (!path || !line) return;
32+ appendFileSync(path, `${line}\n`, "utf8");
33+};
34+
35+const 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+
58+const 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+
68+if (import.meta.main) {
69+ run();
70+}