@catladder/cli 0.0.0-next-401fe684 → 0.0.0-next-23a53e9e

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.
Files changed (43) hide show
  1. package/dist/bundles/catci/index.js +4 -4
  2. package/dist/bundles/catenv/index.js +62 -14
  3. package/dist/bundles/cli/index.js +62 -14
  4. package/dist/bundles/runner-images/changesets/Dockerfile +13 -0
  5. package/dist/bundles/runner-images/changesets/scripts/changesetsRelease +37 -0
  6. package/dist/bundles/runner-images/semantic-release/Dockerfile +4 -0
  7. package/dist/bundles/runner-images/semantic-release/scripts/semanticRelease +43 -4
  8. package/dist/cli/src/catci.js +16 -0
  9. package/dist/cli/src/catci.js.map +1 -1
  10. package/dist/cli/src/release/changesets.d.ts +44 -0
  11. package/dist/cli/src/release/changesets.js +124 -0
  12. package/dist/cli/src/release/changesets.js.map +1 -0
  13. package/dist/cli/src/release/changesetsReleaseJob.d.ts +9 -0
  14. package/dist/cli/src/release/changesetsReleaseJob.js +160 -0
  15. package/dist/cli/src/release/changesetsReleaseJob.js.map +1 -0
  16. package/dist/pipeline/src/backends/github/GithubBackend.js +5 -1
  17. package/dist/pipeline/src/backends/github/GithubBackend.js.map +1 -1
  18. package/dist/pipeline/src/backends/github/githubReleaseJobs.js +21 -9
  19. package/dist/pipeline/src/backends/github/githubReleaseJobs.js.map +1 -1
  20. package/dist/pipeline/src/backends/gitlab/gitlabReleaseJobs.js +5 -3
  21. package/dist/pipeline/src/backends/gitlab/gitlabReleaseJobs.js.map +1 -1
  22. package/dist/pipeline/src/constants.js +1 -1
  23. package/dist/pipeline/src/customImages/shippedImages.js +1 -0
  24. package/dist/pipeline/src/customImages/shippedImages.js.map +1 -1
  25. package/dist/pipeline/src/index.d.ts +1 -0
  26. package/dist/pipeline/src/index.js +1 -0
  27. package/dist/pipeline/src/index.js.map +1 -1
  28. package/dist/pipeline/src/release/index.d.ts +23 -0
  29. package/dist/pipeline/src/release/index.js +21 -0
  30. package/dist/pipeline/src/release/index.js.map +1 -0
  31. package/dist/pipeline/src/runner/index.d.ts +1 -1
  32. package/dist/pipeline/src/runner/index.js.map +1 -1
  33. package/dist/pipeline/src/types/release.d.ts +18 -0
  34. package/dist/runner-images/changesets/Dockerfile +13 -0
  35. package/dist/runner-images/changesets/scripts/changesetsRelease +37 -0
  36. package/dist/runner-images/semantic-release/Dockerfile +4 -0
  37. package/dist/runner-images/semantic-release/scripts/semanticRelease +43 -4
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +2 -1
  40. package/src/catci.ts +23 -0
  41. package/src/release/__tests__/changesets.test.ts +168 -0
  42. package/src/release/changesets.ts +156 -0
  43. package/src/release/changesetsReleaseJob.ts +213 -0
@@ -1586,10 +1586,14 @@ const TRIGGER_WORKFLOWS = {
1586
1586
  },
1587
1587
  taggedRelease: {
1588
1588
  name: "catladder release",
1589
+ // tags pushed with the default GITHUB_TOKEN (as the release job
1590
+ // does) don't trigger `on: push: tags` — the release job therefore
1591
+ // also dispatches this workflow explicitly for the new tag
1589
1592
  on: {
1590
1593
  push: {
1591
1594
  tags: ["v*"]
1592
- }
1595
+ },
1596
+ workflow_dispatch: {}
1593
1597
  }
1594
1598
  }
1595
1599
  };
@@ -2164,9 +2168,11 @@ Object.defineProperty(exports, "__esModule", ({
2164
2168
  }));
2165
2169
  exports.getGithubReleaseJobs = void 0;
