@catladder/cli 0.0.0-next-89bce6d0 → 0.0.0-next-d13ff46d

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 (35) hide show
  1. package/dist/apps/cli/src/release/changesetsReleaseJob.js +4 -0
  2. package/dist/apps/cli/src/release/changesetsReleaseJob.js.map +1 -1
  3. package/dist/apps/cli/src/release/githubQueuedRelease.js +22 -3
  4. package/dist/apps/cli/src/release/githubQueuedRelease.js.map +1 -1
  5. package/dist/apps/cli/src/release/stepSummary.d.ts +6 -0
  6. package/dist/apps/cli/src/release/stepSummary.js +32 -0
  7. package/dist/apps/cli/src/release/stepSummary.js.map +1 -0
  8. package/dist/bundles/catci/index.js +3 -3
  9. package/dist/bundles/catenv/index.js +216 -109
  10. package/dist/bundles/cli/index.js +216 -109
  11. package/dist/bundles/skills/catladder-config/SKILL.md +4 -0
  12. package/dist/bundles/skills/catladder-migrate-ci-backend/SKILL.md +249 -0
  13. package/dist/bundles/skills/catladder-migrate-release-method/SKILL.md +233 -0
  14. package/dist/bundles/skills/catladder-pipelines/SKILL.md +10 -1
  15. package/dist/bundles/skills/catladder-releases/SKILL.md +20 -10
  16. package/dist/bundles/skills/catladder-secrets/SKILL.md +2 -0
  17. package/dist/packages/pipeline/src/backends/github/GithubBackend.js +93 -72
  18. package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
  19. package/dist/packages/pipeline/src/backends/github/ensureImageJobs.d.ts +12 -0
  20. package/dist/packages/pipeline/src/backends/github/ensureImageJobs.js +40 -0
  21. package/dist/packages/pipeline/src/backends/github/ensureImageJobs.js.map +1 -0
  22. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.d.ts +17 -14
  23. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js +76 -37
  24. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js.map +1 -1
  25. package/dist/skills/catladder-config/SKILL.md +4 -0
  26. package/dist/skills/catladder-migrate-ci-backend/SKILL.md +249 -0
  27. package/dist/skills/catladder-migrate-release-method/SKILL.md +233 -0
  28. package/dist/skills/catladder-pipelines/SKILL.md +10 -1
  29. package/dist/skills/catladder-releases/SKILL.md +20 -10
  30. package/dist/skills/catladder-secrets/SKILL.md +2 -0
  31. package/dist/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +1 -1
  33. package/src/release/changesetsReleaseJob.ts +6 -0
  34. package/src/release/githubQueuedRelease.ts +37 -3
  35. package/src/release/stepSummary.ts +27 -0
@@ -2288,9 +2288,8 @@ const ciVariables_1 = __nccwpck_require__(88393);
2288
2288
  const index_1 = __nccwpck_require__(68906);
2289
2289
  const createGithubJobs_1 = __nccwpck_require__(57877);
2290
2290
  const jobImagesPlan_1 = __nccwpck_require__(47864);
2291
- const scriptFunctions_1 = __nccwpck_require__(79252);
2291
+ const ensureImageJobs_1 = __nccwpck_require__(70051);
2292
2292
  const shippedCatci_1 = __nccwpck_require__(79024);
2293
- const utils_1 = __nccwpck_require__(24516);
2294
2293
  const githubReleaseJobs_1 = __nccwpck_require__(89800);
2295
2294
  const scriptFiles_1 = __nccwpck_require__(30966);
2296
2295
  const WORKFLOWS_FOLDER = ".github/workflows";
@@ -2299,9 +2298,13 @@ const WORKFLOWS_FOLDER = ".github/workflows";
2299
2298
  * user-maintained workflows in the same folder
2300
2299
  */
2301
2300
  const GENERATED_FILE_PREFIX = "catladder-";
