@catladder/cli 0.0.0-next-b3e567e8 → 0.0.0-next-78f04d3f

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 (53) hide show
  1. package/dist/apps/cli/src/catci.js +23 -0
  2. package/dist/apps/cli/src/catci.js.map +1 -1
  3. package/dist/apps/cli/src/release/githubQueuedRelease.d.ts +14 -0
  4. package/dist/apps/cli/src/release/githubQueuedRelease.js +152 -0
  5. package/dist/apps/cli/src/release/githubQueuedRelease.js.map +1 -0
  6. package/dist/bundles/catci/index.js +3 -3
  7. package/dist/bundles/catenv/index.js +516 -136
  8. package/dist/bundles/cli/index.js +516 -136
  9. package/dist/bundles/skills/catladder-builds/SKILL.md +49 -2
  10. package/dist/bundles/skills/catladder-builds/references/build-types.md +2 -2
  11. package/dist/bundles/skills/catladder-pipelines/SKILL.md +13 -3
  12. package/dist/bundles/skills/catladder-releases/SKILL.md +13 -2
  13. package/dist/packages/pipeline/src/backends/github/GithubBackend.js +11 -4
  14. package/dist/packages/pipeline/src/backends/github/GithubBackend.js.map +1 -1
  15. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.d.ts +18 -2
  16. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js +92 -10
  17. package/dist/packages/pipeline/src/backends/github/githubReleaseJobs.js.map +1 -1
  18. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js +35 -9
  19. package/dist/packages/pipeline/src/backends/gitlab/GitlabBackend.js.map +1 -1
  20. package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.d.ts +285 -3
  21. package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js +142 -54
  22. package/dist/packages/pipeline/src/backends/gitlab/gitlabReleaseJobs.js.map +1 -1
  23. package/dist/packages/pipeline/src/build/types.d.ts +6 -5
  24. package/dist/packages/pipeline/src/build/types.js.map +1 -1
  25. package/dist/packages/pipeline/src/customImages/hash.d.ts +9 -0
  26. package/dist/packages/pipeline/src/customImages/hash.js +41 -16
  27. package/dist/packages/pipeline/src/customImages/hash.js.map +1 -1
  28. package/dist/packages/pipeline/src/customImages/jobImagesPlan.d.ts +23 -5
  29. package/dist/packages/pipeline/src/customImages/jobImagesPlan.js +177 -43
  30. package/dist/packages/pipeline/src/customImages/jobImagesPlan.js.map +1 -1
  31. package/dist/packages/pipeline/src/customImages/projectImages.d.ts +67 -0
  32. package/dist/packages/pipeline/src/customImages/projectImages.js +9 -0
  33. package/dist/packages/pipeline/src/customImages/projectImages.js.map +1 -0
  34. package/dist/packages/pipeline/src/deploy/types/custom.d.ts +2 -2
  35. package/dist/packages/pipeline/src/deploy/types/index.d.ts +4 -4
  36. package/dist/packages/pipeline/src/deploy/types/pages.d.ts +2 -2
  37. package/dist/packages/pipeline/src/index.d.ts +2 -0
  38. package/dist/packages/pipeline/src/index.js +2 -0
  39. package/dist/packages/pipeline/src/index.js.map +1 -1
  40. package/dist/packages/pipeline/src/types/config.d.ts +8 -0
  41. package/dist/packages/pipeline/src/types/config.js.map +1 -1
  42. package/dist/packages/pipeline/src/types/github-types.d.ts +1 -0
  43. package/dist/packages/pipeline/src/types/jobs.d.ts +2 -1
  44. package/dist/packages/pipeline/src/types/jobs.js.map +1 -1
  45. package/dist/packages/pipeline/src/types/release.d.ts +7 -1
  46. package/dist/skills/catladder-builds/SKILL.md +49 -2
  47. package/dist/skills/catladder-builds/references/build-types.md +2 -2
  48. package/dist/skills/catladder-pipelines/SKILL.md +13 -3
  49. package/dist/skills/catladder-releases/SKILL.md +13 -2
  50. package/dist/tsconfig.tsbuildinfo +1 -1
  51. package/package.json +1 -1
  52. package/src/catci.ts +30 -0
  53. package/src/release/githubQueuedRelease.ts +173 -0
@@ -3,6 +3,8 @@ export * from "./backends";
3
3
  export * from "./types";
4
4
  export * from "./rules";
5
5
  export * from "./runner";
