Skip to content

Commit cd89e9a

Browse files
chore: deploy pipeline cleanup (#17788)
1 parent 4c78015 commit cd89e9a

23 files changed

+406
-331
lines changed

.github/scripts/construct-environments.mjs

Lines changed: 83 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
11
import { pathToFileURL } from "node:url";
22

3-
const VALID_MODES = new Set(["studio", "runtime"]);
3+
const VALID_MODES = new Set(["studio", "studio-preapproved", "runtime"]);
44
const DEFAULTS_BY_MODE = {
5-
studio: "dev,staging,prod",
6-
runtime: "at_ring1,at_ring2,tt_ring1,tt_ring2,prod_ring1,prod_ring2",
5+
"studio": "dev,staging,prod",
6+
"studio-preapproved": "dev,staging,preapproved-prod",
7+
"runtime": "at_ring1,at_ring2,tt_ring1,tt_ring2,prod_ring1,prod_ring2",
78
};
8-
const OVERRIDE_ENV_BY_MODE = {
9-
studio: "OVERRIDE_STUDIO_ENVIRONMENTS",
10-
runtime: "OVERRIDE_RUNTIME_RINGS",
9+
const OVERRIDE_DEFAULT_ENV_BY_MODE = {
10+
"studio": "OVERRIDE_DEFAULT_STUDIO_ENVIRONMENTS",
11+
"studio-preapproved": "OVERRIDE_DEFAULT_STUDIO_ENVIRONMENTS",
12+
"runtime": "OVERRIDE_DEFAULT_RUNTIME_ENVIRONMENTS",
1113
};
1214
const ALLOWED_VALUES_BY_MODE = {
13-
studio: new Set(DEFAULTS_BY_MODE.studio.split(",").map((value) => value.trim())),
14-
runtime: new Set(DEFAULTS_BY_MODE.runtime.split(",").map((value) => value.trim())),
15+
"studio": new Set(DEFAULTS_BY_MODE["studio"].split(",").map((value) => value.trim())),
16+
"studio-preapproved": new Set(
17+
DEFAULTS_BY_MODE["studio-preapproved"].split(",").map((value) => value.trim())
18+
),
19+
"runtime": new Set(DEFAULTS_BY_MODE["runtime"].split(",").map((value) => value.trim())),
1520
};
1621

1722
/**
1823
* Construct parsed output for studio or runtime environment inputs.
19-
* @param {{mode: string, value?: string, inputsJson?: string, allowEmpty?: boolean|string}} input
24+
* @param {{mode: string, inputs?: string, allowEmpty?: boolean|string}} input
2025
* @returns {Array<{environment: string, ring?: string}>}
2126
*/
2227
export function constructResult(input) {
2328
const mode = input.mode;
2429
if (!VALID_MODES.has(mode)) {
25-
throw new Error("mode must be 'studio' or 'runtime'.");
30+
throw new Error("mode must be 'studio', 'studio-preapproved', or 'runtime'.");
2631
}
2732

2833
const allowEmpty = parseBool(input.allowEmpty);
29-
const inputsJson = input.inputsJson ?? "null";
30-
let raw = input.value ?? "";
34+
const inputs = input.inputs ?? "null";
35+
const parsedInputs = parseInputs(inputs);
36+
let raw = "";
3137

32-
// No workflow_dispatch inputs context (e.g. push) with no explicit value:
38+
if (raw === "" && parsedInputs !== null) {
39+
raw = getEnvironmentsFromInputs(parsedInputs);
40+
}
41+
42+
// No workflow_dispatch inputs context (e.g. push) with no explicit value/input:
3343
// use override when present, otherwise mode defaults.
34-
if (inputsJson === "null" && raw === "") {
35-
raw = getOverrideValue(mode) || DEFAULTS_BY_MODE[mode];
44+
if (raw === "" && parsedInputs === null) {
45+
raw = getDefaultOverrideValue(mode) || DEFAULTS_BY_MODE[mode];
3646
}
3747

3848
if (raw === "") {
@@ -43,18 +53,66 @@ export function constructResult(input) {
4353
}
4454

4555
const values = splitCsvStrict(raw);
56+
const allowedValues = ALLOWED_VALUES_BY_MODE[mode];
4657
switch (mode) {
4758
case "studio":
48-
validateValues(values, ALLOWED_VALUES_BY_MODE.studio, "studio environment");
59+
case "studio-preapproved":
60+
validateValues(values, allowedValues, "studio environment");
4961
return values.map((environment) => ({ environment }));
5062
case "runtime":
51-
validateValues(values, ALLOWED_VALUES_BY_MODE.runtime, "runtime ring");
63+
validateValues(values, allowedValues, "runtime ring");
5264
return values.map((ring) => ({ ring, environment: `runtime_${ring}` }));
5365
default:
5466
throw new Error("unreachable mode.");
5567
}
5668
}
5769

70+
/**
71+
* @param {string} inputs
72+
* @returns {Record<string, unknown> | null}
73+
*/
74+
function parseInputs(inputs) {
75+
if (inputs === "null") {
76+
return null;
77+
}
78+
79+
let parsed;
80+
try {
81+
parsed = JSON.parse(inputs);
82+
} catch {
83+
throw new Error("inputs must be valid JSON.");
84+
}
85+
86+
if (parsed === null) {
87+
return null;
88+
}
89+
90+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
91+
throw new Error("inputs must be an object or null.");
92+
}
93+
94+
return parsed;
95+
}
96+
97+
/**
98+
* @param {Record<string, unknown>} parsedInputs
99+
* @returns {string}
100+
*/
101+
function getEnvironmentsFromInputs(parsedInputs) {
102+
if (!("environments" in parsedInputs)) {
103+
return "";
104+
}
105+
106+
const value = parsedInputs.environments;
107+
if (value === null || value === undefined) {
108+
return "";
109+
}
110+
if (typeof value !== "string") {
111+
throw new Error("input 'environments' must be a string.");
112+
}
113+
return value;
114+
}
115+
58116
/**
59117
* @param {string} raw
60118
* @returns {string[]}
@@ -92,22 +150,21 @@ function parseBool(value) {
92150
}
93151

94152
/**
95-
* @param {"studio"|"runtime"} mode
153+
* @param {"studio"|"studio-preapproved"|"runtime"} mode
96154
* @returns {string}
97155
*/
98-
function getOverrideValue(mode) {
99-
return (process.env[OVERRIDE_ENV_BY_MODE[mode]] ?? "").trim();
156+
function getDefaultOverrideValue(mode) {
157+
return (process.env[OVERRIDE_DEFAULT_ENV_BY_MODE[mode]] ?? "").trim();
100158
}
101159

102160
/**
103161
* @param {string[]} argv
104-
* @returns {{mode: string, value: string, inputsJson: string, allowEmpty: string}}
162+
* @returns {{mode: string, inputs: string, allowEmpty: string}}
105163
*/
106164
function parseArgs(argv) {
107165
const args = {
108166
mode: "",
109-
value: "",
110-
inputsJson: "null",
167+
inputs: "null",
111168
allowEmpty: "false",
112169
};
113170

@@ -125,11 +182,8 @@ function parseArgs(argv) {
125182
case "--mode":
126183
args.mode = next;
127184
break;
128-
case "--value":
129-
args.value = next;
130-
break;
131-
case "--inputs-json":
132-
args.inputsJson = next;
185+
case "--inputs":
186+
args.inputs = next;
133187
break;
134188
case "--allow-empty":
135189
args.allowEmpty = next;
@@ -148,8 +202,7 @@ if (import.meta.url === pathToFileURL(process.argv[1]).href) {
148202
const args = parseArgs(process.argv.slice(2));
149203
const result = constructResult({
150204
mode: args.mode,
151-
value: args.value,
152-
inputsJson: args.inputsJson,
205+
inputs: args.inputs,
153206
allowEmpty: args.allowEmpty,
154207
});
155208
process.stdout.write(`${JSON.stringify(result)}\n`);

0 commit comments

Comments
 (0)