@intentius/chant 0.124.33 → 0.124.35

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 (218) hide show
  1. package/dist/cli/handlers/graph.js +2 -2
  2. package/dist/cli/handlers/pr.d.ts.map +1 -1
  3. package/dist/cli/handlers/pr.js +147 -51
  4. package/dist/cli/handlers/promote.d.ts.map +1 -1
  5. package/dist/cli/handlers/promote.js +284 -81
  6. package/dist/cli/handlers/release.d.ts +12 -0
  7. package/dist/cli/handlers/release.d.ts.map +1 -1
  8. package/dist/cli/handlers/release.js +125 -10
  9. package/dist/cli/handlers/run.d.ts +3 -1
  10. package/dist/cli/handlers/run.d.ts.map +1 -1
  11. package/dist/cli/handlers/run.js +12 -2
  12. package/dist/cli/main.d.ts.map +1 -1
  13. package/dist/cli/main.js +37 -2
  14. package/dist/cli/parse-args.d.ts.map +1 -1
  15. package/dist/cli/parse-args.js +24 -0
  16. package/dist/cli/registry.d.ts +17 -1
  17. package/dist/cli/registry.d.ts.map +1 -1
  18. package/dist/components/auto-release.d.ts +8 -1
  19. package/dist/components/auto-release.d.ts.map +1 -1
  20. package/dist/components/auto-release.js +3 -2
  21. package/dist/components/green-cover.d.ts +77 -0
  22. package/dist/components/green-cover.d.ts.map +1 -0
  23. package/dist/components/green-cover.js +153 -0
  24. package/dist/components/pr-pipeline.d.ts +34 -0
  25. package/dist/components/pr-pipeline.d.ts.map +1 -1
  26. package/dist/components/pr-pipeline.js +39 -5
  27. package/dist/components/promote-rounds.d.ts +102 -0
  28. package/dist/components/promote-rounds.d.ts.map +1 -0
  29. package/dist/components/promote-rounds.js +174 -0
  30. package/dist/components/promote.d.ts +4 -1
  31. package/dist/components/promote.d.ts.map +1 -1
  32. package/dist/components/promote.js +6 -3
  33. package/dist/components/release-gate.d.ts +30 -0
  34. package/dist/components/release-gate.d.ts.map +1 -1
  35. package/dist/components/release-gate.js +92 -42
  36. package/dist/components/release-promote.d.ts +9 -0
  37. package/dist/components/release-promote.d.ts.map +1 -1
  38. package/dist/components/release-promote.js +15 -0
  39. package/dist/config.d.ts +2 -0
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/deep-observation.d.ts +11 -0
  42. package/dist/deep-observation.d.ts.map +1 -1
  43. package/dist/graph-declared.d.ts +9 -1
  44. package/dist/graph-declared.d.ts.map +1 -1
  45. package/dist/graph-declared.js +18 -3
  46. package/dist/graph-detail.d.ts.map +1 -1
  47. package/dist/graph-detail.js +30 -1
  48. package/dist/graph-ir.d.ts.map +1 -1
  49. package/dist/graph-ir.js +13 -2
  50. package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
  51. package/dist/lifecycle/__fixtures__/publish-fakes.js +5 -1
  52. package/dist/lifecycle/compose-refs.d.ts +52 -0
  53. package/dist/lifecycle/compose-refs.d.ts.map +1 -0
  54. package/dist/lifecycle/compose-refs.js +115 -0
  55. package/dist/lifecycle/deep-observe.d.ts.map +1 -1
  56. package/dist/lifecycle/deep-observe.js +3 -2
  57. package/dist/lifecycle/green-apply.d.ts +39 -0
  58. package/dist/lifecycle/green-apply.d.ts.map +1 -0
  59. package/dist/lifecycle/green-apply.js +51 -0
  60. package/dist/lifecycle/publish-declaration.d.ts +4 -0
  61. package/dist/lifecycle/publish-declaration.d.ts.map +1 -1
  62. package/dist/lifecycle/publish-declaration.js +15 -0
  63. package/dist/lifecycle/publish-npm.d.ts +7 -4
  64. package/dist/lifecycle/publish-npm.d.ts.map +1 -1
  65. package/dist/lifecycle/publish-npm.js +60 -13
  66. package/dist/lifecycle/release-compose.d.ts +91 -0
  67. package/dist/lifecycle/release-compose.d.ts.map +1 -0
  68. package/dist/lifecycle/release-compose.js +235 -0
  69. package/dist/lifecycle/release-cut.d.ts +8 -0
  70. package/dist/lifecycle/release-cut.d.ts.map +1 -1
  71. package/dist/lifecycle/release-cut.js +2 -0
  72. package/dist/lifecycle/release-publish.d.ts +2 -0
  73. package/dist/lifecycle/release-publish.d.ts.map +1 -1
  74. package/dist/lifecycle/release-publish.js +2 -1
  75. package/dist/lifecycle/release-store.d.ts +15 -0
  76. package/dist/lifecycle/release-store.d.ts.map +1 -1
  77. package/dist/lifecycle/release-store.js +5 -1
  78. package/dist/wave-runtime.mjs +226 -224
  79. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  80. package/dist/workspace/__fixtures__/contract-repo.js +13 -2
  81. package/dist/workspace/check.schema.json +20 -2
  82. package/dist/workspace/checks/ci-workflow.d.ts +17 -0
  83. package/dist/workspace/checks/ci-workflow.d.ts.map +1 -0
  84. package/dist/workspace/checks/ci-workflow.js +130 -0
  85. package/dist/workspace/checks/security.d.ts +16 -1
  86. package/dist/workspace/checks/security.d.ts.map +1 -1
  87. package/dist/workspace/checks/security.js +4 -4
  88. package/dist/workspace/checks.d.ts +1 -1
  89. package/dist/workspace/checks.d.ts.map +1 -1
  90. package/dist/workspace/checks.js +4 -1
  91. package/dist/workspace/ci-green-cli.d.ts.map +1 -1
  92. package/dist/workspace/ci-green-cli.js +5 -3
  93. package/dist/workspace/ci-green-workflow.d.ts +18 -2
  94. package/dist/workspace/ci-green-workflow.d.ts.map +1 -1
  95. package/dist/workspace/ci-green-workflow.js +27 -5
  96. package/dist/workspace/ci-green.d.ts +31 -0
  97. package/dist/workspace/ci-green.d.ts.map +1 -1
  98. package/dist/workspace/ci-green.js +78 -4
  99. package/dist/workspace/ci-init.d.ts +100 -0
  100. package/dist/workspace/ci-init.d.ts.map +1 -0
  101. package/dist/workspace/ci-init.js +434 -0
  102. package/dist/workspace/ci-run.d.ts +6 -0
  103. package/dist/workspace/ci-run.d.ts.map +1 -1
  104. package/dist/workspace/ci-run.js +2 -1
  105. package/dist/workspace/ci-serve.d.ts +94 -13
  106. package/dist/workspace/ci-serve.d.ts.map +1 -1
  107. package/dist/workspace/ci-serve.js +248 -30
  108. package/dist/workspace/ci-workflow.d.ts +91 -0
  109. package/dist/workspace/ci-workflow.d.ts.map +1 -0
  110. package/dist/workspace/ci-workflow.js +33 -0
  111. package/dist/workspace/declaration.d.ts +18 -0
  112. package/dist/workspace/declaration.d.ts.map +1 -1
  113. package/dist/workspace/declaration.js +9 -2
  114. package/dist/workspace/declaration.schema.json +28 -0
  115. package/dist/workspace/delivery-metrics.d.ts +3 -1
  116. package/dist/workspace/delivery-metrics.d.ts.map +1 -1
  117. package/dist/workspace/delivery-metrics.js +12 -3
  118. package/dist/workspace/init.js +2 -2
  119. package/dist/workspace/member-commands.d.ts.map +1 -1
  120. package/dist/workspace/member-commands.js +4 -0
  121. package/dist/workspace/nested-graph.d.ts.map +1 -1
  122. package/dist/workspace/nested-graph.js +1 -0
  123. package/dist/workspace/reason-codes.d.ts +9 -0
  124. package/dist/workspace/reason-codes.d.ts.map +1 -1
  125. package/dist/workspace/reason-codes.js +10 -0
  126. package/dist/workspace/release-candidates.d.ts +28 -0
  127. package/dist/workspace/release-candidates.d.ts.map +1 -1
  128. package/dist/workspace/release-candidates.js +38 -2
  129. package/dist/workspace/release-candidates.schema.json +51 -0
  130. package/dist/workspace/release-workflow.d.ts +31 -0
  131. package/dist/workspace/release-workflow.d.ts.map +1 -0
  132. package/dist/workspace/release-workflow.js +150 -0
  133. package/dist/workspace/releases.schema.json +30 -0
  134. package/package.json +1 -1
  135. package/src/cli/handlers/graph.ts +2 -2
  136. package/src/cli/handlers/pr-green.test.ts +230 -0
  137. package/src/cli/handlers/pr.ts +148 -66
  138. package/src/cli/handlers/promote.test.ts +34 -0
  139. package/src/cli/handlers/promote.ts +302 -91
  140. package/src/cli/handlers/release-compose.e2e.test.ts +133 -0
  141. package/src/cli/handlers/release.ts +112 -10
  142. package/src/cli/handlers/run.ts +12 -1
  143. package/src/cli/main.ts +37 -2
  144. package/src/cli/parse-args.ts +18 -0
  145. package/src/cli/registry.ts +17 -1
  146. package/src/codegen/release-wiring.test.ts +56 -9
  147. package/src/components/auto-release.test.ts +22 -0
  148. package/src/components/auto-release.ts +9 -2
  149. package/src/components/green-cover.test.ts +170 -0
  150. package/src/components/green-cover.ts +186 -0
  151. package/src/components/pr-pipeline.test.ts +14 -4
  152. package/src/components/pr-pipeline.ts +56 -5
  153. package/src/components/promote-rounds.test.ts +220 -0
  154. package/src/components/promote-rounds.ts +232 -0
  155. package/src/components/promote.test.ts +7 -0
  156. package/src/components/promote.ts +9 -4
  157. package/src/components/release-gate.test.ts +47 -0
  158. package/src/components/release-gate.ts +111 -46
  159. package/src/components/release-promote.test.ts +24 -1
  160. package/src/components/release-promote.ts +15 -0
  161. package/src/deep-observation.ts +8 -0
  162. package/src/graph-declared-exports.test.ts +40 -0
  163. package/src/graph-declared.test.ts +18 -0
  164. package/src/graph-declared.ts +17 -2
  165. package/src/graph-detail.test.ts +68 -1
  166. package/src/graph-detail.ts +29 -1
  167. package/src/graph-ir.ts +12 -4
  168. package/src/lifecycle/__fixtures__/publish-fakes.ts +5 -1
  169. package/src/lifecycle/compose-refs.ts +125 -0
  170. package/src/lifecycle/deep-observe.test.ts +20 -0
  171. package/src/lifecycle/deep-observe.ts +4 -2
  172. package/src/lifecycle/green-apply.ts +71 -0
  173. package/src/lifecycle/publish-declaration.ts +15 -0
  174. package/src/lifecycle/publish-npm.ts +55 -13
  175. package/src/lifecycle/publish-targets.test.ts +45 -0
  176. package/src/lifecycle/release-compose.test.ts +125 -0
  177. package/src/lifecycle/release-compose.ts +312 -0
  178. package/src/lifecycle/release-cut.ts +6 -0
  179. package/src/lifecycle/release-publish.ts +4 -1
  180. package/src/lifecycle/release-store.ts +16 -1
  181. package/src/workspace/__fixtures__/contract-repo.ts +11 -2
  182. package/src/workspace/check-contract.test.ts +3 -2
  183. package/src/workspace/check.schema.json +20 -2
  184. package/src/workspace/checks/ci-workflow.test.ts +160 -0
  185. package/src/workspace/checks/ci-workflow.ts +135 -0
  186. package/src/workspace/checks/security.ts +4 -4
  187. package/src/workspace/checks.ts +4 -1
  188. package/src/workspace/ci-green-cli.ts +5 -3
  189. package/src/workspace/ci-green-workflow.test.ts +52 -0
  190. package/src/workspace/ci-green-workflow.ts +34 -5
  191. package/src/workspace/ci-green.test.ts +33 -0
  192. package/src/workspace/ci-green.ts +85 -4
  193. package/src/workspace/ci-init.test.ts +159 -0
  194. package/src/workspace/ci-init.ts +445 -0
  195. package/src/workspace/ci-report-url.test.ts +6 -1
  196. package/src/workspace/ci-run.test.ts +18 -13
  197. package/src/workspace/ci-run.ts +8 -1
  198. package/src/workspace/ci-serve-land.e2e.test.ts +138 -0
  199. package/src/workspace/ci-serve-land.test.ts +176 -0
  200. package/src/workspace/ci-serve.test.ts +77 -43
  201. package/src/workspace/ci-serve.ts +268 -34
  202. package/src/workspace/ci-workflow.ts +71 -0
  203. package/src/workspace/declaration.schema.json +28 -0
  204. package/src/workspace/declaration.ts +32 -3
  205. package/src/workspace/delivery-metrics.ts +12 -3
  206. package/src/workspace/graph-contract.test.ts +3 -2
  207. package/src/workspace/init.ts +2 -2
  208. package/src/workspace/member-commands.test.ts +11 -4
  209. package/src/workspace/member-commands.ts +3 -0
  210. package/src/workspace/nested-graph.test.ts +4 -0
  211. package/src/workspace/nested-graph.ts +1 -0
  212. package/src/workspace/reason-codes.test.ts +2 -0
  213. package/src/workspace/reason-codes.ts +10 -0
  214. package/src/workspace/release-candidates.schema.json +51 -0
  215. package/src/workspace/release-candidates.test.ts +30 -3
  216. package/src/workspace/release-candidates.ts +54 -2
  217. package/src/workspace/release-workflow.ts +167 -0
  218. package/src/workspace/releases.schema.json +30 -0
