@catladder/cli 5.1.3 → 5.2.0
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/bundles/catenv/index.js +29 -0
- package/dist/bundles/cli/index.js +29 -0
- package/dist/bundles/skills/catladder-pipelines/SKILL.md +32 -0
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js +16 -0
- package/dist/packages/pipeline/src/backends/gitlab/createGitlabPipeline.js.map +1 -1
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.d.ts +17 -0
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js +13 -0
- package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js.map +1 -1
- package/dist/packages/pipeline/src/types/gitlab-types.d.ts +29 -1
- package/dist/skills/catladder-pipelines/SKILL.md +32 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -4803,9 +4803,20 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
4803
4803
|
],
|
|
4804
4804
|
workflow: {
|
|
4805
4805
|
name: "$PIPELINE_ICON $PIPELINE_NAME",
|
|
4806
|
+
// superseded pipelines must actually die: "interruptible" cancels
|
|
4807
|
+
// every interruptible job, while gitlab's default "conservative"
|
|
4808
|
+
// lets one started `interruptible: false` job shield the whole
|
|
4809
|
+
// pipeline from cancellation. The rules below opt the pipelines
|
|
4810
|
+
// that must run to completion back out.
|
|
4811
|
+
// NOTE: this only tunes the project setting "Auto-cancel
|
|
4812
|
+
// redundant pipelines" — with that setting off nothing cancels.
|
|
4813
|
+
auto_cancel: { on_new_commit: "interruptible" },
|
|
4806
4814
|
rules: [
|
|
4807
4815
|
{
|
|
4808
4816
|
if: '$CI_PIPELINE_SOURCE == "trigger"',
|
|
4817
|
+
// an agent run is not redundant work: a commit landing while
|
|
4818
|
+
// it thinks must not kill it
|
|
4819
|
+
auto_cancel: { on_new_commit: "none" },
|
|
4809
4820
|
variables: {
|
|
4810
4821
|
PIPELINE_ICON: "🤖",
|
|
4811
4822
|
PIPELINE_NAME: "Thinking...",
|
|
@@ -4834,6 +4845,11 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
4834
4845
|
},
|
|
4835
4846
|
{
|
|
4836
4847
|
if: rules_1.RULE_IS_TAGGED_RELEASE.if,
|
|
4848
|
+
// a release pipeline always runs through: tags are immutable,
|
|
4849
|
+
// so this only bites when someone force-moves one — and a
|
|
4850
|
+
// release cancelled halfway leaves the version published in
|
|
4851
|
+
// some places and missing in others
|
|
4852
|
+
auto_cancel: { on_new_commit: "none" },
|
|
4837
4853
|
variables: {
|
|
4838
4854
|
PIPELINE_ICON: "🐱📦",
|
|
4839
4855
|
PIPELINE_NAME: "Release $CI_COMMIT_TAG",
|
|
@@ -4950,6 +4966,12 @@ mainBranchJobNames) => {
|
|
|
4950
4966
|
image: releaseImage,
|
|
4951
4967
|
script: [method.script],
|
|
4952
4968
|
after_script: [EXPIRED_TOKEN_HELP],
|
|
4969
|
+
// a release in flight must never be killed by a new commit — a
|
|
4970
|
+
// half-published version (tag pushed, npm publish missing) is not
|
|
4971
|
+
// recoverable by re-running. Under gitlab's default "conservative"
|
|
4972
|
+
// auto-cancel this also shields the rest of the pipeline, but only
|
|
4973
|
+
// once the release actually started, which is late by construction.
|
|
4974
|
+
interruptible: false,
|
|
4953
4975
|
};
|
|
4954
4976
|
const forceReleaseJob = {
|
|
4955
4977
|
["⚠️ force create release"]: {
|
|
@@ -4973,6 +4995,10 @@ mainBranchJobNames) => {
|
|
|
4973
4995
|
stage: "test",
|
|
4974
4996
|
image: releaseImage,
|
|
4975
4997
|
script: [method.checkScript],
|
|
4998
|
+
// a redundant report is worthless: without this the job
|
|
4999
|
+
// defaults to interruptible: false and, once started, stops
|
|
5000
|
+
// gitlab from auto-cancelling the superseded MR pipeline
|
|
5001
|
+
interruptible: true,
|
|
4976
5002
|
allow_failure: true,
|
|
4977
5003
|
artifacts: {
|
|
4978
5004
|
paths: ["changeset-report.md"],
|
|
@@ -5042,6 +5068,9 @@ mainBranchJobNames) => {
|
|
|
5042
5068
|
script: [
|
|
5043
5069
|
`echo "release queued — '${exports.RELEASE_EXECUTOR_JOB_NAME}' runs it as soon as every other job in this pipeline succeeded"`,
|
|
5044
5070
|
],
|
|
5071
|
+
// the recorded intent must survive a new commit: cancelling it
|
|
5072
|
+
// would silently drop the queued release
|
|
5073
|
+
interruptible: false,
|
|
5045
5074
|
needs: [],
|
|
5046
5075
|
// allow_failure keeps the unclicked button from blocking the
|
|
5047
5076
|
// pipeline AND makes the executor's needs treat it as optional
|
|
@@ -11355,9 +11355,20 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
11355
11355
|
],
|
|
11356
11356
|
workflow: {
|
|
11357
11357
|
name: "$PIPELINE_ICON $PIPELINE_NAME",
|
|
11358
|
+
// superseded pipelines must actually die: "interruptible" cancels
|
|
11359
|
+
// every interruptible job, while gitlab's default "conservative"
|
|
11360
|
+
// lets one started `interruptible: false` job shield the whole
|
|
11361
|
+
// pipeline from cancellation. The rules below opt the pipelines
|
|
11362
|
+
// that must run to completion back out.
|
|
11363
|
+
// NOTE: this only tunes the project setting "Auto-cancel
|
|
11364
|
+
// redundant pipelines" — with that setting off nothing cancels.
|
|
11365
|
+
auto_cancel: { on_new_commit: "interruptible" },
|
|
11358
11366
|
rules: [
|
|
11359
11367
|
{
|
|
11360
11368
|
if: '$CI_PIPELINE_SOURCE == "trigger"',
|
|
11369
|
+
// an agent run is not redundant work: a commit landing while
|
|
11370
|
+
// it thinks must not kill it
|
|
11371
|
+
auto_cancel: { on_new_commit: "none" },
|
|
11361
11372
|
variables: {
|
|
11362
11373
|
PIPELINE_ICON: "🤖",
|
|
11363
11374
|
PIPELINE_NAME: "Thinking...",
|
|
@@ -11386,6 +11397,11 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
11386
11397
|
},
|
|
11387
11398
|
{
|
|
11388
11399
|
if: rules_1.RULE_IS_TAGGED_RELEASE.if,
|
|
11400
|
+
// a release pipeline always runs through: tags are immutable,
|
|
11401
|
+
// so this only bites when someone force-moves one — and a
|
|
11402
|
+
// release cancelled halfway leaves the version published in
|
|
11403
|
+
// some places and missing in others
|
|
11404
|
+
auto_cancel: { on_new_commit: "none" },
|
|
11389
11405
|
variables: {
|
|
11390
11406
|
PIPELINE_ICON: "🐱📦",
|
|
11391
11407
|
PIPELINE_NAME: "Release $CI_COMMIT_TAG",
|
|
@@ -11502,6 +11518,12 @@ mainBranchJobNames) => {
|
|
|
11502
11518
|
image: releaseImage,
|
|
11503
11519
|
script: [method.script],
|
|
11504
11520
|
after_script: [EXPIRED_TOKEN_HELP],
|
|
11521
|
+
// a release in flight must never be killed by a new commit — a
|
|
11522
|
+
// half-published version (tag pushed, npm publish missing) is not
|
|
11523
|
+
// recoverable by re-running. Under gitlab's default "conservative"
|
|
11524
|
+
// auto-cancel this also shields the rest of the pipeline, but only
|
|
11525
|
+
// once the release actually started, which is late by construction.
|
|
11526
|
+
interruptible: false,
|
|
11505
11527
|
};
|
|
11506
11528
|
const forceReleaseJob = {
|
|
11507
11529
|
["⚠️ force create release"]: {
|
|
@@ -11525,6 +11547,10 @@ mainBranchJobNames) => {
|
|
|
11525
11547
|
stage: "test",
|
|
11526
11548
|
image: releaseImage,
|
|
11527
11549
|
script: [method.checkScript],
|
|
11550
|
+
// a redundant report is worthless: without this the job
|
|
11551
|
+
// defaults to interruptible: false and, once started, stops
|
|
11552
|
+
// gitlab from auto-cancelling the superseded MR pipeline
|
|
11553
|
+
interruptible: true,
|
|
11528
11554
|
allow_failure: true,
|
|
11529
11555
|
artifacts: {
|
|
11530
11556
|
paths: ["changeset-report.md"],
|
|
@@ -11594,6 +11620,9 @@ mainBranchJobNames) => {
|
|
|
11594
11620
|
script: [
|
|
11595
11621
|
`echo "release queued — '${exports.RELEASE_EXECUTOR_JOB_NAME}' runs it as soon as every other job in this pipeline succeeded"`,
|
|
11596
11622
|
],
|
|
11623
|
+
// the recorded intent must survive a new commit: cancelling it
|
|
11624
|
+
// would silently drop the queued release
|
|
11625
|
+
interruptible: false,
|
|
11597
11626
|
needs: [],
|
|
11598
11627
|
// allow_failure keeps the unclicked button from blocking the
|
|
11599
11628
|
// pipeline AND makes the executor's needs treat it as optional
|
|
@@ -37,6 +37,38 @@ Generated layout:
|
|
|
37
37
|
Stages: setup → test → build → deploy → verify (post-deploy checks),
|
|
38
38
|
plus stop jobs for review-app teardown.
|
|
39
39
|
|
|
40
|
+
## Superseded pipelines are cancelled
|
|
41
|
+
|
|
42
|
+
Pushing a new commit cancels the pipeline of the previous one, so the
|
|
43
|
+
runners are not busy with results nobody will read.
|
|
44
|
+
|
|
45
|
+
| Pipeline | On a new commit |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `mr` | cancelled |
|
|
48
|
+
| `mainBranch` (dev) | cancelled, except a release already running |
|
|
49
|
+
| `taggedRelease` | **runs through** — never cancelled |
|
|
50
|
+
| agent runs (`trigger`) | **runs through** — never cancelled |
|
|
51
|
+
|
|
52
|
+
- **GitHub**: the generated MR workflow sets `concurrency` with
|
|
53
|
+
`cancel-in-progress: true`.
|
|
54
|
+
- **GitLab**: generated `workflow:auto_cancel:on_new_commit:
|
|
55
|
+
interruptible`, with per-rule `none` for tags and agent runs. Every
|
|
56
|
+
job carries an explicit `interruptible`, jobs that must finish
|
|
57
|
+
(release jobs, agent jobs) carry `interruptible: false`.
|
|
58
|
+
|
|
59
|
+
**GitLab requires the project setting too.** The generated YAML only
|
|
60
|
+
tunes *how* redundant pipelines are cancelled — it does not switch the
|
|
61
|
+
feature on. If old pipelines keep running, check **Settings > CI/CD >
|
|
62
|
+
General pipelines > Auto-cancel redundant pipelines**; with that
|
|
63
|
+
checkbox off nothing is ever cancelled. (`catladder project-doctor`
|
|
64
|
+
does not check this.)
|
|
65
|
+
|
|
66
|
+
**Adding a hand-written GitLab job?** Set `interruptible` explicitly.
|
|
67
|
+
GitLab defaults it to `false`, and a non-interruptible job that has
|
|
68
|
+
started keeps *itself* alive — under gitlab's own default
|
|
69
|
+
(`conservative`, which catladder overrides) it would shield the whole
|
|
70
|
+
pipeline from cancellation.
|
|
71
|
+
|
|
40
72
|
## Review-app auto-stop and pinning (GitLab)
|
|
41
73
|
|
|
42
74
|
GitLab review environments stop automatically after 1 week, dev
|
|
@@ -33,9 +33,20 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
33
33
|
],
|
|
34
34
|
workflow: {
|
|
35
35
|
name: "$PIPELINE_ICON $PIPELINE_NAME",
|
|
36
|
+
// superseded pipelines must actually die: "interruptible" cancels
|
|
37
|
+
// every interruptible job, while gitlab's default "conservative"
|
|
38
|
+
// lets one started `interruptible: false` job shield the whole
|
|
39
|
+
// pipeline from cancellation. The rules below opt the pipelines
|
|
40
|
+
// that must run to completion back out.
|
|
41
|
+
// NOTE: this only tunes the project setting "Auto-cancel
|
|
42
|
+
// redundant pipelines" — with that setting off nothing cancels.
|
|
43
|
+
auto_cancel: { on_new_commit: "interruptible" },
|
|
36
44
|
rules: [
|
|
37
45
|
{
|
|
38
46
|
if: '$CI_PIPELINE_SOURCE == "trigger"',
|
|
47
|
+
// an agent run is not redundant work: a commit landing while
|
|
48
|
+
// it thinks must not kill it
|
|
49
|
+
auto_cancel: { on_new_commit: "none" },
|
|
39
50
|
variables: {
|
|
40
51
|
PIPELINE_ICON: "🤖",
|
|
41
52
|
PIPELINE_NAME: "Thinking...",
|
|
@@ -64,6 +75,11 @@ const createGitlabPipelineWithDefaults = ({ image, variables, before_script, aut
|
|
|
64
75
|
},
|
|
65
76
|
{
|
|
66
77
|
if: rules_1.RULE_IS_TAGGED_RELEASE.if,
|
|
78
|
+
// a release pipeline always runs through: tags are immutable,
|
|
79
|
+
// so this only bites when someone force-moves one — and a
|
|
80
|
+
// release cancelled halfway leaves the version published in
|
|
81
|
+
// some places and missing in others
|
|
82
|
+
auto_cancel: { on_new_commit: "none" },
|
|
67
83
|
variables: {
|
|
68
84
|
PIPELINE_ICON: "🐱📦",
|
|
69
85
|
PIPELINE_NAME: "Release $CI_COMMIT_TAG",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createGitlabPipeline.js","sourceRoot":"","sources":["../../../../../../../../packages/pipeline/src/backends/gitlab/createGitlabPipeline.ts"],"names":[],"mappings":";;;AACA,0CAAwD;AACxD,6CAIwB;AACxB,uCAIqB;AAGrB;;;;;GAKG;AACH,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAElC,MAAM,gCAAgC,GAAG,CAAC,EAC/C,KAAK,EACL,SAAS,EACT,aAAa,EACb,QAAQ,EACR,GAAG,MAAM,EAGV,EAAsB,EAAE;IACvB,MAAM,QAAQ,GAAG,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAC/C,OAAO;QACL,KAAK,EAAE,KAAK,aAAL,KAAK,cAAL,KAAK,GAAI,sBAAsB;QACtC,SAAS,EAAE;YACT,cAAc,EAAE,MAAM,EAAE,uFAAuF;YAC/G,0BAA0B,EAAE,MAAM,EAAE,kCAAkC;YACtE,uBAAuB,EAAE,MAAM,EAAE,gCAAgC;YACjE,wBAAwB,EAAE,IAAI,EAAE,0EAA0E;YAE1G,SAAS,EAAE,GAAG,EAAE,yBAAyB;YACzC,0DAA0D;YAC1D,0DAA0D;YAC1D,4CAA4C;YAC5C,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,oCAAyB,CAAC,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,GAAG,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC;SACrB;QACD,aAAa,EAAE;YACb,GAAG,CAAC,GAAG,4BAAqB,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CACpD,MAAM,CAAC,cAAc,EAAE,CACxB;YACD,GAAG,CAAC,aAAa,aAAb,aAAa,cAAb,aAAa,GAAI,EAAE,CAAC;SACzB;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,+BAA+B;YACrC,KAAK,EAAE;gBACL;oBACE,EAAE,EAAE,mCAAmC;oBACvC,SAAS,EAAE;wBACT,aAAa,EAAE,IAAI;wBACnB,aAAa,EAAE,aAAa;qBAC7B;iBACF;gBACD,+DAA+D;gBAC/D,uCAAuC;gBACvC,GAAG,CAAC,QAAQ;oBACV,CAAC,CAAC;wBACE;4BACE,EAAE,EAAE,GAAG,6BAAqB,CAAC,EAAE,oCAAoC,IAAA,iCAAsB,EAAC,QAAQ,CAAC,GAAG;4BACtG,SAAS,EAAE;gCACT,aAAa,EAAE,MAAM;gCACrB,aAAa,EACX,mDAAmD;gCACrD,CAAC,oCAAyB,CAAC,EAAE,OAAO;6BACrC;yBACF;qBACF;oBACH,CAAC,CAAC,EAAE,CAAC;gBACP;oBACE,EAAE,EAAE,6BAAqB,CAAC,EAAE;oBAC5B,SAAS,EAAE;wBACT,aAAa,EAAE,MAAM;wBACrB,aAAa,EAAE,mDAAmD;qBACnE;iBACF;gBACD;oBACE,EAAE,EAAE,8BAAsB,CAAC,EAAE;oBAC7B,SAAS,EAAE;wBACT,aAAa,EAAE,MAAM;wBACrB,aAAa,EAAE,wBAAwB;qBACxC;iBACF;gBACD;oBACE,EAAE,EAAE,kDAA0C,CAAC,EAAE;oBACjD,SAAS,EAAE;wBACT,aAAa,EAAE,MAAM;wBACrB,aAAa,EAAE,yBAAyB;qBACzC;iBACF;gBAED;oBACE,IAAI,EAAE,QAAQ,EAAE,WAAW;oBAC3B,SAAS,EAAE;wBACT,aAAa,EAAE,KAAK;wBACpB,aAAa,EAAE,SAAS;qBACzB;iBACF;aACF;SACF;QAED,GAAG,MAAM;KACV,CAAC;AACJ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"createGitlabPipeline.js","sourceRoot":"","sources":["../../../../../../../../packages/pipeline/src/backends/gitlab/createGitlabPipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
7
7
|
stage: string;
|
|
8
8
|
image: string;
|
|
9
9
|
script: string[];
|
|
10
|
+
interruptible: true;
|
|
10
11
|
allow_failure: true;
|
|
11
12
|
artifacts: {
|
|
12
13
|
paths: string[];
|
|
@@ -42,6 +43,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
42
43
|
image: string;
|
|
43
44
|
script: string[];
|
|
44
45
|
after_script: string[];
|
|
46
|
+
interruptible: false;
|
|
45
47
|
};
|
|
46
48
|
"create release": {
|
|
47
49
|
rules: {
|
|
@@ -58,6 +60,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
58
60
|
image: string;
|
|
59
61
|
script: string[];
|
|
60
62
|
after_script: string[];
|
|
63
|
+
interruptible: false;
|
|
61
64
|
needs?: undefined;
|
|
62
65
|
allow_failure?: undefined;
|
|
63
66
|
};
|
|
@@ -81,6 +84,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
81
84
|
image: string;
|
|
82
85
|
script: string[];
|
|
83
86
|
after_script: string[];
|
|
87
|
+
interruptible: false;
|
|
84
88
|
};
|
|
85
89
|
"create release": {
|
|
86
90
|
rules: {
|
|
@@ -97,6 +101,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
97
101
|
image: string;
|
|
98
102
|
script: string[];
|
|
99
103
|
after_script: string[];
|
|
104
|
+
interruptible: false;
|
|
100
105
|
needs?: undefined;
|
|
101
106
|
allow_failure?: undefined;
|
|
102
107
|
};
|
|
@@ -105,6 +110,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
105
110
|
stage: string;
|
|
106
111
|
image: string;
|
|
107
112
|
script: string[];
|
|
113
|
+
interruptible: true;
|
|
108
114
|
allow_failure: true;
|
|
109
115
|
artifacts: {
|
|
110
116
|
paths: string[];
|
|
@@ -140,6 +146,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
140
146
|
image: string;
|
|
141
147
|
script: string[];
|
|
142
148
|
after_script: string[];
|
|
149
|
+
interruptible: false;
|
|
143
150
|
};
|
|
144
151
|
"create release": {
|
|
145
152
|
allow_failure: true;
|
|
@@ -157,6 +164,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
157
164
|
image: string;
|
|
158
165
|
script: string[];
|
|
159
166
|
after_script: string[];
|
|
167
|
+
interruptible: false;
|
|
160
168
|
needs?: undefined;
|
|
161
169
|
};
|
|
162
170
|
} | {
|
|
@@ -179,6 +187,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
179
187
|
image: string;
|
|
180
188
|
script: string[];
|
|
181
189
|
after_script: string[];
|
|
190
|
+
interruptible: false;
|
|
182
191
|
};
|
|
183
192
|
"create release": {
|
|
184
193
|
allow_failure: true;
|
|
@@ -196,6 +205,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
196
205
|
image: string;
|
|
197
206
|
script: string[];
|
|
198
207
|
after_script: string[];
|
|
208
|
+
interruptible: false;
|
|
199
209
|
needs?: undefined;
|
|
200
210
|
};
|
|
201
211
|
} | {
|
|
@@ -203,6 +213,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
203
213
|
stage: string;
|
|
204
214
|
image: string;
|
|
205
215
|
script: string[];
|
|
216
|
+
interruptible: true;
|
|
206
217
|
allow_failure: true;
|
|
207
218
|
artifacts: {
|
|
208
219
|
paths: string[];
|
|
@@ -238,11 +249,13 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
238
249
|
image: string;
|
|
239
250
|
script: string[];
|
|
240
251
|
after_script: string[];
|
|
252
|
+
interruptible: false;
|
|
241
253
|
};
|
|
242
254
|
"create release": {
|
|
243
255
|
stage: string;
|
|
244
256
|
image: string;
|
|
245
257
|
script: string[];
|
|
258
|
+
interruptible: false;
|
|
246
259
|
needs: any[];
|
|
247
260
|
allow_failure: true;
|
|
248
261
|
rules: {
|
|
@@ -277,6 +290,7 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
277
290
|
image: string;
|
|
278
291
|
script: string[];
|
|
279
292
|
after_script: string[];
|
|
293
|
+
interruptible: false;
|
|
280
294
|
};
|
|
281
295
|
} | {
|
|
282
296
|
"\uD83E\uDD8B changeset check"?: undefined;
|
|
@@ -298,11 +312,13 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
298
312
|
image: string;
|
|
299
313
|
script: string[];
|
|
300
314
|
after_script: string[];
|
|
315
|
+
interruptible: false;
|
|
301
316
|
};
|
|
302
317
|
"create release": {
|
|
303
318
|
stage: string;
|
|
304
319
|
image: string;
|
|
305
320
|
script: string[];
|
|
321
|
+
interruptible: false;
|
|
306
322
|
needs: any[];
|
|
307
323
|
allow_failure: true;
|
|
308
324
|
rules: {
|
|
@@ -337,5 +353,6 @@ export declare const getGitlabReleaseJobs: (config: Config, images: JobImagesPla
|
|
|
337
353
|
image: string;
|
|
338
354
|
script: string[];
|
|
339
355
|
after_script: string[];
|
|
356
|
+
interruptible: false;
|
|
340
357
|
};
|
|
341
358
|
};
|
|
@@ -53,6 +53,12 @@ mainBranchJobNames) => {
|
|
|
53
53
|
image: releaseImage,
|
|
54
54
|
script: [method.script],
|
|
55
55
|
after_script: [EXPIRED_TOKEN_HELP],
|
|
56
|
+
// a release in flight must never be killed by a new commit — a
|
|
57
|
+
// half-published version (tag pushed, npm publish missing) is not
|
|
58
|
+
// recoverable by re-running. Under gitlab's default "conservative"
|
|
59
|
+
// auto-cancel this also shields the rest of the pipeline, but only
|
|
60
|
+
// once the release actually started, which is late by construction.
|
|
61
|
+
interruptible: false,
|
|
56
62
|
};
|
|
57
63
|
const forceReleaseJob = {
|
|
58
64
|
["⚠️ force create release"]: {
|
|
@@ -76,6 +82,10 @@ mainBranchJobNames) => {
|
|
|
76
82
|
stage: "test",
|
|
77
83
|
image: releaseImage,
|
|
78
84
|
script: [method.checkScript],
|
|
85
|
+
// a redundant report is worthless: without this the job
|
|
86
|
+
// defaults to interruptible: false and, once started, stops
|
|
87
|
+
// gitlab from auto-cancelling the superseded MR pipeline
|
|
88
|
+
interruptible: true,
|
|
79
89
|
allow_failure: true,
|
|
80
90
|
artifacts: {
|
|
81
91
|
paths: ["changeset-report.md"],
|
|
@@ -145,6 +155,9 @@ mainBranchJobNames) => {
|
|
|
145
155
|
script: [
|
|
146
156
|
`echo "release queued — '${exports.RELEASE_EXECUTOR_JOB_NAME}' runs it as soon as every other job in this pipeline succeeded"`,
|
|
147
157
|
],
|
|
158
|
+
// the recorded intent must survive a new commit: cancelling it
|
|
159
|
+
// would silently drop the queued release
|
|
160
|
+
interruptible: false,
|
|
148
161
|
needs: [],
|
|
149
162
|
// allow_failure keeps the unclicked button from blocking the
|
|
150
163
|
// pipeline AND makes the executor's needs treat it as optional
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitlabReleaseJobs.js","sourceRoot":"","sources":["../../../../../../../../packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.ts"],"names":[],"mappings":";;;AAAA,uCAOqB;AAErB,2CAAiD;AAIjD,MAAM,kBAAkB,GACtB,gJAAgJ,CAAC;AAEnJ;;;;GAIG;AACH,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEf,QAAA,uBAAuB,GAAG,gBAAgB,CAAC;AAC3C,QAAA,yBAAyB,GAAG,mCAAmC,CAAC;AAE7E,MAAM,gBAAgB,GAAG;IACvB,oCAA4B;IAC5B,mCAA2B;IAC3B,8BAAsB;CACvB,CAAC;AAEF,sEAAsE;AACtE,mEAAmE;AACnE,uEAAuE;AACvE,oCAAoC;AACpC,MAAM,kBAAkB,GAAG;IACzB,GAAG,gBAAgB;IACnB;QACE,EAAE,EAAE,kCAA0B;QAC9B,IAAI,EAAE,QAAQ;KACf;IACD;QACE,EAAE,EAAE,oCAA4B;QAChC,IAAI,EAAE,QAAQ;KACf;CACqB,CAAC;AAElB,MAAM,oBAAoB,GAAG,CAClC,MAAc,EACd,MAAqB;AACrB;;;;GAIG;AACH,kBAA4B,EAC5B,EAAE;;IACF,MAAM,MAAM,GAAG,IAAA,0BAAgB,EAAC,MAAM,CAAC,CAAC;IACxC,qEAAqE;IACrE,qEAAqE;IACrE,kEAAkE;IAClE,uCAAuC;IACvC,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC,KAAK;KAC7B,CAAC,CAAC,KAAK,CAAC;IAET,MAAM,cAAc,GAAG;QACrB,KAAK,EAAE,SAAS;QAChB,KAAK,EAAE,YAAY;QACnB,MAAM,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;QACvB,YAAY,EAAE,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"gitlabReleaseJobs.js","sourceRoot":"","sources":["../../../../../../../../packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,33 @@ export { Retry, Image as GitlabJobImage } from "./gitlab-ci-yml";
|
|
|
4
4
|
export type Artifacts = GitlabCiArtifacts;
|
|
5
5
|
export type { GitlabJobCache };
|
|
6
6
|
export type GitlabRule = Exclude<Exclude<Rules, null>[number], string | string[]>;
|
|
7
|
+
/**
|
|
8
|
+
* gitlab's auto-cancel policy for redundant pipelines. Tunes the
|
|
9
|
+
* project setting "Auto-cancel redundant pipelines" (Settings > CI/CD >
|
|
10
|
+
* General pipelines) — it does NOT enable it: with the setting off,
|
|
11
|
+
* nothing is ever cancelled regardless of this.
|
|
12
|
+
*
|
|
13
|
+
* needs gitlab >= 16.8 (top-level) / >= 16.10 (per workflow rule).
|
|
14
|
+
*/
|
|
15
|
+
export interface GitlabAutoCancel {
|
|
16
|
+
/**
|
|
17
|
+
* - `conservative` (gitlab's default): cancel the whole pipeline, but
|
|
18
|
+
* only while no `interruptible: false` job has *started* — a single
|
|
19
|
+
* such job then shields every other job from cancellation
|
|
20
|
+
* - `interruptible`: cancel every `interruptible: true` job, with no
|
|
21
|
+
* such veto
|
|
22
|
+
* - `none`: never auto-cancel
|
|
23
|
+
*/
|
|
24
|
+
on_new_commit?: "conservative" | "interruptible" | "none";
|
|
25
|
+
on_job_failure?: "all" | "none";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* a workflow rule may override {@link GitlabAutoCancel} per pipeline
|
|
29
|
+
* kind — job rules may not.
|
|
30
|
+
*/
|
|
31
|
+
export type GitlabWorkflowRule = GitlabRule & {
|
|
32
|
+
auto_cancel?: GitlabAutoCancel;
|
|
33
|
+
};
|
|
7
34
|
export type GitlabEnvironment = Omit<Exclude<JobTemplate["environment"], undefined | string>, "deployment_tier">;
|
|
8
35
|
export interface GitlabJobDef extends Pick<JobTemplate, "after_script" | "allow_failure" | "artifacts" | "before_script" | "coverage" | "dependencies" | "environment" | "except" | "hooks" | "image" | "interruptible" | "needs" | "only" | "parallel" | "release" | "resource_group" | "retry" | "rules" | "script" | "services" | "stage" | "tags" | "trigger" | "variables"> {
|
|
9
36
|
stage: JobTemplate["stage"];
|
|
@@ -23,8 +50,9 @@ export interface GitlabJobDef extends Pick<JobTemplate, "after_script" | "allow_
|
|
|
23
50
|
export interface GitlabPipeline extends Pick<JobTemplate, "variables"> {
|
|
24
51
|
image: string;
|
|
25
52
|
workflow?: {
|
|
26
|
-
rules: GitlabRule[];
|
|
27
53
|
name?: string;
|
|
54
|
+
auto_cancel?: GitlabAutoCancel;
|
|
55
|
+
rules: GitlabWorkflowRule[];
|
|
28
56
|
variables?: Record<string, string>;
|
|
29
57
|
};
|
|
30
58
|
stages: string[];
|
|
@@ -37,6 +37,38 @@ Generated layout:
|
|
|
37
37
|
Stages: setup → test → build → deploy → verify (post-deploy checks),
|
|
38
38
|
plus stop jobs for review-app teardown.
|
|
39
39
|
|
|
40
|
+
## Superseded pipelines are cancelled
|
|
41
|
+
|
|
42
|
+
Pushing a new commit cancels the pipeline of the previous one, so the
|
|
43
|
+
runners are not busy with results nobody will read.
|
|
44
|
+
|
|
45
|
+
| Pipeline | On a new commit |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `mr` | cancelled |
|
|
48
|
+
| `mainBranch` (dev) | cancelled, except a release already running |
|
|
49
|
+
| `taggedRelease` | **runs through** — never cancelled |
|
|
50
|
+
| agent runs (`trigger`) | **runs through** — never cancelled |
|
|
51
|
+
|
|
52
|
+
- **GitHub**: the generated MR workflow sets `concurrency` with
|
|
53
|
+
`cancel-in-progress: true`.
|
|
54
|
+
- **GitLab**: generated `workflow:auto_cancel:on_new_commit:
|
|
55
|
+
interruptible`, with per-rule `none` for tags and agent runs. Every
|
|
56
|
+
job carries an explicit `interruptible`, jobs that must finish
|
|
57
|
+
(release jobs, agent jobs) carry `interruptible: false`.
|
|
58
|
+
|
|
59
|
+
**GitLab requires the project setting too.** The generated YAML only
|
|
60
|
+
tunes *how* redundant pipelines are cancelled — it does not switch the
|
|
61
|
+
feature on. If old pipelines keep running, check **Settings > CI/CD >
|
|
62
|
+
General pipelines > Auto-cancel redundant pipelines**; with that
|
|
63
|
+
checkbox off nothing is ever cancelled. (`catladder project-doctor`
|
|
64
|
+
does not check this.)
|
|
65
|
+
|
|
66
|
+
**Adding a hand-written GitLab job?** Set `interruptible` explicitly.
|
|
67
|
+
GitLab defaults it to `false`, and a non-interruptible job that has
|
|
68
|
+
started keeps *itself* alive — under gitlab's own default
|
|
69
|
+
(`conservative`, which catladder overrides) it would shield the whole
|
|
70
|
+
pipeline from cancellation.
|
|
71
|
+
|
|
40
72
|
## Review-app auto-stop and pinning (GitLab)
|
|
41
73
|
|
|
42
74
|
GitLab review environments stop automatically after 1 week, dev
|