Skip to content

Commit fcccb7e

Browse files
bcouetilCopilot
andauthored
feat: implement workflow:rules:variables support (#1832) (#1833)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 06b3fdb commit fcccb7e

5 files changed

Lines changed: 94 additions & 0 deletions

File tree

src/parser.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,21 @@ export class Parser {
131131
DataExpander.inheritDefault(gitlabData);
132132
DataExpander.normalize(gitlabData);
133133

134+
// Evaluate workflow:rules and merge matched rule variables into global variables
135+
const workflowRules = gitlabData.workflow?.rules;
136+
if (workflowRules) {
137+
const globalVars = gitlabData.variables ?? {};
138+
const workflowVariables = {...predefinedVariables, ...globalVars, ...envMatchedVariables, ...argv.variable};
139+
const ruleResult = Utils.getRulesResult({argv, cwd, rules: workflowRules, variables: workflowVariables}, gitData, "on_success");
140+
if (ruleResult.variables) {
141+
const normalizedRuleVars: {[key: string]: string} = {};
142+
for (const [key, value] of Object.entries(ruleResult.variables)) {
143+
normalizedRuleVars[key] = Utils.normalizeVariables(value);
144+
}
145+
gitlabData.variables = {...globalVars, ...normalizedRuleVars};
146+
}
147+
}
148+
134149
assert(gitlabData.stages && Array.isArray(gitlabData.stages), chalk`{yellow stages:} must be an array`);
135150
if (!gitlabData.stages.includes(".pre")) {
136151
gitlabData.stages.unshift(".pre");
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
workflow:
3+
rules:
4+
- if: $CI_COMMIT_BRANCH
5+
variables:
6+
WORKFLOW_VAR: from-workflow-rules
7+
8+
test-job:
9+
stage: test
10+
variables:
11+
WORKFLOW_VAR: from-job
12+
script:
13+
- echo "WORKFLOW_VAR=${WORKFLOW_VAR}"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
workflow:
3+
rules:
4+
- if: $NONEXISTENT_VAR == 'something'
5+
variables:
6+
WORKFLOW_VAR: from-workflow-rules
7+
8+
test-job:
9+
stage: test
10+
script:
11+
- echo "WORKFLOW_VAR=${WORKFLOW_VAR}"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
workflow:
3+
rules:
4+
- if: $CI_COMMIT_BRANCH
5+
variables:
6+
WORKFLOW_VAR: from-workflow-rules
7+
8+
test-job:
9+
stage: test
10+
script:
11+
- echo "WORKFLOW_VAR=${WORKFLOW_VAR}"
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {WriteStreamsMock} from "../../../src/write-streams.js";
2+
import {handler} from "../../../src/handler.js";
3+
import {initSpawnSpy} from "../../mocks/utils.mock.js";
4+
import {WhenStatics} from "../../mocks/when-statics.js";
5+
6+
beforeAll(() => {
7+
initSpawnSpy(WhenStatics.all);
8+
});
9+
10+
// workflow:rules:variables should be applied as global variables when a rule matches
11+
test.concurrent("workflow-rules-variables are applied", async () => {
12+
const writeStreams = new WriteStreamsMock();
13+
await handler({
14+
cwd: "tests/test-cases/workflow-rules-variables",
15+
stateDir: ".gitlab-ci-local-workflow-rules-variables",
16+
}, writeStreams);
17+
18+
const output = writeStreams.stdoutLines.join("\n");
19+
expect(output).toContain("WORKFLOW_VAR=from-workflow-rules");
20+
});
21+
22+
test.concurrent("workflow-rules-variables not applied when rule does not match", async () => {
23+
const writeStreams = new WriteStreamsMock();
24+
await handler({
25+
cwd: "tests/test-cases/workflow-rules-variables",
26+
file: ".gitlab-ci-no-match.yml",
27+
stateDir: ".gitlab-ci-local-workflow-rules-variables-no-match",
28+
}, writeStreams);
29+
30+
const output = writeStreams.stdoutLines.join("\n");
31+
expect(output).not.toContain("WORKFLOW_VAR=from-workflow-rules");
32+
});
33+
34+
test.concurrent("workflow-rules-variables overridden by job variables", async () => {
35+
const writeStreams = new WriteStreamsMock();
36+
await handler({
37+
cwd: "tests/test-cases/workflow-rules-variables",
38+
file: ".gitlab-ci-job-override.yml",
39+
stateDir: ".gitlab-ci-local-workflow-rules-variables-job-override",
40+
}, writeStreams);
41+
42+
const output = writeStreams.stdoutLines.join("\n");
43+
expect(output).toContain("WORKFLOW_VAR=from-job");
44+
});

0 commit comments

Comments
 (0)