mirror of
https://github.com/firecow/gitlab-ci-local.git
synced 2026-10-16 04:16:55 +02:00
fix: carry a job's !reference through extends at every depth (#1970)
build / yamllint (push) Has been cancelled
build / smoke-test (1.2.23, 24) (push) Has been cancelled
build / smoke-test (1.2.23, 25) (push) Has been cancelled
build / smoke-test (1.3.10, 24) (push) Has been cancelled
build / smoke-test (1.3.10, 25) (push) Has been cancelled
build / typecheck (push) Has been cancelled
build / eslint (push) Has been cancelled
build / unused-deps (push) Has been cancelled
build / test (push) Has been cancelled
build / CodeQL (push) Has been cancelled
build / yamllint (push) Has been cancelled
build / smoke-test (1.2.23, 24) (push) Has been cancelled
build / smoke-test (1.2.23, 25) (push) Has been cancelled
build / smoke-test (1.3.10, 24) (push) Has been cancelled
build / smoke-test (1.3.10, 25) (push) Has been cancelled
build / typecheck (push) Has been cancelled
build / eslint (push) Has been cancelled
build / unused-deps (push) Has been cancelled
build / test (push) Has been cancelled
build / CodeQL (push) Has been cancelled
Co-authored-by: tran4774 <59108692+tran4774@users.noreply.github.com>
This commit is contained in:
1 parent
86ba8e23aa
commit
74778ea8a9
3 files changed
+114
-10
No files matched your search
+11
-8
@@ -1,10 +1,18 @@
|
||||
import chalk from "chalk-template";
|
||||
import deepExtend from "deep-extend";
|
||||
import assert, {AssertionError} from "node:assert";
|
||||
import {Job, Need} from "./job.js";
|
||||
import {getNodeByPath, traverse} from "object-traversal";
|
||||
import {traverse} from "object-traversal";
|
||||
import {Utils} from "./utils.js";
|
||||
|
||||
const isMergeable = (value: any) => value != null && Utils.isObject(value) && value.referenceData == null;
|
||||
const extendsMerge = (target: any, source: any): any => {
|
||||
if (!isMergeable(target) || !isMergeable(source)) return structuredClone(source);
|
||||
for (const [key, value] of Object.entries(source)) {
|
||||
target[key] = extendsMerge(target[key], value);
|
||||
}
|
||||
return target;
|
||||
};
|
||||
|
||||
const extendsMaxDepth = 11;
|
||||
const extendsRecurse = (gitlabData: any, jobName: string, jobData: any, parents: any[], depth: number) => {
|
||||
assert(depth < extendsMaxDepth, chalk`{blueBright ${jobName}}: circular dependency detected in \`extends\``);
|
||||
@@ -27,12 +35,7 @@ export function jobExtends (gitlabData: any) {
|
||||
if (Job.illegalJobNames.has(jobName)) continue;
|
||||
if (!Utils.isObject(jobData)) continue;
|
||||
const parentDatas = extendsRecurse(gitlabData, jobName, jobData, [], 0);
|
||||
const mergedData = deepExtend({}, ...parentDatas, jobData);
|
||||
traverse(jobData, ({key, value, meta}) => {
|
||||
if (key == null || value?.referenceData == null) return;
|
||||
getNodeByPath(mergedData, meta.nodePath!.slice(0, -key.length - 1))[key] = value;
|
||||
});
|
||||
gitlabData[jobName] = mergedData;
|
||||
gitlabData[jobName] = [...parentDatas, jobData].reduce((mergedData, data) => extendsMerge(mergedData, data), {});
|
||||
}
|
||||
|
||||
for (const [jobName, jobData] of Object.entries<any>(gitlabData)) {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
.src:
|
||||
cache:
|
||||
key: src
|
||||
paths: [a, b, jib]
|
||||
|
||||
.setup:
|
||||
cache:
|
||||
key: setup
|
||||
paths: [a, b]
|
||||
|
||||
holder:
|
||||
extends: .setup
|
||||
script:
|
||||
- echo "Heya"
|
||||
cache: !reference [.src, cache]
|
||||
|
||||
inherits:
|
||||
extends: holder
|
||||
|
||||
overrides:
|
||||
extends: holder
|
||||
cache:
|
||||
key: own
|
||||
paths: [own]
|
||||
|
||||
.key-src:
|
||||
key:
|
||||
files: [k.lock]
|
||||
|
||||
.key-setup:
|
||||
cache:
|
||||
key:
|
||||
files: [setup.lock]
|
||||
prefix: setup
|
||||
paths: [a, b]
|
||||
|
||||
nested:
|
||||
extends: [holder, .key-setup]
|
||||
cache:
|
||||
key: !reference [.key-src, key]
|
||||
@@ -159,7 +159,7 @@ test.concurrent("should not support 11 level deep", async () => {
|
||||
throw new Error("Error is expected but not thrown/caught");
|
||||
});
|
||||
|
||||
it("should merge values", async () => {
|
||||
it("should let a job's own value replace an inherited reference", async () => {
|
||||
const writeStreams = new WriteStreamsMock();
|
||||
await handler({
|
||||
preview: true,
|
||||
@@ -177,7 +177,6 @@ stages:
|
||||
- .post
|
||||
test-job:
|
||||
variables:
|
||||
HESTHEST: ponypony
|
||||
NICENESS: byrdalos
|
||||
script:
|
||||
- echo \${NICENESS}
|
||||
@@ -274,3 +273,64 @@ job:
|
||||
|
||||
expect(writeStreams.stdoutLines.join("\n")).toEqual(expected.trim());
|
||||
});
|
||||
|
||||
it("should carry a reference through a job that extends the one holding it", async () => {
|
||||
const writeStreams = new WriteStreamsMock();
|
||||
await handler({
|
||||
preview: true,
|
||||
file: ".gitlab-ci-inherited-reference.yml",
|
||||
cwd: "tests/test-cases/reference",
|
||||
}, writeStreams);
|
||||
|
||||
const expected = `
|
||||
---
|
||||
stages:
|
||||
- .pre
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
- .post
|
||||
holder:
|
||||
cache:
|
||||
- key: src
|
||||
paths: &ref_0
|
||||
- a
|
||||
- b
|
||||
- jib
|
||||
policy: pull-push
|
||||
when: on_success
|
||||
script:
|
||||
- echo "Heya"
|
||||
inherits:
|
||||
cache:
|
||||
- key: src
|
||||
paths: *ref_0
|
||||
policy: pull-push
|
||||
when: on_success
|
||||
script:
|
||||
- echo "Heya"
|
||||
overrides:
|
||||
cache:
|
||||
- key: own
|
||||
paths:
|
||||
- own
|
||||
policy: pull-push
|
||||
when: on_success
|
||||
script:
|
||||
- echo "Heya"
|
||||
nested:
|
||||
cache:
|
||||
- key:
|
||||
files:
|
||||
- k.lock
|
||||
paths:
|
||||
- a
|
||||
- b
|
||||
policy: pull-push
|
||||
when: on_success
|
||||
script:
|
||||
- echo "Heya"
|
||||
`;
|
||||
|
||||
expect(writeStreams.stdoutLines.join("\n")).toEqual(expected.trim());
|
||||
});
|
||||
Reference in new issue
Block a user