2166
2170
  const createGithubJobs_1 = __nccwpck_require__(14016);
2167
- const createReleaseJob = (images, needs) => {
2171
+ const release_1 = __nccwpck_require__(61319);
2172
+ const createReleaseJob = (config, images, needs) => {
2173
+ const method = (0, release_1.getReleaseMethod)(config);
2168
2174
  const resolved = images.resolveRef({
2169
- catladderImage: "semantic-release"
2175
+ catladderImage: method.image
2170
2176
  });
2171
2177
  const imageNeeds = resolved.need && typeof resolved.need === "object" ? [(0, createGithubJobs_1.githubGlobalJobId)(resolved.need.job)] : [];
2172
2178
  const allNeeds = [...imageNeeds, ...(needs !== null && needs !== void 0 ? needs : [])];
@@ -2182,9 +2188,18 @@ const createReleaseJob = (images, needs) => {
2182
2188
  }
2183
2189
  } : {})
2184
2190
  },
2185
- // semantic-release pushes the version tag and release commit
2191
+ // the release method pushes the version tag and release commit,
2192
+ // and dispatches the taggedRelease workflow for the new tag (tags
2193
+ // pushed with the job token don't trigger `on: push: tags`).
2194
+ // Declaring permissions drops all default token grants, so the
2195
+ // packages read access (needed to pull the job image from the repo
2196
+ // registry) must be re-granted explicitly.
2186
2197
  permissions: {
2187
- contents: "write"
2198
+ contents: "write",
2199
+ actions: "write",
2200
+ ...(resolved.fromRepoRegistry ? {
2201
+ packages: "read"
2202
+ } : {})
2188
2203
  },