@@ -0,0 +1,434 @@
1
+ /**
2
+ * `chant ci init --workflow <name> [--forge <forge>] [--security <group>]...
3
+ * [--yes]` (#4168 step 6, section 9): set a workspace up for a prescribed
4
+ * delivery workflow (../ci-workflow.ts).
5
+ *
6
+ * It proposes, prints the proposal as a diff, and writes only on `--yes` or a
7
+ * yes at the prompt. What it proposes comes from what `workspace check`'s
8
+ * WSP151 reports for the workspace as it would be with `ci.workflow` set, so
9
+ * a second run proposes only what is still missing, and nothing once the
10
+ * workspace has it all.
11
+ *
12
+ * - The declaration gains `ci.workflow`, a `ci.green` block when it has none
13
+ * (one phase per GitHub workflow, its jobs as the check runs, and the
14
+ * workflows a pull request runs as `preMerge`), and `preMerge` when the
15
+ * block has none. `--security` adds groups to the top-level `security`;
16
+ * without it no group is turned on, and the groups are listed.
17
+ * - A member that builds with chant and declares no component gets a
18
+ * `<member>.component.ts` stub with a gate and a TODO line, which WSP151
19
+ * keeps reporting until someone fills the stub in. A `chant.config.ts`
20
+ * that declares no environments gains `environments: ["staging", "prod"]`
21
+ * when its default export is a plain object literal.
22
+ * - The generated files are written by the generators that own them, run
23
+ * after the edits: `chant build --components --generate <forge> --pr-loop`
24
+ * in each member, `chant ci workflow` for the tick, and `chant release
25
+ * workflow` for the publish job. Each is named in the proposal before it
26
+ * runs.
27
+ *
28
+ * It never edits a file the diff did not show, and never overwrites a file
29
+ * it proposed to create that appeared in the meantime.
30
+ */
31
+ import { spawnSync } from "node:child_process";
32
+ import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
33
+ import { basename, join } from "node:path";
34
+ import { formatError, formatSuccess } from "../cli/format.js";
35
+ import { parseYAMLDocument } from "../yaml.js";
36
+ import { CI_WORKFLOW_CHECKS } from "./checks/ci-workflow.js";
37
+ import { CI_WORKFLOWS, STUB_MARKER, appliesOnMerge } from "./ci-workflow.js";
38
+ export { STUB_MARKER };
39
+ import { CI_GREEN_WORKFLOW_FILE, jobCheckRuns, readWorkflowSources, workflowsHolding } from "./ci-green-workflow.js";
40
+ import { findWorkspaceRoot } from "../project-root.js";
41
+ import { parseDeclaration, readDeclaration, WorkspaceReadError } from "./declaration.js";
42
+ import { staticPromotionOrder } from "./promotion-order.js";
43
+ import { SECURITY_GROUPS } from "./security.js";
44
+ import { gitTop, workingTree } from "./tree.js";
45
+ import { RELEASE_WORKFLOW_FORGES } from "./release-workflow.js";
46
+ const USAGE = "chant ci init --workflow trunk-curated|trunk-curated+apply-on-merge [--forge github|gitlab|forgejo] [--security <group>]... [--yes]";
47
+ /** The environments a config with none is given. */
48
+ export const DEFAULT_ENVIRONMENTS = ["staging", "prod"];
49
+ const memberDir = (dir) => (dir === "." ? "" : dir);
50
+ const join2 = (dir, file) => (dir === "" ? file : `${dir}/${file}`);
51
+ const isObject = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
52
+ /** The forge whose pipeline files the repository has, or null. */
53
+ export function inferForge(repoRoot) {
54
+ if (existsSync(join(repoRoot, ".github", "workflows")))
55
+ return "github";
56
+ if (existsSync(join(repoRoot, ".forgejo", "workflows")))
57
+ return "forgejo";
58
+ if (existsSync(join(repoRoot, ".gitlab-ci.yml")))
59
+ return "gitlab";
60
+ return null;
61
+ }
62
+ /** The branch `origin/HEAD` names, else `main`. */
63
+ export function inferTrunk(repoRoot) {
64
+ const r = spawnSync("git", ["symbolic-ref", "--short", "refs/remotes/origin/HEAD"], { cwd: repoRoot, encoding: "utf-8" });
65
+ const ref = r.status === 0 ? r.stdout.trim() : "";
66
+ return ref.startsWith("origin/") ? ref.slice("origin/".length) : "main";
67
+ }
68
+ /** Whether a workflow document runs on a pull request. */
69
+ function onPullRequest(doc) {
70
+ if (!isObject(doc))
71
+ return false;
72
+ const on = doc.on ?? doc["true"];
73
+ if (typeof on === "string")
74
+ return on === "pull_request" || on === "pull_request_target";
75
+ if (Array.isArray(on))
76
+ return on.includes("pull_request") || on.includes("pull_request_target");
77
+ return isObject(on) && ("pull_request" in on || "pull_request_target" in on);
78
+ }
79
+ /**
80
+ * A `ci.green` block from the repository's GitHub workflows: a phase per
81
+ * workflow holding its jobs' check runs, all required, and those a pull
82
+ * request runs as `preMerge`. chant's own generated workflows are left out.
83
+ */
84
+ export function inferGreen(repoRoot) {
85
+ const phases = {};
86
+ const preMerge = [];
87
+ for (const s of readWorkflowSources(repoRoot, "")) {
88
+ if (/\/chant-[^/]*\.ya?ml$/.test(s.path))
89
+ continue;
90
+ let doc;
91
+ try {
92
+ doc = parseYAMLDocument(s.text);
93
+ }
94
+ catch {
95
+ continue;
96
+ }
97
+ const runs = jobCheckRuns(doc);
98
+ if (runs.length === 0)
99
+ continue;
100
+ const name = basename(s.path).replace(/\.ya?ml$/, "").replace(/[^A-Za-z0-9_.-]/g, "-").slice(0, 64) || "check";
101
+ phases[name] = runs;
102
+ if (onPullRequest(doc))
103
+ preMerge.push(name);
104
+ }
105
+ if (Object.keys(phases).length === 0) {
106
+ phases.check = ["check"];
107
+ preMerge.push("check");
108
+ }
109
+ return { branch: inferTrunk(repoRoot), phases, require: Object.keys(phases), preMerge: preMerge.length > 0 ? preMerge : [Object.keys(phases)[0]] };
110
+ }
111
+ /**
112
+ * The declaration's text with `next`'s top-level keys. A key the file lacks
113
+ * is added as text before the closing brace, so the rest keeps its layout; a
114
+ * key it has whose value changes rewrites the file, two-space indented.
115
+ */
116
+ export function editDeclarationText(text, raw, next) {
117
+ const whole = `${JSON.stringify(next, null, 2)}\n`;
118
+ const changed = Object.keys(next).filter((k) => JSON.stringify(raw[k]) !== JSON.stringify(next[k]));
119
+ if (changed.length === 0)
120
+ return text;
121
+ if (changed.some((k) => k in raw))
122
+ return whole;
123
+ const close = text.lastIndexOf("}");
124
+ if (close < 0)
125
+ return whole;
126
+ const head = text.slice(0, close).replace(/\s*$/, "");
127
+ const added = changed.map((k) => ` ${JSON.stringify(k)}: ${JSON.stringify(next[k], null, 2).replace(/\n/g, "\n ")}`).join(",\n");
128
+ const out = `${head}${head.endsWith("{") ? "" : ","}\n${added}\n${text.slice(close)}`;
129
+ try {
130
+ return JSON.stringify(JSON.parse(out)) === JSON.stringify(next) ? out : whole;
131
+ }
132
+ catch {
133
+ return whole;
134
+ }
135
+ }
136
+ /** An identifier for a member's stub export. */
137
+ function exportName(member) {
138
+ const parts = member.split(/[^A-Za-z0-9]+/).filter(Boolean);
139
+ const id = parts.map((p, i) => (i === 0 ? p.toLowerCase() : p[0].toUpperCase() + p.slice(1))).join("");
140
+ return /^[A-Za-z_]/.test(id) ? id : `component${id}`;
141
+ }
142
+ /** The component stub for a member that declares none: a gate and a TODO, so WSP151 keeps asking until it is filled in. */
143
+ export function componentStub(member, lastEnvironment) {
144
+ return [
145
+ `// ${STUB_MARKER}: say how ${member} is built and deployed, then delete this line.`,
146
+ "// The gate makes a promote wait on an approval; a release gate decides it",
147
+ `// for each environment, ${lastEnvironment} among them.`,
148
+ "// chant-disable COMP004 -- the release gate: the person promoting approves each environment with chant approve",
149
+ 'import { gate, phase, type Component } from "@intentius/chant/components/component";',
150
+ "",
151
+ `export const ${exportName(member)}: Component = {`,
152
+ ` name: ${JSON.stringify(member)},`,
153
+ " deploy: [",
154
+ ` phase("Release", [gate("release", { description: "Approve the release for ${lastEnvironment}." })]),`,
155
+ " ],",
156
+ "};",
157
+ "",
158
+ ].join("\n");
159
+ }
160
+ /** The config with `environments` added after `export default {`, or null when its default export is not a plain object literal. */
161
+ export function withEnvironments(config, environments = DEFAULT_ENVIRONMENTS) {
162
+ const m = /export\s+default\s*\{/.exec(config);
163
+ if (!m)
164
+ return null;
165
+ const at = m.index + m[0].length;
166
+ return `${config.slice(0, at)}\n environments: ${JSON.stringify(environments).replace(/,/g, ", ")},${config.slice(at)}`;
167
+ }
168
+ function read(tree, path) {
169
+ if (tree.stat(path) !== "file")
170
+ return null;
171
+ try {
172
+ return tree.read(path);
173
+ }
174
+ catch {
175
+ return null;
176
+ }
177
+ }
178
+ /** Run WSP151 over `declaration` and the tree as it is. */
179
+ function check(declaration, tree) {
180
+ return CI_WORKFLOW_CHECKS.flatMap((c) => c.check({ declaration, tree, groups: [], kinds: new Map(), kindProblems: [] }));
181
+ }
182
+ /**
183
+ * What `chant ci init` would write for the workspace at `root`, and the
184
+ * generators it would run. Reads only; {@link applyCiInit} writes.
185
+ */
186
+ export function proposeCiInit(root, options) {
187
+ const tree = workingTree(root);
188
+ const current = readDeclaration(tree);
189
+ if (current.file.endsWith(".jsonc")) {
190
+ throw new WorkspaceReadError("declaration-invalid", `${current.file} is JSONC, which chant ci init does not rewrite, since its comments would be lost; add ci.workflow by hand, then rerun chant ci init for the rest`);
191
+ }
192
+ const repoRoot = gitTop(root) ?? root;
193
+ const text = readFileSync(join(root, current.file), "utf-8");
194
+ const raw = JSON.parse(text);
195
+ const ci = isObject(raw.ci) ? { ...raw.ci } : {};
196
+ ci.workflow = options.workflow;
197
+ if (!isObject(ci.green))
198
+ ci.green = inferGreen(repoRoot);
199
+ else if (!Array.isArray(ci.green.preMerge) || ci.green.preMerge.length === 0) {
200
+ const inferred = inferGreen(repoRoot).preMerge;
201
+ const declared = Object.keys(ci.green.phases ?? {});
202
+ const pick = inferred.filter((p) => declared.includes(p));
203
+ ci.green = { ...ci.green, preMerge: pick.length > 0 ? pick : declared.slice(0, 1) };
204
+ }
205
+ const next = { ...raw, ci };
206
+ const security = [...new Set([...(raw.security ?? []), ...(options.security ?? [])])];
207
+ if (security.length > 0)
208
+ next.security = security;
209
+ const after = editDeclarationText(text, raw, next);
210
+ const proposed = parseDeclaration(after, current.file);
211
+ const files = [];
212
+ if (after !== text)
213
+ files.push({ path: current.file, before: text, after });
214
+ const notes = [];
215
+ const findings = check(proposed, tree);
216
+ const reported = (code, entity) => findings.some((f) => f.code === code && (entity === undefined || f.entity === entity));
217
+ const forge = options.forge ?? inferForge(repoRoot);
218
+ const releasing = proposed.members.filter((m) => (m.ciWorkflow ?? proposed.ci?.workflow) && (m.ciWorkflow !== null || tree.stat(join2(memberDir(m.dir), "chant.config.ts")) === "file"));
219
+ const firstEnv = new Map();
220
+ for (const m of releasing) {
221
+ const dir = memberDir(m.dir);
222
+ const configPath = join2(dir, "chant.config.ts");
223
+ const config = read(tree, configPath);
224
+ let order = config === null ? [] : (staticPromotionOrder(config) ?? null);
225
+ if (reported("ci-workflow-no-environments", m.name) && config !== null) {
226
+ const edited = withEnvironments(config);
227
+ if (edited) {
228
+ files.push({ path: configPath, before: config, after: edited });
229
+ order = DEFAULT_ENVIRONMENTS.map((name) => ({ name, canary: false }));
230
+ notes.push(`${configPath}: ${DEFAULT_ENVIRONMENTS.join(", ")} is a guess at the promotion order; edit it if yours differs.`);
231
+ }
232
+ else {
233
+ notes.push(`${configPath}: add environments, the promotion order; its default export is not a plain object, so chant ci init leaves it alone.`);
234
+ }
235
+ }
236
+ const names = (order ?? []).map((s) => s.name);
237
+ if (names.length > 0)
238
+ firstEnv.set(m.name, names[0]);
239
+ if (reported("ci-workflow-no-components", m.name)) {
240
+ const stubPath = join2(dir, `${m.name}.component.ts`);
241
+ if (!tree.stat(stubPath))
242
+ files.push({ path: stubPath, before: null, after: componentStub(m.name, names[names.length - 1] ?? "the last environment") });
243
+ }
244
+ for (const f of findings.filter((f) => f.code === "ci-workflow-ungated-env" && f.entity === m.name)) {
245
+ notes.push(`${f.treeFile}: add a gate() step, so a promote to the last environment waits on an approval; chant ci init does not edit a component you wrote.`);
246
+ }
247
+ }
248
+ const commands = [];
249
+ if (forge === null && (reported("ci-workflow-pipeline-missing") || reported("ci-workflow-pipeline-differs") || reported("ci-workflow-publish-missing"))) {
250
+ notes.push("No .github/workflows, .forgejo/workflows or .gitlab-ci.yml was found, so no pipeline is generated; rerun with --forge github|gitlab|forgejo.");
251
+ }
252
+ else if (forge !== null) {
253
+ if (reported("ci-workflow-pipeline-missing") || reported("ci-workflow-pipeline-differs")) {
254
+ for (const m of releasing) {
255
+ const env = firstEnv.get(m.name);
256
+ commands.push({
257
+ cwd: memberDir(m.dir) || ".",
258
+ // The root member builds alone: at a workspace root, chant build refuses without --root-only (WSP000).
259
+ args: ["build", "--components", "--generate", forge, "--pr-loop", ...(m.dir === "." ? ["--root-only"] : []), ...(env ? ["--env", env] : []), ...(appliesOnMerge(m.ciWorkflow ?? proposed.ci.workflow) ? ["--apply-on-merge"] : [])],
260
+ why: `the pull-request pipeline for ${m.name}: plan on a pull request, ${appliesOnMerge(m.ciWorkflow ?? proposed.ci.workflow) ? "apply" : "record"} on merge`,
261
+ });
262
+ }
263
+ if (forge === "github") {
264
+ // ci workflow refuses when no workflow holds a required phase's check run, so say so instead of running it.
265
+ const green = proposed.ci?.green;
266
+ const holding = green ? workflowsHolding(green, readWorkflowSources(repoRoot, CI_GREEN_WORKFLOW_FILE)).workflows : [];
267
+ if (holding.length > 0)
268
+ commands.push({ cwd: ".", args: ["ci", "workflow"], why: "the tick that tags green commits" });
269
+ else
270
+ notes.push("No workflow in .github/workflows runs a job of a required ci.green phase on the branch yet, so the tick is not generated; add your CI, name its jobs in ci.green.phases, then rerun chant ci init.");
271
+ }
272
+ else
273
+ notes.push(`${forge} has no check runs for ci tick to read; set ci.green.source to runs and run chant ci tick from a scheduled job (see the green-commits guide).`);
274
+ }
275
+ if (reported("ci-workflow-publish-missing"))
276
+ commands.push({ cwd: ".", args: ["release", "workflow", "--forge", forge], why: "the publish job for release/** tags" });
277
+ }
278
+ return { files, commands, notes, findings };
279
+ }
280
+ /** A unified-style diff of two texts, for the proposal. Line-based, from their longest common subsequence. */
281
+ export function lineDiff(path, before, after) {
282
+ const a = before === null ? [] : before.replace(/\n$/, "").split("\n");
283
+ const b = after.replace(/\n$/, "").split("\n");
284
+ const n = a.length;
285
+ const m = b.length;
286
+ const lcs = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
287
+ for (let i = n - 1; i >= 0; i--)
288
+ for (let j = m - 1; j >= 0; j--)
289
+ lcs[i][j] = a[i] === b[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);
290
+ const out = [`--- ${before === null ? "/dev/null" : `a/${path}`}`, `+++ b/${path}`];
291
+ let i = 0;
292
+ let j = 0;
293
+ while (i < n || j < m) {
294
+ if (i < n && j < m && a[i] === b[j]) {
295
+ out.push(` ${a[i]}`);
296
+ i++;
297
+ j++;
298
+ }
299
+ else if (i < n && (j >= m || lcs[i + 1][j] >= lcs[i][j + 1]))
300
+ out.push(`- ${a[i++]}`);
301
+ else
302
+ out.push(`+ ${b[j++]}`);
303
+ }
304
+ // Keep three lines of context around each change.
305
+ const keep = new Set();
306
+ out.forEach((l, k) => {
307
+ if (k < 2 || l.startsWith("+ ") || l.startsWith("- "))
308
+ for (let d = -3; d <= 3; d++)
309
+ keep.add(k + d);
310
+ });
311
+ const shown = [];
312
+ let skipped = false;
313
+ out.forEach((l, k) => {
314
+ if (keep.has(k)) {
315
+ shown.push(l);
316
+ skipped = false;
317
+ }
318
+ else if (!skipped) {
319
+ shown.push(" ...");
320
+ skipped = true;
321
+ }
322
+ });
323
+ return shown.join("\n");
324
+ }
325
+ /** Write the proposal's files. A file it would create that now exists is refused, and nothing is written. */
326
+ export function applyCiInit(root, proposal) {
327
+ for (const f of proposal.files) {
328
+ if (f.before === null && existsSync(join(root, f.path)))
329
+ throw new Error(`${f.path} appeared after the proposal was made; nothing written`);
330
+ if (f.before !== null && readFileSync(join(root, f.path), "utf-8") !== f.before)
331
+ throw new Error(`${f.path} changed after the proposal was made; nothing written`);
332
+ }
333
+ for (const f of proposal.files)
334
+ writeFileSync(join(root, f.path), f.after, f.before === null ? { flag: "wx" } : {});
335
+ return proposal.files.map((f) => f.path);
336
+ }
337
+ async function confirm(question) {
338
+ const { createInterface } = await import("node:readline");
339
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
340
+ return new Promise((resolveAnswer) => {
341
+ rl.question(question, (answer) => {
342
+ resolveAnswer(/^y(es)?$/i.test(answer.trim()));
343
+ rl.close();
344
+ });
345
+ rl.on("close", () => resolveAnswer(false));
346
+ });
347
+ }
348
+ /** Run a chant command the way this process was run, so `npx chant` and a source checkout both work. */
349
+ function runChant(cwd, args) {
350
+ const r = spawnSync(process.execPath, [...process.execArgv, process.argv[1], ...args], { cwd, stdio: "inherit" });
351
+ return r.status ?? 1;
352
+ }
353
+ export async function runCiInit(ctx) {
354
+ const { args } = ctx;
355
+ const workflow = (args.ciWorkflows ?? [])[0];
356
+ if (!workflow || !CI_WORKFLOWS.includes(workflow) || (args.ciWorkflows ?? []).length > 1) {
357
+ console.error(formatError({ message: `--workflow names one of ${CI_WORKFLOWS.join(", ")}`, hint: USAGE }));
358
+ return 1;
359
+ }
360
+ if (args.forge !== undefined && !RELEASE_WORKFLOW_FORGES.includes(args.forge)) {
361
+ console.error(formatError({ message: `--forge ${JSON.stringify(args.forge)} is not one of ${RELEASE_WORKFLOW_FORGES.join(", ")}`, hint: USAGE }));
362
+ return 1;
363
+ }
364
+ const security = args.securityGroups ?? [];
365
+ const unknown = security.filter((g) => !SECURITY_GROUPS.includes(g));
366
+ if (unknown.length > 0) {
367
+ console.error(formatError({ message: `--security ${unknown.join(", ")} is not a group; the groups are ${SECURITY_GROUPS.join(", ")}`, hint: USAGE }));
368
+ return 1;
369
+ }
370
+ const found = findWorkspaceRoot(process.cwd());
371
+ if (!found) {
372
+ console.error(formatError({ message: "no chant.workspace.json between this directory and the git root", hint: "Run chant workspace init first, then chant ci init." }));
373
+ return 1;
374
+ }
375
+ const root = realpathSync(found.dir);
376
+ let proposal;
377
+ try {
378
+ proposal = proposeCiInit(root, { workflow: workflow, ...(args.forge ? { forge: args.forge } : {}), security: security });
379
+ }
380
+ catch (err) {
381
+ console.error(formatError({ message: `chant ci init: ${err instanceof WorkspaceReadError ? err.describe() : err.message}`, hint: USAGE }));
382
+ return 1;
383
+ }
384
+ if (proposal.files.length === 0 && proposal.commands.length === 0) {
385
+ for (const n of proposal.notes)
386
+ console.log(n);
387
+ console.log(formatSuccess(`The workspace has what ${workflow} needs; chant workspace check reports anything left.`));
388
+ return 0;
389
+ }
390
+ for (const f of proposal.files) {
391
+ console.log(lineDiff(f.path, f.before, f.after));
392
+ console.log("");
393
+ }
394
+ if (proposal.commands.length > 0) {
395
+ console.log("Then runs:");
396
+ for (const c of proposal.commands)
397
+ console.log(` (in ${c.cwd}) chant ${c.args.join(" ")} # ${c.why}`);
398
+ console.log("");
399
+ }
400
+ for (const n of proposal.notes)
401
+ console.log(`Note: ${n}`);
402
+ if (security.length === 0)
403
+ console.log(`No security group is turned on. Add one later with chant ci init --workflow ${workflow} --security <group>: ${SECURITY_GROUPS.join(", ")}.`);
404
+ console.log("");
405
+ let write = !!args.yes;
406
+ if (!write) {
407
+ if (!process.stdin.isTTY) {
408
+ console.log("Nothing written. Re-run with --yes to write it.");
409
+ return 0;
410
+ }
411
+ write = await confirm("Write these files and run the generators? [y/N] ");
412
+ }
413
+ if (!write) {
414
+ console.log("Nothing written.");
415
+ return 0;
416
+ }
417
+ try {
418
+ for (const path of applyCiInit(root, proposal))
419
+ console.log(`Wrote ${path}`);
420
+ }
421
+ catch (err) {
422
+ console.error(formatError({ message: `chant ci init: ${err.message}`, hint: "Rerun chant ci init to see a fresh proposal." }));
423
+ return 1;
424
+ }
425
+ for (const c of proposal.commands) {
426
+ const status = runChant(join(root, c.cwd), c.args);
427
+ if (status !== 0) {
428
+ console.error(formatError({ message: `chant ${c.args.join(" ")} failed in ${c.cwd}`, hint: "Fix what it reports and rerun chant ci init; it proposes only what is still missing." }));
429
+ return 1;
430
+ }
431
+ }
432
+ console.log(formatSuccess("Done. chant workspace check reports what the workflow still lacks, such as the component stubs to fill in."));
433
+ return 0;
434
+ }
@@ -235,6 +235,12 @@ export interface CiRunRequest {
235
235
  /** `--env`: the environment the pipeline is for. */
236
236
  env: string;
237
237
  forge: ForgeKind;
238
+ /**
239
+ * Run the job's command without `--forge` (#4016 gap 6): `ci serve --forge
240
+ * git` reads a plain git server, which has no API for the command to ask.
241
+ * `forge` then only shapes the job's variables.
242
+ */
243
+ noForge?: boolean;
238
244
  /** `--base`, `--pr` and `--commit` (default `HEAD`). */
239
245
  base?: string;
240
246
  pr?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ci-run.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ci-run.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-run.ts"],"names":[],"mappings":"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"}
@@ -479,7 +479,8 @@ export async function ciRun(req) {
479
479
  const isolated = !req.requireRunnerStart && !req.local && req.job === "apply" && securityGroupsAt(cwd).has("isolated-runners");
480
480
  const started = req.requireRunnerStart || isolated ? runnerStartFor(req, { top, commit, hostEnv }) : undefined;
481
481
  // A generated wave job's command, as prLoopWaveJobs writes it. #4161: a local job's command posts no status or note.
482
- const command = `${found.command}${req.wave !== undefined ? ` --wave ${req.wave}` : ""}${req.local ? " --no-status" : ""}`;
482
+ const forgeCommand = req.noForge ? found.command.replace(` --forge ${req.forge}`, "") : found.command;
483
+ const command = `${forgeCommand}${req.wave !== undefined ? ` --wave ${req.wave}` : ""}${req.local ? " --no-status" : ""}`;
483
484
  const job = { ...found, command, ...(req.wave !== undefined ? { wave: req.wave } : {}) };
484
485
  const own = ciJobEnv(job, {
485
486
  forge: req.forge,