Skip to content

Commit aa9934a

Browse files
authored
feat: support variables:expand (#1691)
1 parent 56a2e8a commit aa9934a

File tree

5 files changed

+75
-15
lines changed

5 files changed

+75
-15
lines changed

src/data-expander.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,7 @@ export function inheritDefault (gitlabData: any) {
221221

222222
function normalizeGlobalVariables (gitlabData: any) {
223223
for (const [key, value] of Object.entries<any>(gitlabData.variables ?? {})) {
224-
if (value === null) {
225-
gitlabData.variables[key] = ""; // variable's values are nullable
226-
} else if (Utils.isObject(value)) {
227-
gitlabData.variables[key] = String(value["value"]);
228-
} else {
229-
gitlabData.variables[key] = String(value);
230-
}
224+
gitlabData.variables[key] = Utils.normalizeVariables(value);
231225
}
232226
}
233227

src/parser.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,8 @@ export class Parser {
138138
assert(jobData.when !== "never",
139139
chalk`This GitLab CI configuration is invalid: jobs:${jobName} when:never can only be used in a rules section or workflow:rules`,
140140
);
141-
for (const [key, _value] of Object.entries(jobData.variables || {})) {
142-
let value = _value;
143-
if (value === null) value = ""; // variable's values are nullable
144-
assert(
145-
typeof value === "string" || typeof value === "number" || typeof value === "boolean",
146-
chalk`{blueBright ${jobName}} has invalid variables hash of key value pairs. ${key}=${value}`,
147-
);
148-
jobData.variables[key] = String(value);
141+
for (const [key, value] of Object.entries(jobData.variables ?? {})) {
142+
jobData.variables[key] = Utils.normalizeVariables(value);
149143
}
150144

151145
for (let i = 0; i < (jobData.services ?? []).length; i++) {

src/utils.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,4 +460,17 @@ export class Utils {
460460
}
461461
return {};
462462
}
463+
464+
static normalizeVariables (variable: any) {
465+
if (variable === null) {
466+
return ""; // variable's values are nullable
467+
} else if (Utils.isObject(variable)) {
468+
if (variable["expand"] === false) {
469+
return String(variable["value"]).replaceAll("$", () => "$$");
470+
}
471+
return String(variable["value"]);
472+
} else {
473+
return String(variable);
474+
}
475+
}
463476
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
variables:
3+
DEFAULT_VAR_1: "1"
4+
DEFAULT_VAR_2:
5+
value: 2 $DEFAULT_VAR_1
6+
expand: false
7+
DEFAULT_VAR_3:
8+
value: 3 $DEFAULT_VAR_1
9+
expand: true
10+
DEFAULT_VAR_4:
11+
# expect expand to be true by default
12+
value: 4 $DEFAULT_VAR_1
13+
14+
job:
15+
stage: build
16+
image: busybox
17+
variables:
18+
JOB_VAR_1: "1"
19+
JOB_VAR_2:
20+
value: 2 $JOB_VAR_1
21+
expand: false
22+
JOB_VAR_3:
23+
value: 3 $JOB_VAR_1
24+
expand: true
25+
JOB_VAR_4:
26+
# expect expand to be true by default
27+
value: 4 $JOB_VAR_1
28+
script:
29+
- echo $DEFAULT_VAR_1 # 1
30+
- echo $DEFAULT_VAR_2 # 2 $DEFAULT_VAR_1
31+
- echo $DEFAULT_VAR_3 # 3 1
32+
- echo $DEFAULT_VAR_4 # 4 1
33+
- echo $JOB_VAR_1 # 1
34+
- echo $JOB_VAR_2 # 2 $JOB_VAR_1
35+
- echo $JOB_VAR_3 # 3 1
36+
- echo $JOB_VAR_4 # 4 1

tests/test-cases/variable-expansion/integration.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,26 @@ test("should expand variables referencing dotenv artifact variables", async () =
103103
const filteredStdout = writeStreams.stdoutLines.filter(f => f.startsWith("job2 >")).join("\n");
104104
expect(filteredStdout).toEqual(expected);
105105
});
106+
107+
test("should support variables:expand", async () => {
108+
const writeStreams = new WriteStreamsMock();
109+
await handler({
110+
cwd: "tests/test-cases/variable-expansion",
111+
file: ".gitlab-ci-4.yml",
112+
noColor: true,
113+
}, writeStreams);
114+
115+
const expected = `
116+
job > 1
117+
job > 2 $DEFAULT_VAR_1
118+
job > 3 1
119+
job > 4 1
120+
job > 1
121+
job > 2 $JOB_VAR_1
122+
job > 3 1
123+
job > 4 1
124+
`;
125+
126+
const filteredStdout = writeStreams.stdoutLines.filter(f => f.startsWith("job >")).join("\n");
127+
expect(filteredStdout).toEqual(expected.trim());
128+
});

0 commit comments

Comments
 (0)