2189
2204
  ...(allNeeds.length > 0 ? {
2190
2205
  needs: allNeeds
@@ -2195,13 +2210,14 @@ const createReleaseJob = (images, needs) => {
2195
2210
  steps: [{
2196
2211
  name: "Checkout",
2197
2212
  uses: "actions/checkout@v4",
2198
- // semantic-release needs the full history to determine the version
2213
+ // the release method needs the full history (commits resp.
2214
+ // tags since the last release) to determine the version
2199
2215
  with: {
2200
2216
  "fetch-depth": 0
2201
2217
  }
2202
2218
  }, {
2203
2219
  name: "create release",
2204
- run: "semanticRelease",
2220
+ run: method.script,
2205
2221
  shell: "bash"
2206
2222
  }]
2207
2223
  };
@@ -2220,17 +2236,17 @@ const getGithubReleaseJobs = (config, mainWorkflowJobIds, images) => {
2220
2236
  if (((_a = config.releases) === null || _a === void 0 ? void 0 : _a.when) === "auto") {
2221
2237
  return {
2222
2238
  main: {
2223
- "create-release": createReleaseJob(images, mainWorkflowJobIds)
2239
+ "create-release": createReleaseJob(config, images, mainWorkflowJobIds)
2224
2240
  },
2225
2241
  manual: {
2226
- "force-create-release": createReleaseJob(images)
2242
+ "force-create-release": createReleaseJob(config, images)
2227
2243
  }
2228
2244
  };
2229
2245
  }
2230
2246
  return {
2231
2247
  main: {},
2232
2248
  manual: {
2233
- "create-release": createReleaseJob(images)
2249
+ "create-release": createReleaseJob(config, images)
2234
2250
  }
2235
2251
  };
2236
2252
  };
@@ -3101,23 +3117,25 @@ Object.defineProperty(exports, "__esModule", ({
3101
3117
  }));
3102
3118
  exports.getGitlabReleaseJobs = void 0;
3103
3119
  const rules_1 = __nccwpck_require__(44565);
3120
+ const release_1 = __nccwpck_require__(61319);
3104
3121
  const EXPIRED_TOKEN_HELP = "echo '👉 If this job failed with access denied, the project access token might be invald - run `project-renew-token` in catladder CLI to fix.'";
3105
3122
  const baseReleaseRules = [rules_1.RULE_NEVER_ON_RELEASE_COMMIT, rules_1.RULE_NEVER_ON_AGENT_TRIGGER, rules_1.RULE_NEVER_ON_SCHEDULE];
3106
3123
  const getGitlabReleaseJobs = (config, images) => {
3107
3124
  var _a;
3125
+ const method = (0, release_1.getReleaseMethod)(config);
3108
3126
  // NOTE: only the resolved image url is used, not the `need`: release
3109
3127
  // jobs have no `needs` on purpose — their stage ordering already
3110
3128
  // guarantees the image build job (setup stage) ran, and adding a
3111
3129
  // `needs` would switch gitlab to DAG mode, so the release job would no
3112
3130
  // longer wait for the build/deploy stages.
3113
3131
  const releaseImage = images.resolveRef({
3114
- catladderImage: "semantic-release"
3132
+ catladderImage: method.image
3115
3133
  }).image;
3116
3134
  return {
3117
3135
  ["create release"]: {
3118
3136
  stage: "release",
3119
3137
  image: releaseImage,
3120
- script: ["semanticRelease"],
3138
+ script: [method.script],
3121
3139
  after_script: [EXPIRED_TOKEN_HELP],
3122
3140
  rules: [...baseReleaseRules, {
3123
3141
  if: rules_1.RULE_CONDITION_MAIN_BRANCH,
@@ -3130,7 +3148,7 @@ const getGitlabReleaseJobs = (config, images) => {
3130
3148
  ["⚠️ force create release"]: {
3131
3149
  stage: "release",
3132
3150
  image: releaseImage,
3133
- script: ["semanticRelease"],
3151
+ script: [method.script],
3134
3152
  after_script: [EXPIRED_TOKEN_HELP],
3135
3153
  needs: [],
3136
3154
  rules: [...baseReleaseRules, {
@@ -5352,7 +5370,7 @@ Object.defineProperty(exports, "__esModule", ({
5352
5370
  value: true
5353
5371
  }));
5354
5372
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
5355
- exports.PIPELINE_IMAGE_TAG = "next-401fe684" || 0;
5373
+ exports.PIPELINE_IMAGE_TAG = "next-23a53e9e" || 0;
5356
5374
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
5357
5375
 
5358
5376
  /***/ }),
@@ -6361,6 +6379,7 @@ exports.RUNNER_IMAGE_BUILD_CONTEXT = {
6361
6379
  "docker-build": "self",
6362
6380
  gcloud: "self",
6363
6381
  "semantic-release": "self",
6382
+ changesets: "self",
6364
6383
  "agent-claude": "self"
6365
6384
  };
6366
6385
  /**
@@ -8801,6 +8820,7 @@ __exportStar(__nccwpck_require__(38045), exports);
8801
8820
  __exportStar(__nccwpck_require__(51398), exports);
8802
8821
  __exportStar(__nccwpck_require__(88025), exports);
8803
8822
  __exportStar(__nccwpck_require__(39871), exports);
8823
+ __exportStar(__nccwpck_require__(61319), exports);
8804
8824
  __exportStar(__nccwpck_require__(45585), exports);
8805
8825
  __exportStar(__nccwpck_require__(47666), exports);
8806
8826
  __exportStar(__nccwpck_require__(60250), exports);
@@ -9840,6 +9860,34 @@ exports.getWorkspaceDependencies = getWorkspaceDependencies;
9840
9860
 
9841
9861
  /***/ }),
9842
9862
 
9863
+ /***/ 61319:
9864
+ /***/ ((__unused_webpack_module, exports) => {
9865
+
9866
+ "use strict";
9867
+
9868
+
9869
+ Object.defineProperty(exports, "__esModule", ({
9870
+ value: true
9871
+ }));
9872
+ exports.getReleaseMethod = exports.RELEASE_METHODS = void 0;
9873
+ exports.RELEASE_METHODS = {
9874
+ "semantic-release": {
9875
+ image: "semantic-release",
9876
+ script: "semanticRelease"
9877
+ },
9878
+ changesets: {
9879
+ image: "changesets",
9880
+ script: "changesetsRelease"
9881
+ }
9882
+ };
9883
+ const getReleaseMethod = config => {
9884
+ var _a, _b;
9885
+ return exports.RELEASE_METHODS[(_b = (_a = config.releases) === null || _a === void 0 ? void 0 : _a.method) !== null && _b !== void 0 ? _b : "semantic-release"];
9886
+ };
9887
+ exports.getReleaseMethod = getReleaseMethod;
9888
+
9889
+ /***/ }),
9890
+
9843
9891
  /***/ 44565:
9844
9892
  /***/ ((__unused_webpack_module, exports) => {
9845
9893
 
@@ -7634,10 +7634,14 @@ const TRIGGER_WORKFLOWS = {
7634
7634
  },
7635
7635
  taggedRelease: {
7636
7636
  name: "catladder release",
7637
+ // tags pushed with the default GITHUB_TOKEN (as the release job
7638
+ // does) don't trigger `on: push: tags` — the release job therefore
7639
+ // also dispatches this workflow explicitly for the new tag
7637
7640
  on: {
7638
7641
  push: {
7639
7642
  tags: ["v*"]
7640
- }
7643
+ },
7644
+ workflow_dispatch: {}
7641
7645
  }
7642
7646
  }
7643
7647
  };
@@ -8212,9 +8216,11 @@ Object.defineProperty(exports, "__esModule", ({
8212
8216
  }));
8213
8217
  exports.getGithubReleaseJobs = void 0;
8214
8218
  const createGithubJobs_1 = __nccwpck_require__(14016);
8215
- const createReleaseJob = (images, needs) => {
8219
+ const release_1 = __nccwpck_require__(61319);
8220
+ const createReleaseJob = (config, images, needs) => {
8221
+ const method = (0, release_1.getReleaseMethod)(config);
8216
8222
  const resolved = images.resolveRef({
8217
- catladderImage: "semantic-release"
8223
+ catladderImage: method.image
8218
8224
  });
8219
8225
  const imageNeeds = resolved.need && typeof resolved.need === "object" ? [(0, createGithubJobs_1.githubGlobalJobId)(resolved.need.job)] : [];
8220
8226
  const allNeeds = [...imageNeeds, ...(needs !== null && needs !== void 0 ? needs : [])];
@@ -8230,9 +8236,18 @@ const createReleaseJob = (images, needs) => {
8230
8236
  }
8231
8237
  } : {})
8232
8238
  },
8233
- // semantic-release pushes the version tag and release commit
8239
+ // the release method pushes the version tag and release commit,
8240
+ // and dispatches the taggedRelease workflow for the new tag (tags
8241
+ // pushed with the job token don't trigger `on: push: tags`).
8242
+ // Declaring permissions drops all default token grants, so the
8243
+ // packages read access (needed to pull the job image from the repo
8244
+ // registry) must be re-granted explicitly.
8234
8245
  permissions: {
8235
- contents: "write"
8246
+ contents: "write",
8247
+ actions: "write",
8248
+ ...(resolved.fromRepoRegistry ? {
8249
+ packages: "read"
8250
+ } : {})
8236
8251
  },
8237
8252
  ...(allNeeds.length > 0 ? {
8238
8253
  needs: allNeeds
@@ -8243,13 +8258,14 @@ const createReleaseJob = (images, needs) => {
8243
8258
  steps: [{
8244
8259
  name: "Checkout",
8245
8260
  uses: "actions/checkout@v4",
8246
- // semantic-release needs the full history to determine the version
8261
+ // the release method needs the full history (commits resp.
8262
+ // tags since the last release) to determine the version
8247
8263
  with: {
8248
8264
  "fetch-depth": 0
8249
8265
  }
8250
8266
  }, {
8251
8267
  name: "create release",
8252
- run: "semanticRelease",
8268
+ run: method.script,
8253
8269
  shell: "bash"
8254
8270
  }]
8255
8271
  };
@@ -8268,17 +8284,17 @@ const getGithubReleaseJobs = (config, mainWorkflowJobIds, images) => {
8268
8284
  if (((_a = config.releases) === null || _a === void 0 ? void 0 : _a.when) === "auto") {
8269
8285
  return {
8270
8286
  main: {
8271
- "create-release": createReleaseJob(images, mainWorkflowJobIds)
8287
+ "create-release": createReleaseJob(config, images, mainWorkflowJobIds)
8272
8288
  },
8273
8289
  manual: {
8274
- "force-create-release": createReleaseJob(images)
8290
+ "force-create-release": createReleaseJob(config, images)
8275
8291
  }
8276
8292
  };
8277
8293
  }
8278
8294
  return {
8279
8295
  main: {},
8280
8296
  manual: {
8281
- "create-release": createReleaseJob(images)
8297
+ "create-release": createReleaseJob(config, images)
8282
8298
  }
8283
8299
  };
8284
8300
  };
@@ -9149,23 +9165,25 @@ Object.defineProperty(exports, "__esModule", ({
9149
9165
  }));
9150
9166
  exports.getGitlabReleaseJobs = void 0;
9151
9167
  const rules_1 = __nccwpck_require__(44565);
9168
+ const release_1 = __nccwpck_require__(61319);
9152
9169
  const EXPIRED_TOKEN_HELP = "echo '👉 If this job failed with access denied, the project access token might be invald - run `project-renew-token` in catladder CLI to fix.'";
9153
9170
  const baseReleaseRules = [rules_1.RULE_NEVER_ON_RELEASE_COMMIT, rules_1.RULE_NEVER_ON_AGENT_TRIGGER, rules_1.RULE_NEVER_ON_SCHEDULE];
9154
9171
  const getGitlabReleaseJobs = (config, images) => {
9155
9172
  var _a;
9173
+ const method = (0, release_1.getReleaseMethod)(config);
9156
9174
  // NOTE: only the resolved image url is used, not the `need`: release
9157
9175
  // jobs have no `needs` on purpose — their stage ordering already
9158
9176
  // guarantees the image build job (setup stage) ran, and adding a
9159
9177
  // `needs` would switch gitlab to DAG mode, so the release job would no
9160
9178
  // longer wait for the build/deploy stages.
9161
9179
  const releaseImage = images.resolveRef({
9162
- catladderImage: "semantic-release"
9180
+ catladderImage: method.image
9163
9181
  }).image;
9164
9182
  return {
9165
9183
  ["create release"]: {
9166
9184
  stage: "release",
9167
9185
  image: releaseImage,
9168
- script: ["semanticRelease"],
9186
+ script: [method.script],
9169
9187
  after_script: [EXPIRED_TOKEN_HELP],
9170
9188
  rules: [...baseReleaseRules, {
9171
9189
  if: rules_1.RULE_CONDITION_MAIN_BRANCH,
@@ -9178,7 +9196,7 @@ const getGitlabReleaseJobs = (config, images) => {
9178
9196
  ["⚠️ force create release"]: {
9179
9197
  stage: "release",
9180
9198
  image: releaseImage,
9181
- script: ["semanticRelease"],
9199
+ script: [method.script],
9182
9200
  after_script: [EXPIRED_TOKEN_HELP],
9183
9201
  needs: [],
9184
9202
  rules: [...baseReleaseRules, {
@@ -11400,7 +11418,7 @@ Object.defineProperty(exports, "__esModule", ({
11400
11418
  value: true
11401
11419
  }));
11402
11420
  exports.DOCKER_REGISTRY = exports.PIPELINE_IMAGE_TAG = void 0;
11403
- exports.PIPELINE_IMAGE_TAG = "next-401fe684" || 0;
11421
+ exports.PIPELINE_IMAGE_TAG = "next-23a53e9e" || 0;
11404
11422
  exports.DOCKER_REGISTRY = "git.panter.ch:5001/catladder/catladder" || 0;
11405
11423
 
11406
11424
  /***/ }),
@@ -12409,6 +12427,7 @@ exports.RUNNER_IMAGE_BUILD_CONTEXT = {
12409
12427
  "docker-build": "self",
12410
12428
  gcloud: "self",
12411
12429
  "semantic-release": "self",
12430
+ changesets: "self",
12412
12431
  "agent-claude": "self"
12413
12432
  };
12414
12433
  /**
@@ -14849,6 +14868,7 @@ __exportStar(__nccwpck_require__(38045), exports);
14849
14868
  __exportStar(__nccwpck_require__(51398), exports);
14850
14869
  __exportStar(__nccwpck_require__(88025), exports);
14851
14870
  __exportStar(__nccwpck_require__(39871), exports);
14871
+ __exportStar(__nccwpck_require__(61319), exports);
14852
14872
  __exportStar(__nccwpck_require__(45585), exports);
14853
14873
  __exportStar(__nccwpck_require__(47666), exports);
14854
14874
  __exportStar(__nccwpck_require__(60250), exports);
@@ -15888,6 +15908,34 @@ exports.getWorkspaceDependencies = getWorkspaceDependencies;
15888
15908
 
15889
15909
  /***/ }),
15890
15910
 
15911
+ /***/ 61319:
15912
+ /***/ ((__unused_webpack_module, exports) => {
15913
+
15914
+ "use strict";
15915
+
15916
+
15917
+ Object.defineProperty(exports, "__esModule", ({
15918
+ value: true
15919
+ }));
15920
+ exports.getReleaseMethod = exports.RELEASE_METHODS = void 0;
15921
+ exports.RELEASE_METHODS = {
15922
+ "semantic-release": {
15923
+ image: "semantic-release",
15924
+ script: "semanticRelease"
15925
+ },
15926
+ changesets: {
15927
+ image: "changesets",
15928
+ script: "changesetsRelease"
15929
+ }
15930
+ };
15931
+ const getReleaseMethod = config => {
15932
+ var _a, _b;
15933
+ return exports.RELEASE_METHODS[(_b = (_a = config.releases) === null || _a === void 0 ? void 0 : _a.method) !== null && _b !== void 0 ? _b : "semantic-release"];
15934
+ };
15935
+ exports.getReleaseMethod = getReleaseMethod;
15936
+
15937
+ /***/ }),
15938
+
15891
15939
  /***/ 44565:
15892
15940
  /***/ ((__unused_webpack_module, exports) => {
15893
15941
 
@@ -0,0 +1,13 @@
1
+ FROM node:lts-alpine
2
+
3
+ RUN apk add --no-cache bash git git-lfs
4
+
5
+ # no release tooling baked in: the changesets release logic lives in
6
+ # catci, which is materialized into the repository checkout
7
+ # (.catladder-generated/catci) by pipeline generation
8
+
9
+ RUN mkdir -p /scripts
10
+ COPY ./scripts/* /scripts/
11
+ RUN chmod +x /scripts/*
12
+
13
+ ENV PATH="/scripts:${PATH}"
@@ -0,0 +1,37 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ # 0. check and evaluate security audit or create MR with security audit template (and exit 1)
5
+ # 1. compute the next version from the last v* tag + pending .changeset/*.md files
6
+ # 2. write the changelog, commit, tag and push (all done by catci)
7
+
8
+ # NOTE: keep the security-audit gate below in sync with
9
+ # runner-images/semantic-release/scripts/semanticRelease
10
+
11
+ if [ "$GITHUB_ACTIONS" = "true" ]; then
12
+ # github container jobs: the workspace volume is owned by the host
13
+ # runner user while this step runs as the container user, and the
14
+ # safe.directory entry actions/checkout writes goes to a temporary
15
+ # HOME that is gone by now — git would refuse the repo ("dubious
16
+ # ownership")
17
+ git config --global --add safe.directory "$(pwd)"
18
+ fi
19
+
20
+ echo "doing security audit check"
21
+ CATCI=".catladder-generated/catci/index.js"
22
+ if [ -f "$CATCI" ]; then
23
+ # catci is materialized by pipeline generation — always the exact
24
+ # catladder version that generated this pipeline
25
+ if [ "$GITHUB_ACTIONS" = "true" ]; then
26
+ # github: gate only — the MR remediation is gitlab-specific
27
+ node "$CATCI" security-audit check ./
28
+ else
29
+ node "$CATCI" security-audit ci-job ./ "$GL_TOKEN" "$CI_DEFAULT_BRANCH" "$CI_PROJECT_ID" "$GITLAB_USER_ID"
30
+ fi
31
+ else
32
+ echo "$CATCI not found — regenerate the pipeline with a current catladder version (catenv)"
33
+ exit 1
34
+ fi
35
+
36
+ echo "doing changesets release"
37
+ node "$CATCI" release changesets
@@ -7,6 +7,10 @@ FROM node:22-alpine
7
7
  RUN apk add --no-cache bash git git-lfs
8
8
 
9
9
  # add semantic release
10
+ # NOTE: keep every plugin pinned to a major that is compatible with
11
+ # semantic-release@19 (they declare `semantic-release` as a peer dependency).
12
+ # Unpinned plugins drift to their latest major on image rebuild, which now
13
+ # requires semantic-release>=20 and fails with "plugins configuration is invalid".
10
14
  RUN yarn global add \
11
15
  semantic-release@19.0.5 \
12
16
  @semantic-release/commit-analyzer@13.0.1 \
@@ -8,6 +8,15 @@ set -e
8
8
 
9
9
  # better branches settings: https://github.com/semantic-release/semantic-release/issues/1581
10
10
 
11
+ if [ "$GITHUB_ACTIONS" = "true" ]; then
12
+ # github container jobs: the workspace volume is owned by the host
13
+ # runner user while this step runs as the container user, and the
14
+ # safe.directory entry actions/checkout writes goes to a temporary
15
+ # HOME that is gone by now — git would refuse the repo ("dubious
16
+ # ownership", surfacing as ENOGITREPO from semantic-release)
17
+ git config --global --add safe.directory "$(pwd)"
18
+ fi
19
+
11
20
  echo "doing security audit check"
12
21
  CATCI=".catladder-generated/catci/index.js"
13
22
  if [ -f "$CATCI" ]; then
@@ -30,6 +39,18 @@ fi
30
39
 
31
40
  echo "doing semantic release"
32
41
 
42
+ if [ "$GITHUB_ACTIONS" = "true" ]; then
43
+ # the gitlab publish plugin would fail on github; skip it (the tag
44
+ # and changelog commit still happen, only the gitlab release entry
45
+ # is gitlab-specific)
46
+ PUBLISH_PLUGIN=""
47
+ else
48
+ PUBLISH_PLUGIN=',
49
+ ["@semantic-release/gitlab", {
50
+ "gitlabUrl": "https://git.panter.ch"
51
+ }]'
52
+ fi
53
+
33
54
  if [ ! -e .releaserc ]; then
34
55
  cat >.releaserc <<EOF
35
56
  {
@@ -58,10 +79,7 @@ if [ ! -e .releaserc ]; then
58
79
  "@semantic-release/changelog",
59
80
  ["@semantic-release/git", {
60
81
  "message": "chore(\${branch.type}): \${nextRelease.version}\n\n\${nextRelease.notes}"
61
- }],
62
- ["@semantic-release/gitlab", {
63
- "gitlabUrl": "https://git.panter.ch"
64
- }]
82
+ }]${PUBLISH_PLUGIN}
65
83
  ],
66
84
  "branches": [
67
85
  "+([0-9])?(.{+([0-9]),x}).x",
@@ -81,4 +99,25 @@ if [ ! -e .releaserc ]; then
81
99
  }
82
100
  EOF
83
101
  fi
102
+
103
+ if [ "$GITHUB_ACTIONS" = "true" ]; then
104
+ TAGS_BEFORE=$(git tag --list 'v[0-9]*')
105
+ fi
106
+
84
107
  semantic-release
108
+
109
+ # tags pushed with the default GITHUB_TOKEN don't trigger `on: push:
110
+ # tags` workflows (github's recursion guard) — dispatch the
111
+ # taggedRelease workflow explicitly for a tag semantic-release created
112
+ if [ "$GITHUB_ACTIONS" = "true" ] && [ -f "$CATCI" ]; then
113
+ if [ -z "$TAGS_BEFORE" ]; then
114
+ NEW_TAG=$(git tag --list 'v[0-9]*' | tail -n1)
115
+ else
116
+ NEW_TAG=$(git tag --list 'v[0-9]*' | grep -Fxv -f <(printf '%s\n' "$TAGS_BEFORE") | tail -n1 || true)
117
+ fi
118
+ if [ -n "$NEW_TAG" ]; then
119
+ node "$CATCI" release dispatch-tagged-workflow "$NEW_TAG"
120
+ else
121
+ echo "no new release tag created — skipping taggedRelease dispatch"
122
+ fi
123
+ fi
@@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", {
18
18
  const rest_1 = require("@gitbeaker/rest");
19
19
  const evaluateSecurityAudit_1 = require("./security/evaluateSecurityAudit");
20
20
  const createSecurityAuditMergeRequest_1 = require("./security/createSecurityAuditMergeRequest");
21
+ const changesetsReleaseJob_1 = require("./release/changesetsReleaseJob");
21
22
  const GITLAB_HOST = "https://git.panter.ch";
22
23
  const USAGE = `catci — catladder CI companion
23
24
 
@@ -30,6 +31,15 @@ usage:
30
31
  evaluates ${createSecurityAuditMergeRequest_1.SECURITY_AUDIT_FILE_NAME}; exits 1 with instructions when
31
32
  the document is missing or unanswered (no remediation — works on
32
33
  any CI, including github)
34
+
35
+ catci release changesets
36
+ consumes pending .changeset/*.md files: computes the next version
37
+ from the last v* tag, writes the changelog, commits, tags and
38
+ pushes (no-op when no changesets are pending)
39
+
40
+ catci release dispatch-tagged-workflow <tag>
41
+ github only: dispatches the generated taggedRelease workflow for
42
+ the tag (tags pushed with the job token don't trigger it)
33
43
  `;
34
44
  const fail = message => {
35
45
  console.error(message);
@@ -93,6 +103,12 @@ const main = async () => {
93
103
  if (group === "security-audit" && command === "check" && args.length === 1) {
94
104
  return securityAuditCheck(args[0]);
95
105
  }
106
+ if (group === "release" && command === "changesets" && args.length === 0) {
107
+ return (0, changesetsReleaseJob_1.changesetsReleaseJob)();
108
+ }
109
+ if (group === "release" && command === "dispatch-tagged-workflow" && args.length === 1) {
110
+ return (0, changesetsReleaseJob_1.dispatchTaggedReleaseWorkflow)(args[0]);
111
+ }
96
112
  fail(USAGE);
97
113
  };
98
114
  main().catch(error => {
@@ -1 +1 @@
1
- {"version":3,"file":"catci.js","sourceRoot":"","sources":["../../../src/catci.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catci.js","sourceRoot":"","sources":["../../../src/catci.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export declare const BUMPS: readonly ["patch", "minor", "major"];
2
+ export type Bump = (typeof BUMPS)[number];
3
+ export type Changeset = {
4
+ fileName: string;
5
+ bump: Bump;
6
+ summary: string;
7
+ };
8
+ /**
9
+ * parses one changeset markdown file (official changesets format):
10
+ *
11
+ * ```
12
+ * ---
13
+ * "some-package": minor
14
+ * ---
15
+ *
16
+ * human-written summary
17
+ * ```
18
+ *
19
+ * The frontmatter is parsed by `@changesets/parse` (real YAML), then
20
+ * reduced to a single effective bump: `none` releases are dropped
21
+ * (they intentionally request no version change) and the highest of the
22
+ * rest wins. Throws on files that aren't valid changesets — a malformed
23
+ * file in `.changeset/` is a mistake worth failing the release over,
24
+ * not skipping silently.
25
+ */
26
+ export declare const parseChangesetFile: (fileName: string, content: string) => Changeset;
27
+ export declare const maxBump: (bumps: readonly Bump[]) => Bump;
28
+ /**
29
+ * the next version, derived from the last release tag (like
30
+ * semantic-release does). No previous tag → first release 1.0.0
31
+ * (matching semantic-release's first release).
32
+ */
33
+ export declare const getNextVersion: (lastTag: string | null, bump: Bump) => string;
34
+ /**
35
+ * the changelog entries for one release, grouped by bump level
36
+ * (mirroring the official changesets changelog layout), without the
37
+ * version heading — also used as the release commit body
38
+ */
39
+ export declare const renderChangelogEntries: (changesets: readonly Changeset[]) => string;
40
+ /**
41
+ * prepends the release section to the changelog, keeping the
42
+ * `# Changelog` header on top
43
+ */
44
+ export declare const prependToChangelog: (existingContent: string | null, version: string, date: string, entries: string) => string;