2301
+ // NOTE on the emoji prefixes: github sorts the Actions sidebar by raw
2302
+ // code point, so the đŸ› ī¸ (U+1F6E0) prefix makes the pipeline workflows
2303
+ // sort BELOW the triggerable action workflows (â†Šī¸ âšī¸ â–ļī¸ 🚀, all lower
2304
+ // code points) — the things a human clicks come first.
2302
2305
  const TRIGGER_WORKFLOWS = {
2303
2306
  mr: {
2304
- name: "catladder review",
2307
+ name: "đŸ› ī¸ catladder review",
2305
2308
  on: { pull_request: { types: ["opened", "synchronize", "reopened"] } },
2306
2309
  concurrency: {
2307
2310
  group: "catladder-review-${{ github.event.number }}",
@@ -2309,12 +2312,12 @@ const TRIGGER_WORKFLOWS = {
2309
2312
  },
2310
2313
  },
2311
2314
  mainBranch: {
2312
- name: "catladder main",
2315
+ name: "đŸ› ī¸ catladder main",
2313
2316
  // TODO: make the default branch configurable
2314
2317
  on: { push: { branches: ["main"] } },
2315
2318
  },
2316
2319
  taggedRelease: {
2317
- name: "catladder release",
2320
+ name: "đŸ› ī¸ catladder release",
2318
2321
  // tags pushed with the default GITHUB_TOKEN (as the release job
2319
2322
  // does) don't trigger `on: push: tags` — the release job therefore
2320
2323
  // also dispatches this workflow explicitly for the new tag
@@ -2364,15 +2367,18 @@ class GithubBackend {
2364
2367
  ...(0, index_1.getPipelineOptions)(config, this.type).runnerVariables,
2365
2368
  };
2366
2369
  const reviewStopJobs = {};
2367
- // jobs routed to the workflow_dispatch "manual tasks" workflow. A
2368
- // manual job and its build closure live here instead of an automatic
2369
- // workflow; `manualJobConditions` is the `if` that selects each one
2370
- // from the dispatch input, `manualDispatchOptions` the leaf jobs that
2371
- // become dropdown choices (closure jobs run because their leaf was
2372
- // chosen, not on their own).
2373
- const manualJobs = {};
2374
- const manualJobConditions = {};
2375
- const manualDispatchOptions = [];
2370
+ // jobs routed to the per-kind workflow_dispatch workflows (deploy /
2371
+ // stop / rollback). A manual job and its build closure live there
2372
+ // instead of an automatic workflow; `conditions` is the `if` that
2373
+ // selects each one from the dispatch input, `options` the leaf jobs
2374
+ // that become dropdown choices (closure jobs run because their leaf
2375
+ // was chosen, not on their own). A closure job serving leaves of
2376
+ // several kinds is duplicated into each kind's workflow.
2377
+ const manualKindBuckets = {
2378
+ deploy: { jobs: {}, conditions: {}, options: [], envTypes: [] },
2379
+ stop: { jobs: {}, conditions: {}, options: [], envTypes: [] },
2380
+ rollback: { jobs: {}, conditions: {}, options: [], envTypes: [] },
2381
+ };
2376
2382
  for (const trigger of config_1.ALL_PIPELINE_TRIGGERS) {
2377
2383
  const allJobs = await (0, createAllJobs_1.createAllJobs)({
2378
2384
  config,
@@ -2449,32 +2455,46 @@ class GithubBackend {
2449
2455
  }
2450
2456
  }
2451
2457
  }
2458
+ const kindOfLeaf = new Map(leafIds.map((id) => [id, manualKind(triggerJobs.get(id).job)]));
2452
2459
  const jobs = {};
2453
2460
  for (const [id, { githubJob }] of triggerJobs) {
2454
2461
  const leaves = servesLeaves.get(id);
2455
2462
  if (leaves) {
2456
- manualJobs[id] = githubJob;
2457
- manualJobConditions[id] = [...leaves]
2458
- .sort()
2459
- .map((leaf) => `inputs.job == '${leaf}'`)
2460
- .join(" || ");
2463
+ // one entry per kind the job serves — restricted to that
2464
+ // kind's leaves, so the `if` only references its own inputs
2465
+ for (const kind of new Set([...leaves].map((leaf) => kindOfLeaf.get(leaf)))) {
2466
+ const bucket = manualKindBuckets[kind];
2467
+ bucket.jobs[id] = githubJob;
2468
+ bucket.conditions[id] = [...leaves]
2469
+ .filter((leaf) => kindOfLeaf.get(leaf) === kind)
2470
+ .sort()
2471
+ .map((leaf) => `inputs.job == '${leaf}'`)
2472
+ .join(" || ");
2473
+ }
2461
2474
  }
2462
2475
  else {
2463
2476
  jobs[id] = githubJob;
2464
2477
  }
2465
2478
  }
2466
- manualDispatchOptions.push(...leafIds);
2479
+ for (const id of leafIds) {
2480
+ const bucket = manualKindBuckets[kindOfLeaf.get(id)];
2481
+ bucket.options.push(id);
2482
+ const context = triggerJobs.get(id).context;
2483
+ if (context.type === "component") {
2484
+ bucket.envTypes.push(context.environment.envType);
2485
+ }
2486
+ }
2467
2487
  if (trigger === "mr") {
2468
2488
  Object.assign(jobs, (0, githubReleaseJobs_1.getGithubReleaseCheckJobs)(config, images));
2469
2489
  }
2470
2490
  if (trigger === "mainBranch") {
2471
- const releaseJobs = (0, githubReleaseJobs_1.getGithubReleaseJobs)(config, Object.keys(jobs), images);
2472
- Object.assign(jobs, releaseJobs.main);
2473
- for (const [id, job] of Object.entries(releaseJobs.manual)) {
2474
- manualJobs[id] = job;
2475
- manualJobConditions[id] = `inputs.job == '${id}'`;
2476
- manualDispatchOptions.push(id);
2477
- }
2491
+ // auto release mode: the release job runs at the end of the
2492
+ // main workflow itself
2493
+ Object.assign(jobs, (0, githubReleaseJobs_1.getGithubReleaseJobs)(config, Object.keys(jobs), images));
2494
+ // the dispatch workflow to trigger a release by hand (with a
2495
+ // force checkbox where the method distinguishes it)
2496
+ workflows[`${GENERATED_FILE_PREFIX}create-release.yml`] =
2497
+ (0, githubReleaseJobs_1.getGithubCreateReleaseWorkflow)(config, images, workflowEnv);
2478
2498
  // manual release mode: the workflow that runs a queued release
2479
2499
  // once the main workflow completed green
2480
2500
  const releaseOnGreen = (0, githubReleaseJobs_1.getGithubReleaseOnGreenWorkflow)(config, images, TRIGGER_WORKFLOWS.mainBranch.name, workflowEnv);
@@ -2488,41 +2508,59 @@ class GithubBackend {
2488
2508
  ...TRIGGER_WORKFLOWS[trigger],
2489
2509
  ...workflowPermissions(images),
2490
2510
  env: workflowEnv,
2491
- jobs: { ...makeEnsureImageGithubJobs(images), ...jobs },
2511
+ jobs: { ...(0, ensureImageJobs_1.makeEnsureImageGithubJobs)(images), ...jobs },
2492
2512
  };
2493
2513
  }
2494
2514
  }
2495
2515
  if (Object.keys(reviewStopJobs).length > 0) {
2496
2516
  workflows[`${GENERATED_FILE_PREFIX}review-stop.yml`] = {
2497
- name: "catladder review stop",
2517
+ name: "đŸ› ī¸ catladder review stop",
2498
2518
  on: { pull_request: { types: ["closed"] } },
2499
2519
  ...workflowPermissions(images),
2500
2520
  env: workflowEnv,
2501
- jobs: { ...makeEnsureImageGithubJobs(images), ...reviewStopJobs },
2521
+ jobs: { ...(0, ensureImageJobs_1.makeEnsureImageGithubJobs)(images), ...reviewStopJobs },
2502
2522
  };
2503
2523
  }
2504
- if (Object.keys(manualJobs).length > 0) {
2505
- workflows[`${GENERATED_FILE_PREFIX}manual.yml`] = {
2506
- name: "catladder manual tasks",
2524
+ for (const [kind, bucket] of Object.entries(manualKindBuckets)) {
2525
+ if (Object.keys(bucket.jobs).length === 0) {
2526
+ continue;
2527
+ }
2528
+ const options = [...new Set(bucket.options)];
2529
+ // a single candidate needs no dropdown — the dispatch just runs it
2530
+ const singleTask = options.length === 1;
2531
+ // one common env across the kind's tasks → carry it in the name
2532
+ // ("â–ļī¸ catladder deploy prod"); mixed envs keep the generic name
2533
+ // and the dropdown distinguishes
2534
+ const envTypes = [...new Set(bucket.envTypes)];
2535
+ const envSuffix = envTypes.length === 1 &&
2536
+ bucket.envTypes.length === bucket.options.length
2537
+ ? ` ${envTypes[0]}`
2538
+ : "";
2539
+ workflows[`${GENERATED_FILE_PREFIX}${kind}.yml`] = {
2540
+ name: `${MANUAL_KIND_WORKFLOW_NAMES[kind]}${envSuffix}`,
2507
2541
  on: {
2508
- workflow_dispatch: {
2509
- inputs: {
2510
- job: {
2511
- description: "the task to run",
2512
- required: true,
2513
- type: "choice",
2514
- options: [...new Set(manualDispatchOptions)],
2542
+ workflow_dispatch: singleTask
2543
+ ? {}
2544
+ : {
2545
+ inputs: {
2546
+ job: {
2547
+ description: "the task to run",
2548
+ required: true,
2549
+ type: "choice",
2550
+ options,
2551
+ },
2515
2552
  },
2516
2553
  },
2517
- },
2518
2554
  },
2519
2555
  ...workflowPermissions(images),
2520
2556
  env: workflowEnv,
2521
2557
  jobs: {
2522
- ...makeEnsureImageGithubJobs(images),
2523
- ...Object.fromEntries(Object.entries(manualJobs).map(([id, job]) => [
2558
+ ...(0, ensureImageJobs_1.makeEnsureImageGithubJobs)(images),
2559
+ ...Object.fromEntries(Object.entries(bucket.jobs).map(([id, job]) => [
2524
2560
  id,
2525
- { ...job, if: `\${{ ${manualJobConditions[id]} }}` },
2561
+ singleTask
2562
+ ? job
2563
+ : { ...job, if: `\${{ ${bucket.conditions[id]} }}` },
2526
2564
  ])),
2527
2565
  },
2528
2566
  };
@@ -2537,33 +2575,6 @@ exports.GithubBackend = GithubBackend;
2537
2575
  const workflowPermissions = (_images) => ({
2538
2576
  permissions: { contents: "read", packages: "write" },
2539
2577
  });
2540
- /**
2541
- * the image build jobs: always run (github has no server-side
2542
- * changes-filter), the existence check makes unchanged runs fast.
2543
- * Docker is native on github runners — no container, no dind.
2544
- */
2545
- const makeEnsureImageGithubJobs = (images) => Object.fromEntries(images.getEnsureJobs().map((job) => {
2546
- var _a, _b;
2547
- return [
2548
- (0, createGithubJobs_1.githubGlobalJobId)(job.name),
2549
- {
2550
- name: job.name,
2551
- "runs-on": "ubuntu-latest",
2552
- steps: [
2553
- { name: "Checkout", uses: "actions/checkout@v4" },
2554
- {
2555
- name: job.name,
2556
- id: "main",
2557
- run: [
2558
- ...(0, scriptFunctions_1.getGithubScriptFunctionDefinitions)(),
2559
- ...((_b = (_a = job.script) === null || _a === void 0 ? void 0 : _a.filter(utils_1.notNil)) !== null && _b !== void 0 ? _b : []),
2560
- ].join("\n"),
2561
- shell: "bash",
2562
- },
2563
- ],
2564
- },
2565
- ];
2566
- }));
2567
2578
  const workflowFileName = (trigger) => {
2568
2579
  switch (trigger) {
2569
2580
  case "mr":
@@ -2587,10 +2598,20 @@ const isReviewStopJob = (context, job) => {
2587
2598
  };
2588
2599
  /**
2589
2600
  * stop/rollback jobs of non-review environments have no automatic
2590
- * trigger; they are collected in a workflow_dispatch workflow
2601
+ * trigger; they are collected in workflow_dispatch workflows
2591
2602
  * (gitlab runs them as manual jobs inside the pipeline)
2592
2603
  */
2593
2604
  const isManualTaskJob = (job) => job.stage === "stop" || job.stage === "rollback";
2605
+ const MANUAL_KIND_WORKFLOW_NAMES = {
2606
+ deploy: "â–ļī¸ catladder deploy",
2607
+ stop: "âšī¸ catladder stop",
2608
+ rollback: "â†Šī¸ catladder rollback",
2609
+ };
2610
+ const manualKind = (job) => job.stage === "stop"
2611
+ ? "stop"
2612
+ : job.stage === "rollback"
2613
+ ? "rollback"
2614
+ : "deploy";
2594
2615
  //# sourceMappingURL=GithubBackend.js.map
2595
2616
 
2596
2617
  /***/ }),
@@ -3020,17 +3041,78 @@ exports.getUploadProviderIds = getUploadProviderIds;
3020
3041
 
3021
3042
  /***/ }),
3022
3043
 
3044
+ /***/ 70051:
3045
+ /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
3046
+
3047
+ "use strict";
3048
+
3049
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
3050
+ exports.makeEnsureImageGithubJobs = void 0;
3051
+ const createGithubJobs_1 = __nccwpck_require__(57877);
3052
+ const scriptFunctions_1 = __nccwpck_require__(79252);
3053
+ const utils_1 = __nccwpck_require__(24516);
3054
+ /**
3055
+ * the image build jobs: always run (github has no server-side
3056
+ * changes-filter), the existence check makes unchanged runs fast.
3057
+ * Docker is native on github runners — no container, no dind.
3058
+ * `only` restricts to the named images (e.g. the create-release
3059
+ * workflow needs just the release image).
3060
+ */
3061
+ const makeEnsureImageGithubJobs = (images, options = {}) => Object.fromEntries(images
3062
+ .getEnsureJobs()
3063
+ .filter((job) => !options.only || options.only.includes(job.name))
3064
+ .map((job) => {
3065
+ var _a, _b;
3066
+ return [
3067
+ (0, createGithubJobs_1.githubGlobalJobId)(job.name),
3068
+ {
3069
+ name: job.name,
3070
+ "runs-on": "ubuntu-latest",
3071
+ steps: [
3072
+ { name: "Checkout", uses: "actions/checkout@v4" },
3073
+ {
3074
+ name: job.name,
3075
+ id: "main",
3076
+ run: [
3077
+ ...(0, scriptFunctions_1.getGithubScriptFunctionDefinitions)(),
3078
+ ...((_b = (_a = job.script) === null || _a === void 0 ? void 0 : _a.filter(utils_1.notNil)) !== null && _b !== void 0 ? _b : []),
3079
+ ].join("\n"),
3080
+ shell: "bash",
3081
+ },
3082
+ ],
3083
+ },
3084
+ ];
3085
+ }));
3086
+ exports.makeEnsureImageGithubJobs = makeEnsureImageGithubJobs;
3087
+ //# sourceMappingURL=ensureImageJobs.js.map
3088
+
3089
+ /***/ }),
3090
+
3023
3091
  /***/ 89800:
3024
3092
  /***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
3025
3093
 
3026
3094
  "use strict";
3027
3095
 
3028
3096
  Object.defineProperty(exports, "__esModule", ({ value: true }));
3029
- exports.getGithubReleaseCheckJobs = exports.getGithubReleaseOnGreenWorkflow = exports.getGithubReleaseJobs = void 0;
3097
+ exports.getGithubReleaseCheckJobs = exports.getGithubReleaseOnGreenWorkflow = exports.getGithubCreateReleaseWorkflow = exports.getGithubReleaseJobs = void 0;
3030
3098
  const createGithubJobs_1 = __nccwpck_require__(57877);
3099
+ const ensureImageJobs_1 = __nccwpck_require__(70051);
3031
3100
  const release_1 = __nccwpck_require__(38904);
3032
3101
  const shippedCatci_1 = __nccwpck_require__(79024);
3033
3102
  const CATCI = `${shippedCatci_1.GENERATED_CATCI_FOLDER}/index.js`;
3103
+ /**
3104
+ * the build job of the release image only — the create-release
3105
+ * dispatch workflow needs no other image (empty for external images)
3106
+ */
3107
+ const makeReleaseImageEnsureJobs = (config, images) => {
3108
+ const resolved = images.resolveRef({
3109
+ catladderImage: (0, release_1.getReleaseMethod)(config).image,
3110
+ });
3111
+ if (!resolved.need || typeof resolved.need !== "object") {
3112
+ return {};
3113
+ }
3114
+ return (0, ensureImageJobs_1.makeEnsureImageGithubJobs)(images, { only: [resolved.need.job] });
3115
+ };
3034
3116
  const createReleaseJob = (config, images, options = {}) => {
3035
3117
  var _a;
3036
3118
  const method = (0, release_1.getReleaseMethod)(config);
@@ -3084,6 +3166,7 @@ const createReleaseJob = (config, images, options = {}) => {
3084
3166
  {
3085
3167
  name: "check main workflow",
3086
3168
  id: "queue",
3169
+ ...(options.queueCheckIf ? { if: options.queueCheckIf } : {}),
3087
3170
  run: `node ${CATCI} release github-queue-check`,
3088
3171
  shell: "bash",
3089
3172
  },
@@ -3101,51 +3184,75 @@ const createReleaseJob = (config, images, options = {}) => {
3101
3184
  };
3102
3185
  };
3103
3186
  /**
3104
- * the release jobs for the github backend (the counterpart of the
3105
- * gitlab release jobs):
3106
- * - releases.when === "auto": the release job runs in the main-branch
3107
- * workflow after all other jobs; a force variant goes to the manual
3108
- * tasks workflow
3109
- * - otherwise (manual, the default): the release job goes to the
3110
- * manual tasks workflow. Its queue-check step releases right away on
3111
- * a green main run and otherwise queues the release for the
3112
- * release-on-green workflow (see getGithubReleaseOnGreenWorkflow) —
3113
- * the counterpart of gitlab's queue button + executor pair.
3187
+ * the release jobs of the main-branch workflow: with releases.when ===
3188
+ * "auto" the release runs at the end of every main workflow run.
3189
+ * Manual releasing happens via the create-release dispatch workflow
3190
+ * (see getGithubCreateReleaseWorkflow) instead.
3114
3191
  */
3115
3192
  const getGithubReleaseJobs = (config, mainWorkflowJobIds, images) => {
3116
3193
  var _a;
3117
- const method = (0, release_1.getReleaseMethod)(config);
3118
- if (((_a = config.releases) === null || _a === void 0 ? void 0 : _a.when) === "auto") {
3119
- return {
3120
- main: {
3121
- "create-release": createReleaseJob(config, images, {
3122
- needs: mainWorkflowJobIds,
3123
- }),
3124
- },
3125
- manual: {
3126
- "force-create-release": createReleaseJob(config, images, {
3127
- extraEnv: method.forceReleaseVariables,
3128
- }),
3129
- },
3130
- };
3194
+ if (((_a = config.releases) === null || _a === void 0 ? void 0 : _a.when) !== "auto") {
3195
+ return {};
3131
3196
  }
3132
3197
  return {
3133
- main: {},
3134
- manual: {
3135
- "create-release": createReleaseJob(config, images, { queueCheck: true }),
3136
- // an explicit force option wherever the method distinguishes it
3137
- // (e.g. changesets: release a patch bump without changesets)
3138
- ...(method.forceReleaseVariables
3198
+ "create-release": createReleaseJob(config, images, {
3199
+ needs: mainWorkflowJobIds,
3200
+ }),
3201
+ };
3202
+ };
3203
+ exports.getGithubReleaseJobs = getGithubReleaseJobs;
3204
+ /**
3205
+ * the dispatch workflow to trigger a release by hand — a first-class
3206
+ * entry in the Actions sidebar (the counterpart of gitlab's `create
3207
+ * release` button). Its queue-check step releases right away when the
3208
+ * main workflow run for HEAD is green and otherwise queues the release
3209
+ * for the release-on-green workflow. Where the release method
3210
+ * distinguishes a force mode (e.g. changesets: release a patch bump
3211
+ * without pending changesets), forcing is a checkbox input — a forced
3212
+ * release skips the queue-check and releases immediately, whatever the
3213
+ * pipeline state.
3214
+ */
3215
+ const getGithubCreateReleaseWorkflow = (config, images, workflowEnv) => {
3216
+ const method = (0, release_1.getReleaseMethod)(config);
3217
+ const forceVariables = method.forceReleaseVariables;
3218
+ const job = createReleaseJob(config, images, {
3219
+ queueCheck: true,
3220
+ ...(forceVariables
3221
+ ? {
3222
+ queueCheckIf: "${{ !inputs.force }}",
3223
+ // only effective when the force checkbox is ticked
3224
+ extraEnv: Object.fromEntries(Object.entries(forceVariables).map(([key, value]) => [
3225
+ key,
3226
+ `\${{ inputs.force && '${value}' || '' }}`,
3227
+ ])),
3228
+ }
3229
+ : {}),
3230
+ });
3231
+ return {
3232
+ name: "🚀 catladder create release",
3233
+ on: {
3234
+ workflow_dispatch: forceVariables
3139
3235
  ? {
3140
- "force-create-release": createReleaseJob(config, images, {
3141
- extraEnv: method.forceReleaseVariables,
3142
- }),
3236
+ inputs: {
3237
+ force: {
3238
+ description: "force: release even without pending changes (patch bump), ignoring the pipeline state",
3239
+ required: false,
3240
+ type: "boolean",
3241
+ default: false,
3242
+ },
3243
+ },
3143
3244
  }
3144
- : {}),
3245
+ : {},
3246
+ },
3247
+ permissions: { contents: "read", packages: "write" },
3248
+ env: workflowEnv,
3249
+ jobs: {
3250
+ ...makeReleaseImageEnsureJobs(config, images),
3251
+ "create-release": job,
3145
3252
  },
3146
3253
  };
3147
3254
  };
3148
- exports.getGithubReleaseJobs = getGithubReleaseJobs;
3255
+ exports.getGithubCreateReleaseWorkflow = getGithubCreateReleaseWorkflow;
3149
3256
  /**
3150
3257
  * the release-on-green workflow (manual release mode only): runs on
3151
3258
  * every completed main workflow run. A lightweight host job checks the
@@ -3164,7 +3271,7 @@ const getGithubReleaseOnGreenWorkflow = (config, images, mainWorkflowName, workf
3164
3271
  return null;
3165
3272
  }
3166
3273
  return {
3167
- name: "catladder release on green",
3274
+ name: "đŸ› ī¸ catladder release on green",
3168
3275
  on: {
3169
3276
  workflow_run: {
3170
3277
  workflows: [mainWorkflowName],