Skip to content

Commit 5f92c0c

Browse files
authored
fix: Utils.expandVariables should be pure and should not modify it's input (#1488)
1 parent 4376d0a commit 5f92c0c

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

src/utils.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,28 +118,29 @@ export class Utils {
118118
}
119119

120120
static expandVariables (variables: {[key: string]: string}) {
121+
const _variables = {...variables}; // copy by value to prevent mutating the original input
121122
let expandedAnyVariables, i = 0;
122123
do {
123124
assert(i < 100, "Recursive variable expansion reached 100 iterations");
124125
expandedAnyVariables = false;
125-
for (const [k, v] of Object.entries(variables)) {
126-
const envsWithoutSelf = {...variables};
126+
for (const [k, v] of Object.entries(_variables)) {
127+
const envsWithoutSelf = {..._variables};
127128
delete envsWithoutSelf[k];
128129
// If the $$'s are converted to single $'s now, then the next
129-
// iteration, they might be interpreted as variables, even
130+
// iteration, they might be interpreted as _variables, even
130131
// though they were *explicitly* escaped. To work around this,
131132
// leave the '$$'s as the same value, then only unescape them at
132133
// the very end.
133-
variables[k] = Utils.expandTextWith(v, {
134+
_variables[k] = Utils.expandTextWith(v, {
134135
unescape: "$$",
135136
variable: (name) => envsWithoutSelf[name] ?? "",
136137
});
137-
expandedAnyVariables ||= variables[k] !== v;
138+
expandedAnyVariables ||= _variables[k] !== v;
138139
}
139140
i++;
140141
} while (expandedAnyVariables);
141142

142-
return variables;
143+
return _variables;
143144
}
144145

145146
static unscape$$Variables (variables: {[key: string]: string}) {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
---
2+
job:
3+
stage: build
4+
image: busybox
5+
script:
6+
- echo "BUILD_IMAGE_REF=latest" > build.env
7+
artifacts:
8+
reports: { dotenv: build.env }
9+
10+
job2:
11+
stage: deploy
12+
variables:
13+
REF: $BUILD_IMAGE_REF
14+
image: busybox
15+
script:
16+
- echo $REF

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,17 @@ test("should expand rule variables in environment", async () => {
8989
const filteredStdout = writeStreams.stdoutLines.filter(f => f.startsWith("job environment")).join("\n");
9090
expect(filteredStdout).toEqual(expected);
9191
});
92+
93+
test("should expand variables referencing dotenv artifact variables", async () => {
94+
const writeStreams = new WriteStreamsMock();
95+
await handler({
96+
cwd: "tests/test-cases/variable-expansion",
97+
file: ".gitlab-ci-3.yml",
98+
noColor: true,
99+
}, writeStreams);
100+
101+
const expected = "job2 > latest";
102+
103+
const filteredStdout = writeStreams.stdoutLines.filter(f => f.startsWith("job2 >")).join("\n");
104+
expect(filteredStdout).toEqual(expected);
105+
});

0 commit comments

Comments
 (0)