@intentius/chant-lexicon-gitlab 0.124.56 → 0.124.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/generate-op-waves-pipeline.d.ts +8 -0
- package/dist/components/generate-op-waves-pipeline.d.ts.map +1 -1
- package/dist/components/generate-op-waves-pipeline.js +13 -3
- package/dist/components/generate-pipeline.d.ts.map +1 -1
- package/dist/components/generate-pipeline.js +3 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +3 -3
- package/src/components/__golden__/op-waves-jobs.yml +8 -4
- package/src/components/generate-op-waves-pipeline.test.ts +11 -2
- package/src/components/generate-op-waves-pipeline.ts +13 -2
- package/src/components/generate-pipeline.ts +3 -0
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
* A wave's `environment` is the job's own `environment:`; protect it in the
|
|
19
19
|
* project settings to put a reviewer in front of the job as well.
|
|
20
20
|
*
|
|
21
|
+
* The wave jobs carry no `resource_group` (ruling for ci-products
|
|
22
|
+
* 2026-10-28, "Ledger lock"), the same as the GitHub and Forgejo waves files
|
|
23
|
+
* carry no concurrency group: a per-wave resource group would keep two
|
|
24
|
+
* pipelines' plunge stacks apart where their resource rows do not meet. A
|
|
25
|
+
* stock Pulumi stack or a Terraform root waits for its row on chant's ledger,
|
|
26
|
+
* oldest commit first, up to the job's `timeout`, which `CHANT_LOCK_WAIT`
|
|
27
|
+
* sits five minutes under; the project's own maximum timeout still caps it.
|
|
28
|
+
*
|
|
21
29
|
* With `resume` on the spec (#3683), a `<name>-resume` job runs `chant run
|
|
22
30
|
* resume --op <name>` in scheduled pipelines only: create a pipeline schedule
|
|
23
31
|
* with the spec's cron. It retries a waiting wave's job once its approval
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-op-waves-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-waves-pipeline.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generate-op-waves-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-op-waves-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AAkBH,OAAO,EAaL,KAAK,WAAW,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAO9F,yHAAyH;AACzH,eAAO,MAAM,oBAAoB,GAAoB,CAAC;AAEtD,gHAAgH;AAChH,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAuKvH"}
|
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
* A wave's `environment` is the job's own `environment:`; protect it in the
|
|
19
19
|
* project settings to put a reviewer in front of the job as well.
|
|
20
20
|
*
|
|
21
|
+
* The wave jobs carry no `resource_group` (ruling for ci-products
|
|
22
|
+
* 2026-10-28, "Ledger lock"), the same as the GitHub and Forgejo waves files
|
|
23
|
+
* carry no concurrency group: a per-wave resource group would keep two
|
|
24
|
+
* pipelines' plunge stacks apart where their resource rows do not meet. A
|
|
25
|
+
* stock Pulumi stack or a Terraform root waits for its row on chant's ledger,
|
|
26
|
+
* oldest commit first, up to the job's `timeout`, which `CHANT_LOCK_WAIT`
|
|
27
|
+
* sits five minutes under; the project's own maximum timeout still caps it.
|
|
28
|
+
*
|
|
21
29
|
* With `resume` on the spec (#3683), a `<name>-resume` job runs `chant run
|
|
22
30
|
* resume --op <name>` in scheduled pipelines only: create a pipeline schedule
|
|
23
31
|
* with the spec's cron. It retries a waiting wave's job once its approval
|
|
@@ -60,7 +68,7 @@
|
|
|
60
68
|
* after it stop.
|
|
61
69
|
*/
|
|
62
70
|
import { assertGitlabBranch, assertGitlabEnvironment, assertRunnerLabels, CI_IMAGE, environmentDoc, GITLAB_FULL_HISTORY, GITLAB_MERGE_REQUEST_SOURCE, GITLAB_SCHEDULE_SOURCE, gitlabIdTokensDoc, gitlabPushRule, gitlabSetupScript, gitlabTags, nonEmpty, pushBranches, } from "@intentius/chant/ci-jobs";
|
|
63
|
-
import { opWaveGroupOf, opWaveJobs, opWaveOutcomeDir, opWavesControlTarget, opWavesLastJobs, OP_WAVES_APPROVAL_STATUS_VAR, opWavesApprovalStatusCommand, opWavesPostsApprovalStatus, opWavesOutcomeCommand, opWavesRecordPlansCommand, opWavesResumeCommand, } from "@intentius/chant/op/op-waves";
|
|
71
|
+
import { opWaveGroupOf, opWaveJobs, opWaveJobTimeout, opWaveOutcomeDir, opWavesControlTarget, opWavesLastJobs, OP_WAVES_APPROVAL_STATUS_VAR, opWavesApprovalStatusCommand, opWavesPostsApprovalStatus, opWavesOutcomeCommand, opWavesRecordPlansCommand, opWavesResumeCommand, } from "@intentius/chant/op/op-waves";
|
|
64
72
|
import { CONTROL_OUTCOME_VAR, CONTROL_TOKEN_VARS, controlDispatchJob } from "@intentius/chant/control/dispatch";
|
|
65
73
|
import { gitlabTradeIdTokens, gitlabTradeLines, TRADE_SPEC_ENV } from "@intentius/chant/ci-identity";
|
|
66
74
|
import { JOB_GUARD_ENV, jobGuardLine, jobGuardSpec, opWaveJobLabel } from "@intentius/chant/ci-job-guard";
|
|
@@ -108,6 +116,8 @@ export function generateGitlabOpWavesPipeline(spec, options) {
|
|
|
108
116
|
if (spec.resume)
|
|
109
117
|
stages.push("resume");
|
|
110
118
|
const entries = [["stages", stages]];
|
|
119
|
+
// The ruling for ci-products (2026-10-28): each wave job's timeout, and the lock wait five minutes under it.
|
|
120
|
+
const timeout = opWaveJobTimeout(options.jobTimeoutMinutes);
|
|
111
121
|
const variables = nonEmpty("variables", options.variables).variables;
|
|
112
122
|
if (variables)
|
|
113
123
|
entries.push(["variables", variables]);
|
|
@@ -162,10 +172,10 @@ export function generateGitlabOpWavesPipeline(spec, options) {
|
|
|
162
172
|
stage: stages[job.wave - 1 + (byReview ? 1 : 0)],
|
|
163
173
|
image,
|
|
164
174
|
...(tags ? { tags } : {}),
|
|
165
|
-
|
|
175
|
+
timeout: `${timeout.minutes} minutes`,
|
|
166
176
|
...(environment ? { environment: environmentDoc(environment) } : {}),
|
|
167
177
|
...(idTokens ? { id_tokens: idTokens } : {}),
|
|
168
|
-
variables: { ...GITLAB_FULL_HISTORY, ...(wave.variables ?? {}), ...(group?.variables ?? {}), ...(cloud ? { [TRADE_SPEC_ENV]: JSON.stringify(cloud) } : {}), [JOB_GUARD_ENV]: JSON.stringify(guard) },
|
|
178
|
+
variables: { ...GITLAB_FULL_HISTORY, ...timeout.env, ...(wave.variables ?? {}), ...(group?.variables ?? {}), ...(cloud ? { [TRADE_SPEC_ENV]: JSON.stringify(cloud) } : {}), [JOB_GUARD_ENV]: JSON.stringify(guard) },
|
|
169
179
|
rules,
|
|
170
180
|
...(job.needs.length > 0 ? { needs: job.needs } : {}),
|
|
171
181
|
script: [jobGuardLine(), ...(cloud ? gitlabTradeLines() : []), ...dropControl, ...setup, ...(options.beforeScript ?? []), job.command.join(" "), ...(options.extraScript ?? [])],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAaH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"generate-pipeline.d.ts","sourceRoot":"","sources":["../../src/components/generate-pipeline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAaH,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAmCjG,OAAO,KAAK,EACV,oBAAoB,IAAI,YAAY,EACpC,wBAAwB,IAAI,qBAAqB,EACjD,uBAAuB,IAAI,oBAAoB,EAEhD,MAAM,0BAA0B,CAAC;AAIlC,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAE1E;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,eAAe,EAAE,EAC7B,OAAO,GAAE,qBAA0B,GAClC,oBAAoB,CAkJtB"}
|
|
@@ -35,7 +35,7 @@ import { assertGitlabBranch, assertRunnerLabels, CI_IMAGE, ciJobName, fillComman
|
|
|
35
35
|
import { resolveComponentGraph } from "@intentius/chant/components/driver";
|
|
36
36
|
import { hasPublishStep, promoteArchivePaths } from "@intentius/chant/components/promote";
|
|
37
37
|
import { GATED_WAVE_RECORD, gatedWaveJobs } from "@intentius/chant/components/gated-wave-pipeline";
|
|
38
|
-
import { PR_APPLY_RECORD, PR_LOOP_REPORT_DIR, prApplyGroup, prRecordGroup, prApplyRecordKey, prApplyWaveJobName, prLoopJobs, GITLAB_APPLY_PR_VAR, GITLAB_PLAN_NOTES_VAR, gitlabPlanJobName, prLoopPostJob, prLoopSetup, PR_PLAN_NOTE_JOB, prLoopWaveJobs, prLoopWithWaves, prEnvJobs, prCommentLockJobs, prCommentPreviewJob, PR_ENV_REPORT_DIR, PR_ENV_POST_JOB, PR_STALE_JOB, prStaleJob, prLoopJobStage, prLoopRunner, } from "@intentius/chant/components/pr-pipeline";
|
|
38
|
+
import { PR_APPLY_RECORD, PR_LOOP_REPORT_DIR, prApplyGroup, prRecordGroup, prApplyRecordKey, prApplyWaveJobName, prLoopJobs, GITLAB_APPLY_PR_VAR, GITLAB_PLAN_NOTES_VAR, gitlabPlanJobName, prLoopPostJob, prLoopSetup, PR_PLAN_NOTE_JOB, prLoopWaveJobs, prLoopWithWaves, prEnvJobs, prCommentLockJobs, prCommentPreviewJob, prActionJob, PR_ENV_REPORT_DIR, PR_ENV_POST_JOB, PR_STALE_JOB, prStaleJob, prLoopJobStage, prLoopRunner, } from "@intentius/chant/components/pr-pipeline";
|
|
39
39
|
import { REPO_APPLY_GROUP } from "@intentius/chant/components/repo-lock";
|
|
40
40
|
import { memberGitlabChanges, memberRepoPath, memberShellDir } from "@intentius/chant/lexicon";
|
|
41
41
|
import { FORGE_TOKEN_VARS, GITLAB_DROP_FORGE_TOKENS } from "@intentius/chant/ci-handover";
|
|
@@ -369,6 +369,8 @@ function prLoopGitlabPipeline(components, env, image, beforeScript, extraScript,
|
|
|
369
369
|
name: named(job.jobName),
|
|
370
370
|
rule: `$CI_PIPELINE_SOURCE =~ /^(web|api|trigger)$/ && $${job.gitlabVar} =~ /^[0-9]+$/ && $CI_COMMIT_BRANCH == ${targetBranch}`,
|
|
371
371
|
}));
|
|
372
|
+
// #4654: the action job is GitHub's and Forgejo's; asked for here, it is refused by name.
|
|
373
|
+
prActionJob("gitlab", loop);
|
|
372
374
|
// #4620: `/<product> <plan word>`: a pipeline of the target branch started with CHANT_PREVIEW_PR set previews the merge request's head again.
|
|
373
375
|
const preview = prCommentPreviewJob("gitlab", env, loop, member?.name);
|
|
374
376
|
const previewRule = preview ? `$CI_PIPELINE_SOURCE =~ /^(web|api|trigger)$/ && $${preview.gitlabVar} =~ /^[0-9]+$/ && $CI_COMMIT_BRANCH == ${targetBranch}` : undefined;
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "679738b775a2da0000727a84532e5545a10bea8f6d1eaaadaf7a36e4fb5d5e5f",
|
|
5
5
|
"meta.json": "db082fbf90c5941c498b2bee0f106103449c1a4c257716ca2220f0dd490450b2",
|
|
6
6
|
"types/index.d.ts": "a048a66ebe20da0cb5fc889054cac69044d9bf882e2c56b5c5bf113d1f3ba57c",
|
|
7
7
|
"rules/artifact-no-expiry.ts": "0ca5bb972d4a542126e8a0229d43b55658394cb7dd9b9923b2c590bec1c2ad7d",
|
|
@@ -55,5 +55,5 @@
|
|
|
55
55
|
"skills/chant-gitlab-migrate.md": "4853d04980560b379e5b0f7267dcb0a1e5d5879cb9e9931681ce76b2a5fe69d8",
|
|
56
56
|
"skills/chant-gitlab-patterns.md": "6d9a44e9e8de4c3820be9d65381b0d2ede4cb3626aaaf0011e21838a9fbf556e"
|
|
57
57
|
},
|
|
58
|
-
"composite": "
|
|
58
|
+
"composite": "ac4d6532636f55ed94b2fe99ead1acf7cf7509b75182ba82717de275892ff866"
|
|
59
59
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-gitlab",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.58",
|
|
4
4
|
"description": "GitLab CI lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -67,8 +67,8 @@
|
|
|
67
67
|
"typescript": "^5.9.3"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
|
-
"@intentius/chant": "^0.124.
|
|
71
|
-
"@intentius/chant-lexicon-github": "^0.124.
|
|
70
|
+
"@intentius/chant": "^0.124.58",
|
|
71
|
+
"@intentius/chant-lexicon-github": "^0.124.58"
|
|
72
72
|
},
|
|
73
73
|
"peerDependenciesMeta": {
|
|
74
74
|
"@intentius/chant-lexicon-github": {
|
|
@@ -15,9 +15,10 @@ wave-1-dev:
|
|
|
15
15
|
tags:
|
|
16
16
|
- docker
|
|
17
17
|
- dev
|
|
18
|
-
|
|
18
|
+
timeout: '180 minutes'
|
|
19
19
|
variables:
|
|
20
20
|
GIT_DEPTH: '0'
|
|
21
|
+
CHANT_LOCK_WAIT: '10500'
|
|
21
22
|
CHANT_JOB_GUARD: '{"forge":"gitlab","job":"wave 1 (dev) of migrations","branches":["main"],"runnerTags":["docker","dev"]}'
|
|
22
23
|
rules:
|
|
23
24
|
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
|
|
@@ -38,12 +39,13 @@ wave-2-prod-decide:
|
|
|
38
39
|
image: node:22
|
|
39
40
|
tags:
|
|
40
41
|
- plan
|
|
41
|
-
|
|
42
|
+
timeout: '180 minutes'
|
|
42
43
|
id_tokens:
|
|
43
44
|
PLAN_TOKEN:
|
|
44
45
|
aud: plan.example
|
|
45
46
|
variables:
|
|
46
47
|
GIT_DEPTH: '0'
|
|
48
|
+
CHANT_LOCK_WAIT: '10500'
|
|
47
49
|
CHANT_JOB_GUARD: '{"forge":"gitlab","job":"the deciding job of wave 2 (prod) of migrations","branches":["main"],"runnerTags":["plan"]}'
|
|
48
50
|
rules:
|
|
49
51
|
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
|
|
@@ -67,7 +69,7 @@ wave-2-prod-us:
|
|
|
67
69
|
image: node:22
|
|
68
70
|
tags:
|
|
69
71
|
- us-apply
|
|
70
|
-
|
|
72
|
+
timeout: '180 minutes'
|
|
71
73
|
environment:
|
|
72
74
|
name: prod-us
|
|
73
75
|
id_tokens:
|
|
@@ -75,6 +77,7 @@ wave-2-prod-us:
|
|
|
75
77
|
aud: us.example
|
|
76
78
|
variables:
|
|
77
79
|
GIT_DEPTH: '0'
|
|
80
|
+
CHANT_LOCK_WAIT: '10500'
|
|
78
81
|
REGION: us
|
|
79
82
|
CHANT_JOB_GUARD: '{"forge":"gitlab","job":"job group us of wave 2 (prod) of migrations","forgeEnvironment":"prod-us","branches":["main"],"runnerTags":["us-apply"]}'
|
|
80
83
|
rules:
|
|
@@ -99,7 +102,7 @@ wave-2-prod-eu:
|
|
|
99
102
|
image: node:22
|
|
100
103
|
tags:
|
|
101
104
|
- eu-apply
|
|
102
|
-
|
|
105
|
+
timeout: '180 minutes'
|
|
103
106
|
environment:
|
|
104
107
|
name: prod-eu
|
|
105
108
|
id_tokens:
|
|
@@ -107,6 +110,7 @@ wave-2-prod-eu:
|
|
|
107
110
|
aud: eu.example
|
|
108
111
|
variables:
|
|
109
112
|
GIT_DEPTH: '0'
|
|
113
|
+
CHANT_LOCK_WAIT: '10500'
|
|
110
114
|
CHANT_JOB_GUARD: '{"forge":"gitlab","job":"job group eu of wave 2 (prod) of migrations","forgeEnvironment":"prod-eu","branches":["main"],"runnerTags":["eu-apply"]}'
|
|
111
115
|
rules:
|
|
112
116
|
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
|
|
@@ -95,9 +95,9 @@ describe("a runner per wave and job groups per wave (#3914)", () => {
|
|
|
95
95
|
test("tags, environment, id_tokens, variables and the group's command on each job", () => {
|
|
96
96
|
const yaml = generateGitlabOpWavesPipeline(grouped, { specFile: "waves.json" }).files[0]!.yaml;
|
|
97
97
|
expect(yaml).toMatch(/wave-1-dev:\n\s+stage: wave-1-dev\n\s+image: node:22\n\s+tags:\n\s+- docker\n\s+- dev\n/);
|
|
98
|
-
expect(yaml).toMatch(/wave-2-prod-decide:\n\s+stage: wave-2-prod\n\s+image: node:22\n\s+tags:\n\s+- plan\n\s+
|
|
98
|
+
expect(yaml).toMatch(/wave-2-prod-decide:\n\s+stage: wave-2-prod\n\s+image: node:22\n\s+tags:\n\s+- plan\n\s+timeout: '180 minutes'\n\s+id_tokens:\n\s+PLAN_TOKEN:\n\s+aud: plan.example\n/);
|
|
99
99
|
expect(yaml).toMatch(
|
|
100
|
-
/wave-2-prod-us:\n\s+stage: wave-2-prod\n\s+image: node:22\n\s+tags:\n\s+- us-apply\n\s+
|
|
100
|
+
/wave-2-prod-us:\n\s+stage: wave-2-prod\n\s+image: node:22\n\s+tags:\n\s+- us-apply\n\s+timeout: '180 minutes'\n\s+environment:\n\s+name: prod-us\n\s+id_tokens:\n\s+CLOUD_TOKEN:\n\s+aud: us.example\n\s+variables:\n\s+GIT_DEPTH: '0'\n\s+CHANT_LOCK_WAIT: '10500'\n\s+REGION: us\n\s+CHANT_JOB_GUARD: [^\n]*\n[\s\S]*?needs:\n\s+- wave-2-prod-decide\n\s+script:\n\s+- [^\n]*node -e[^\n]*\n\s+- echo us\n\s+- chant run wave --spec waves.json --wave 2 --group us\n/,
|
|
101
101
|
);
|
|
102
102
|
expect(yaml).toMatch(/wave-2-prod-eu:[\s\S]*?id_tokens:\n\s+CLOUD_TOKEN:\n\s+aud: eu.example\n/);
|
|
103
103
|
expect(yaml).not.toContain("_AUDIENCE");
|
|
@@ -149,3 +149,12 @@ describe("an Op wave's jobs by cloud identity (#4332)", () => {
|
|
|
149
149
|
expect(jobs.every((j) => j.command[0] === "chant")).toBe(true);
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
describe("the ledger lock (ruling for ci-products 2026-10-28)", () => {
|
|
154
|
+
test("the wave jobs carry no resource_group; each carries its timeout and the lock wait under it", () => {
|
|
155
|
+
const yaml = generateGitlabOpWavesPipeline(spec, { specFile: "waves.json" }).files[0]!.yaml;
|
|
156
|
+
expect(yaml).not.toContain("resource_group");
|
|
157
|
+
expect(yaml).toContain("timeout: '180 minutes'\n");
|
|
158
|
+
expect(yaml).toContain("CHANT_LOCK_WAIT: '10500'\n");
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -18,6 +18,14 @@
|
|
|
18
18
|
* A wave's `environment` is the job's own `environment:`; protect it in the
|
|
19
19
|
* project settings to put a reviewer in front of the job as well.
|
|
20
20
|
*
|
|
21
|
+
* The wave jobs carry no `resource_group` (ruling for ci-products
|
|
22
|
+
* 2026-10-28, "Ledger lock"), the same as the GitHub and Forgejo waves files
|
|
23
|
+
* carry no concurrency group: a per-wave resource group would keep two
|
|
24
|
+
* pipelines' plunge stacks apart where their resource rows do not meet. A
|
|
25
|
+
* stock Pulumi stack or a Terraform root waits for its row on chant's ledger,
|
|
26
|
+
* oldest commit first, up to the job's `timeout`, which `CHANT_LOCK_WAIT`
|
|
27
|
+
* sits five minutes under; the project's own maximum timeout still caps it.
|
|
28
|
+
*
|
|
21
29
|
* With `resume` on the spec (#3683), a `<name>-resume` job runs `chant run
|
|
22
30
|
* resume --op <name>` in scheduled pipelines only: create a pipeline schedule
|
|
23
31
|
* with the spec's cron. It retries a waiting wave's job once its approval
|
|
@@ -79,6 +87,7 @@ import {
|
|
|
79
87
|
import {
|
|
80
88
|
opWaveGroupOf,
|
|
81
89
|
opWaveJobs,
|
|
90
|
+
opWaveJobTimeout,
|
|
82
91
|
opWaveOutcomeDir,
|
|
83
92
|
opWavesControlTarget,
|
|
84
93
|
opWavesLastJobs,
|
|
@@ -136,6 +145,8 @@ export function generateGitlabOpWavesPipeline(spec: OpWavesSpec, options: OpWave
|
|
|
136
145
|
if (control) stages.push("control");
|
|
137
146
|
if (spec.resume) stages.push("resume");
|
|
138
147
|
const entries: Array<readonly [string, unknown]> = [["stages", stages]];
|
|
148
|
+
// The ruling for ci-products (2026-10-28): each wave job's timeout, and the lock wait five minutes under it.
|
|
149
|
+
const timeout = opWaveJobTimeout(options.jobTimeoutMinutes);
|
|
139
150
|
const variables = nonEmpty("variables", options.variables).variables;
|
|
140
151
|
if (variables) entries.push(["variables", variables]);
|
|
141
152
|
if (byReview) {
|
|
@@ -189,10 +200,10 @@ export function generateGitlabOpWavesPipeline(spec: OpWavesSpec, options: OpWave
|
|
|
189
200
|
stage: stages[job.wave - 1 + (byReview ? 1 : 0)],
|
|
190
201
|
image,
|
|
191
202
|
...(tags ? { tags } : {}),
|
|
192
|
-
|
|
203
|
+
timeout: `${timeout.minutes} minutes`,
|
|
193
204
|
...(environment ? { environment: environmentDoc(environment) } : {}),
|
|
194
205
|
...(idTokens ? { id_tokens: idTokens } : {}),
|
|
195
|
-
variables: { ...GITLAB_FULL_HISTORY, ...(wave.variables ?? {}), ...(group?.variables ?? {}), ...(cloud ? { [TRADE_SPEC_ENV]: JSON.stringify(cloud) } : {}), [JOB_GUARD_ENV]: JSON.stringify(guard) },
|
|
206
|
+
variables: { ...GITLAB_FULL_HISTORY, ...timeout.env, ...(wave.variables ?? {}), ...(group?.variables ?? {}), ...(cloud ? { [TRADE_SPEC_ENV]: JSON.stringify(cloud) } : {}), [JOB_GUARD_ENV]: JSON.stringify(guard) },
|
|
196
207
|
rules,
|
|
197
208
|
...(job.needs.length > 0 ? { needs: job.needs } : {}),
|
|
198
209
|
script: [jobGuardLine(), ...(cloud ? gitlabTradeLines() : []), ...dropControl, ...setup, ...(options.beforeScript ?? []), job.command.join(" "), ...(options.extraScript ?? [])],
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
prEnvJobs,
|
|
66
66
|
prCommentLockJobs,
|
|
67
67
|
prCommentPreviewJob,
|
|
68
|
+
prActionJob,
|
|
68
69
|
PR_ENV_REPORT_DIR,
|
|
69
70
|
PR_ENV_POST_JOB,
|
|
70
71
|
PR_STALE_JOB,
|
|
@@ -442,6 +443,8 @@ function prLoopGitlabPipeline(
|
|
|
442
443
|
name: named(job.jobName),
|
|
443
444
|
rule: `$CI_PIPELINE_SOURCE =~ /^(web|api|trigger)$/ && $${job.gitlabVar} =~ /^[0-9]+$/ && $CI_COMMIT_BRANCH == ${targetBranch}`,
|
|
444
445
|
}));
|
|
446
|
+
// #4654: the action job is GitHub's and Forgejo's; asked for here, it is refused by name.
|
|
447
|
+
prActionJob("gitlab", loop);
|
|
445
448
|
// #4620: `/<product> <plan word>`: a pipeline of the target branch started with CHANT_PREVIEW_PR set previews the merge request's head again.
|
|
446
449
|
const preview = prCommentPreviewJob("gitlab", env, loop, member?.name);
|
|
447
450
|
const previewRule = preview ? `$CI_PIPELINE_SOURCE =~ /^(web|api|trigger)$/ && $${preview.gitlabVar} =~ /^[0-9]+$/ && $CI_COMMIT_BRANCH == ${targetBranch}` : undefined;
|