6
+ export * from "./customImages/projectImages";
7
+ export * from "./customImages/jobImagesPlan";
6
8
  export * from "./config";
7
9
  export * from "./store";
8
10
  export * from "./context";
@@ -19,6 +19,8 @@ __exportStar(require("./backends"), exports);
19
19
  __exportStar(require("./types"), exports);
20
20
  __exportStar(require("./rules"), exports);
21
21
  __exportStar(require("./runner"), exports);
22
+ __exportStar(require("./customImages/projectImages"), exports);
23
+ __exportStar(require("./customImages/jobImagesPlan"), exports);
22
24
  __exportStar(require("./config"), exports);
23
25
  __exportStar(require("./store"), exports);
24
26
  __exportStar(require("./context"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/pipeline/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB;AACzB,0CAAwB;AACxB,4CAA0B;AAC1B,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB;AACzB,4CAA0B;AAC1B,qDAAmC;AACnC,sDAAoC;AACpC,kDAAgC;AAChC,2CAAyB;AACzB,gDAA8B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../packages/pipeline/src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,6CAA2B;AAC3B,0CAAwB;AACxB,0CAAwB;AACxB,2CAAyB;AACzB,+DAA6C;AAC7C,+DAA6C;AAC7C,2CAAyB;AACzB,0CAAwB;AACxB,4CAA0B;AAC1B,0CAAwB;AACxB,2CAAyB;AACzB,2CAAyB;AACzB,4CAA0B;AAC1B,qDAAmC;AACnC,sDAAoC;AACpC,kDAAgC;AAChC,2CAAyB;AACzB,gDAA8B"}
@@ -9,6 +9,7 @@ import type { Hooks } from "./hooks";
9
9
  import type { ReleaseConfig } from "./release";
10
10
  import type { CatladderStore } from "../store";
11
11
  import type { AgentSkillsConfig } from "../agentSkills/types";
12
+ import type { ProjectImageConfig } from "../customImages/projectImages";
12
13
  import type { VerifyConfig } from "../verify/types";
13
14
  export declare const ALL_PIPELINE_TRIGGERS: readonly ["mainBranch", "mr", "taggedRelease"];
14
15
  export type PipelineTrigger = (typeof ALL_PIPELINE_TRIGGERS)[number];
@@ -294,6 +295,13 @@ export type Config<C extends ConfigProps = never> = {
294
295
  */
295
296
  domainCanonical?: string;
296
297
  agents?: Record<string, AgentConfig>;
298
+ /**
299
+ * docker images declared by the project, built automatically in the
300
+ * pipeline: content-hashed into the project's own registry and only
301
+ * rebuilt when their inputs change. Reference them in any `jobImage`
302
+ * field via `{ image: "<key>" }`.
303
+ */
304
+ images?: Record<string, ProjectImageConfig>;
297
305
  builds?: Record<string, WorkspaceBuildConfig>;
298
306
  /**
299
307
  * components (sub apps)
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/config.ts"],"names":[],"mappings":";;;AAca,QAAA,qBAAqB,GAAG;IACnC,YAAY;IACZ,IAAI;IACJ,eAAe;CACP,CAAC;AAGX;;;GAGG;AACU,QAAA,SAAS,GAAG;IACvB,GAAG,EAAE;QACH,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,IAAI,CAAC;KACjB;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE;KACb;CACO,CAAC;AAEX;;;;GAIG;AACI,MAAM,oBAAoB,GAAG,CAAC,OAAwB,EAAE,EAAE,CAC/D,MAAM,CAAC,OAAO,CAAC,iBAAS,CAAC;KACtB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CACf,CAAC,CAAC,QAAuC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC7D;KACA,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAY,CAAC,CAAC;AALnB,QAAA,oBAAoB,wBAKD;AAEnB,QAAA,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC;AACtC,QAAA,iBAAiB,GAAG,oBAAyB,CAAC;AAGpD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAkB,EAAE;IAC3D,OAAO,GAAG,IAAI,iBAAS,CAAC;AAC1B,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/config.ts"],"names":[],"mappings":";;;AAea,QAAA,qBAAqB,GAAG;IACnC,YAAY;IACZ,IAAI;IACJ,eAAe;CACP,CAAC;AAGX;;;GAGG;AACU,QAAA,SAAS,GAAG;IACvB,GAAG,EAAE;QACH,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD,MAAM,EAAE;QACN,QAAQ,EAAE,CAAC,IAAI,CAAC;KACjB;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,IAAI,EAAE;QACJ,QAAQ,EAAE,CAAC,eAAe,CAAC;KAC5B;IACD,KAAK,EAAE;QACL,QAAQ,EAAE,EAAE;KACb;CACO,CAAC;AAEX;;;;GAIG;AACI,MAAM,oBAAoB,GAAG,CAAC,OAAwB,EAAE,EAAE,CAC/D,MAAM,CAAC,OAAO,CAAC,iBAAS,CAAC;KACtB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CACf,CAAC,CAAC,QAAuC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC7D;KACA,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAY,CAAC,CAAC;AALnB,QAAA,oBAAoB,wBAKD;AAEnB,QAAA,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,iBAAS,CAAC,CAAC;AACtC,QAAA,iBAAiB,GAAG,oBAAyB,CAAC;AAGpD,MAAM,aAAa,GAAG,CAAC,GAAW,EAAkB,EAAE;IAC3D,OAAO,GAAG,IAAI,iBAAS,CAAC;AAC1B,CAAC,CAAC;AAFW,QAAA,aAAa,iBAExB"}
@@ -38,6 +38,7 @@ export type GithubJob = {
38
38
  permissions?: Record<string, string>;
39
39
  if?: string;
40
40
  "continue-on-error"?: boolean;
41
+ outputs?: Record<string, string>;
41
42
  steps: GithubStep[];
42
43
  };
43
44
  export type GithubWorkflow = {
@@ -1,5 +1,6 @@
1
1
  import type { UnspecifiedEnvVars } from "..";
2
2
  import type { CatladderImageRef } from "../runner";
3
+ import type { ProjectImageRef } from "../customImages/projectImages";
3
4
  import type { CacheConfig } from "../build/types";
4
5
  import type { Artifacts, GitlabJobCache, GitlabJobDef, GitlabJobImage, GitlabRule } from "./gitlab-types";
5
6
  export type CatladderJobCache = GitlabJobCache & {
@@ -186,7 +187,7 @@ export type GitlabJobFields = {
186
187
  * catladder-provided job image (resolved by the backend to an image
187
188
  * built in the repository's own registry)
188
189
  */
189
- image?: GitlabJobImage | CatladderImageRef;
190
+ image?: GitlabJobImage | CatladderImageRef | ProjectImageRef;
190
191
  /**
191
192
  * whether failures are allowed
192
193
  */
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/jobs.ts"],"names":[],"mappings":";;;AAGA,8DAA2D;AAsB9C,QAAA,WAAW,GAAG;IACzB,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,MAAM;CACE,CAAC;AAWE,QAAA,YAAY,GAAG;IAC1B,OAAO;IACP,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,YAAY;CACJ,CAAC;AA6NX;;;;;;;GAOG;AACH,4JAA4J;AAC5J,MAAa,YAAY;IACvB,YAAY,IAAyB;QACnC,uDAAuD;QACvD,2DAA2D;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAA,iCAAe,EAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,IAAI,CACT,GAAkD;QAElD,OAAO,GAAG,YAAY,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC;CACF;AAZD,oCAYC"}
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../../../../../../packages/pipeline/src/types/jobs.ts"],"names":[],"mappings":";;;AAIA,8DAA2D;AAsB9C,QAAA,WAAW,GAAG;IACzB,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,MAAM;CACE,CAAC;AAWE,QAAA,YAAY,GAAG;IAC1B,OAAO;IACP,gBAAgB;IAChB,aAAa;IACb,aAAa;IACb,YAAY;CACJ,CAAC;AA6NX;;;;;;;GAOG;AACH,4JAA4J;AAC5J,MAAa,YAAY;IACvB,YAAY,IAAyB;QACnC,uDAAuD;QACvD,2DAA2D;QAC3D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAA,iCAAe,EAAC,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,IAAI,CACT,GAAkD;QAElD,OAAO,GAAG,YAAY,YAAY,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC;IACnE,CAAC;CACF;AAZD,oCAYC"}
@@ -14,7 +14,13 @@ export type ReleaseMethod = "semantic-release" | "changesets";
14
14
  export type ReleaseConfig = {
15
15
  /**
16
16
  * Whether to release automatically or manually on main branch.
17
- * Defaults to "manuel"
17
+ * - "manual" (default): the pipeline offers a `create release`
18
+ * button that can be clicked at any time — the release then runs
19
+ * automatically as soon as every other job of the pipeline
20
+ * succeeded (clicking after a green pipeline releases right away).
21
+ * A `force create release` button releases immediately, ignoring
22
+ * the pipeline state.
23
+ * - "auto": every main-branch pipeline releases at the end.
18
24
  */
19
25
  when?: "manual" | "auto";
20
26
  /**
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: catladder-builds
3
- description: Configuring how a component is built in a catladder project — the `build` config in catladder.ts (build types node / rails / meteor / custom, build & start commands, artifacts, caching, lint/test/audit jobs, the Docker image, and shared workspace builds). Use when adding or changing a component's build, choosing a build type, wiring a Dockerfile/nginx image, tuning the build/test/lint jobs, or setting up a monorepo workspace build. Triggers on "build config", "buildCommand", "build type", "Dockerfile", "docker image", "rails build", "monorepo build", "artifacts".
3
+ description: Configuring how a component is built in a catladder project — the `build` config in catladder.ts (build types node / rails / meteor / custom, build & start commands, artifacts, caching, lint/test/audit jobs, the Docker image, project-declared job images, and shared workspace builds). Use when adding or changing a component's build, choosing a build type, wiring a Dockerfile/nginx image, declaring a custom CI job image (`images` config), tuning the build/test/lint jobs, or setting up a monorepo workspace build. Triggers on "build config", "buildCommand", "build type", "Dockerfile", "docker image", "job image", "jobImage", "custom image", "project image", "rails build", "monorepo build", "artifacts".
4
4
  ---
5
5
 
6
6
  # Component builds with catladder
@@ -71,11 +71,58 @@ type: `build: { from: "web" }` (see workspace builds below).
71
71
  - `cache` — build caching (see the `catladder-pipelines` skill for the
72
72
  caching model).
73
73
  - `jobImage`, `jobTags`, `jobVars`, `runnerVariables` — the CI image,
74
- runner tags, build-only env vars, and extra runner variables.
74
+ runner tags, build-only env vars, and extra runner variables. A
75
+ `jobImage` is a concrete image url or `{ image: "<name>" }`
76
+ referencing a project image (see below).
75
77
  - `docker` — the image build strategy: a built-in
76
78
  (`{ type: "nginx" | "node" | "meteor" }`) or
77
79
  `{ type: "custom" }` (expects a `Dockerfile`).
78
80
 
81
+ ## Project images (custom CI job images)
82
+
83
+ When a job needs a toolchain catladder doesn't ship (Java, Playwright,
84
+ …), declare a Docker image at the top level under `images` and reference
85
+ it in any `jobImage` field (build, `test.jobImage`, custom/pages deploy,
86
+ verify):
87
+
88
+ ```ts
89
+ images: {
90
+ // (a) a directory in the repo (default context = the dir)
91
+ "java-build": {
92
+ dir: "docker/java-build", // contains the Dockerfile
93
+ buildArgs: { MAVEN_VERSION: "3.9.9" }, // optional, part of the content hash
94
+ hashExtraPaths: ["shared/settings.xml"], // optional extra hashed+watched files
95
+ },
96
+ // (b) inline (default context = repo root); materialized into
97
+ // .catladder-generated/images/project/<name>/Dockerfile
98
+ "db-tools": {
99
+ dockerfile: ["FROM alpine:3.21", "RUN apk add --no-cache postgresql17-client"],
100
+ },
101
+ },
102
+ components: {
103
+ api: {
104
+ build: { type: "custom", jobImage: { image: "java-build" }, docker: { type: "custom" } },
105
+ },
106
+ }
107
+ ```
108
+
109
+ `dir` and `dockerfile` are mutually exclusive. `context` overrides the
110
+ build context (relative to the repo root) — needed when the image
111
+ `COPY`s files from outside its `dir`.
112
+
113
+ Catladder generates a `🐳 image <name>` job (setup stage) that builds
114
+ the image content-hashed into the project registry
115
+ (`…/job-images/<name>:<hash>`) and skips when it already exists — works
116
+ on GitLab and GitHub.
117
+
118
+ **The build context is not hashed** (it can be the whole repo) — only
119
+ the Dockerfile / `dir`, `buildArgs` and `hashExtraPaths` are. Files
120
+ pulled in via `COPY` that should trigger a rebuild belong in
121
+ `hashExtraPaths`.
122
+
123
+ Generation (`yarn catenv`) fails fast on an undeclared image name, a
124
+ missing `dir`, or a `dir` without a `Dockerfile`.
125
+
79
126
  ## Workspace builds (monorepos)
80
127
 
81
128
  For a shared build across several components, declare it once at the top
@@ -19,7 +19,7 @@ generated pipeline files.
19
19
  | `jobVars` | `EnvVars` | env vars only in build jobs |
20
20
  | `runnerVariables` | `Record<string,string>` | extra runner vars (also for `services:`) |
21
21
  | `jobTags` | `string[]` | runner tags |
22
- | `jobImage` | `GitlabJobImage` | custom CI image for the build |
22
+ | `jobImage` | `JobImageConfig` | CI image for the build: a concrete image or `{ image: "<name>" }` referencing a project image |
23
23
  | `docker` | see below | the deployable image strategy |
24
24
 
25
25
  `TestJobCustom` (for `lint`/`test`/`audit`): `command`, `jobImage`,
@@ -48,7 +48,7 @@ generated pipeline files.
48
48
 
49
49
  ### `custom`
50
50
  - `type: "custom"` — **required**.
51
- - `jobImage: GitlabJobImage` — **required** CI image.
51
+ - `jobImage: JobImageConfig` — **required** CI image (concrete image or `{ image: "<name>" }` project-image ref).
52
52
  - `docker: BuildConfigDocker` — **required** image build config.
53
53
  - `jobServices?: Services` — services for lint/test/audit/build jobs.
54
54
  - `lint?` / `test?` / `audit?: TestJobCustom` — disabled unless set.
@@ -29,13 +29,23 @@ plus stop jobs for review-app teardown.
29
29
 
30
30
  ## Job images and catci
31
31
 
32
- Jobs run in catladder-provided images. Their definitions are
33
- materialized into `.catladder-generated/images/` and built in the
34
- project's own registry (content-hashed, rebuilt only on change).
32
+ Jobs run in catladder-provided images (`🐳 catladder image <name>` build
33
+ jobs). Their definitions are materialized into
34
+ `.catladder-generated/images/` and built in the project's own registry
35
+ under `catladder/` (content-hashed, rebuilt only on change).
35
36
  `.catladder-generated/catci/` holds a small bundled CI companion used by
36
37
  generated jobs (e.g. the release security audit) — all generated, never
37
38
  edit.
38
39
 
40
+ Projects can declare their own job images under `images` in
41
+ `catladder.ts` (`🐳 image <name>` build jobs, pushed to `job-images/` in
42
+ the registry) and reference them in any `jobImage` field via
43
+ `{ image: "<name>" }` — see the `catladder-builds` skill. A declared
44
+ Dockerfile directory is used in place; an inline `dockerfile` is
45
+ materialized into `.catladder-generated/images/project/<name>/`. Either
46
+ way the build job is skipped when the content hash already exists in
47
+ the registry.
48
+
39
49
  ## Caching
40
50
 
41
51
  Cache configuration is generated per build type; node builds cache
@@ -23,12 +23,23 @@ are generated, never hand-edited.
23
23
  ## `when` — who triggers the release
24
24
 
25
25
  - **`manual`** (default) — the `create release` job on the main branch
26
- is manual; someone runs it to cut a release.
26
+ can be clicked **at any time**, even while the pipeline is still
27
+ running: it queues the release, which then runs automatically as soon
28
+ as every other job of the pipeline succeeded (and is skipped if the
29
+ pipeline fails). Clicking after a green pipeline releases right away.
30
+ - On GitLab the button is a quick no-op job; the actual release runs
31
+ in the automatic `🚀 release once pipeline succeeds` job (skipped
32
+ when the button was never clicked — never run it by hand).
33
+ - On GitHub the `create-release` dispatch task releases immediately
34
+ when the main workflow for HEAD is green, queues the release when
35
+ it is still running (the `catladder release on green` workflow then
36
+ picks it up on completion), and fails when the run concluded red.
27
37
  - **`auto`** — the release job runs automatically on every main-branch
28
38
  pipeline (it still no-ops when there is nothing to release).
29
39
 
30
40
  There is always also a manual **`⚠️ force create release`** job as an
31
- escape hatch. With `method: "changesets"` it has an extra meaning: it
41
+ escape hatch: it releases **immediately**, ignoring the state of the
42
+ pipeline. With `method: "changesets"` it has an extra meaning: it
32
43
  releases **even when no changesets are pending** (patch bump with a
33
44
  generic changelog entry) — the recovery path when a change was merged
34
45
  without a changeset and must ship now.