@intentius/chant 0.124.44 → 0.124.45

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 (72) hide show
  1. package/dist/ci-identity.d.ts +183 -12
  2. package/dist/ci-identity.d.ts.map +1 -1
  3. package/dist/ci-identity.js +362 -53
  4. package/dist/cli/handlers/build.d.ts.map +1 -1
  5. package/dist/cli/handlers/build.js +17 -1
  6. package/dist/cli/handlers/pr-env.d.ts +8 -2
  7. package/dist/cli/handlers/pr-env.d.ts.map +1 -1
  8. package/dist/cli/handlers/pr-env.js +126 -225
  9. package/dist/cli/handlers/pr.d.ts +3 -0
  10. package/dist/cli/handlers/pr.d.ts.map +1 -1
  11. package/dist/cli/handlers/pr.js +1 -0
  12. package/dist/components/cli-support.d.ts +2 -0
  13. package/dist/components/cli-support.d.ts.map +1 -1
  14. package/dist/components/cli-support.js +4 -2
  15. package/dist/components/fan-out-support.d.ts +3 -0
  16. package/dist/components/fan-out-support.d.ts.map +1 -1
  17. package/dist/components/fan-out-support.js +1 -1
  18. package/dist/components/pr-env-run.d.ts +270 -0
  19. package/dist/components/pr-env-run.d.ts.map +1 -0
  20. package/dist/components/pr-env-run.js +440 -0
  21. package/dist/components/pr-environment.d.ts +89 -14
  22. package/dist/components/pr-environment.d.ts.map +1 -1
  23. package/dist/components/pr-environment.js +94 -8
  24. package/dist/components/pr-pipeline.d.ts +10 -1
  25. package/dist/components/pr-pipeline.d.ts.map +1 -1
  26. package/dist/op/op-waves.d.ts +17 -0
  27. package/dist/op/op-waves.d.ts.map +1 -1
  28. package/dist/op/op-waves.js +23 -1
  29. package/dist/pr-forge.d.ts +15 -1
  30. package/dist/pr-forge.d.ts.map +1 -1
  31. package/dist/pr-forge.js +28 -16
  32. package/dist/pr-requires.d.ts +5 -1
  33. package/dist/pr-requires.d.ts.map +1 -1
  34. package/dist/wave-runtime.mjs +179 -179
  35. package/dist/workspace/ci-cloud-identity.d.ts +3 -1
  36. package/dist/workspace/ci-cloud-identity.d.ts.map +1 -1
  37. package/dist/workspace/ci-cloud-identity.js +16 -1
  38. package/dist/workspace/ci-run.d.ts +35 -8
  39. package/dist/workspace/ci-run.d.ts.map +1 -1
  40. package/dist/workspace/ci-run.js +95 -21
  41. package/dist/workspace/ci-secrets.d.ts.map +1 -1
  42. package/dist/workspace/ci-secrets.js +4 -3
  43. package/dist/workspace/declaration.d.ts +10 -0
  44. package/dist/workspace/declaration.d.ts.map +1 -1
  45. package/dist/workspace/declaration.js +17 -1
  46. package/dist/workspace/declaration.schema.json +36 -1
  47. package/package.json +1 -1
  48. package/src/ci-identity-targets.test.ts +275 -0
  49. package/src/ci-identity.ts +394 -61
  50. package/src/cli/handlers/build.ts +15 -1
  51. package/src/cli/handlers/pr-env.ts +136 -227
  52. package/src/cli/handlers/pr.ts +4 -0
  53. package/src/components/cli-support.ts +6 -1
  54. package/src/components/fan-out-support.ts +4 -1
  55. package/src/components/pr-env-run.test.ts +290 -0
  56. package/src/components/pr-env-run.ts +634 -0
  57. package/src/components/pr-environment.ts +159 -12
  58. package/src/components/pr-pipeline.ts +10 -1
  59. package/src/op/op-waves.ts +38 -1
  60. package/src/pr-forge-bundle.test.ts +1 -1
  61. package/src/pr-forge.ts +44 -17
  62. package/src/pr-requires.test.ts +43 -6
  63. package/src/pr-requires.ts +5 -1
  64. package/src/workspace/ci-cloud-identity.test.ts +20 -0
  65. package/src/workspace/ci-cloud-identity.ts +14 -1
  66. package/src/workspace/ci-run.test.ts +74 -1
  67. package/src/workspace/ci-run.ts +122 -29
  68. package/src/workspace/ci-secrets.test.ts +1 -1
  69. package/src/workspace/ci-secrets.ts +4 -3
  70. package/src/workspace/declaration.schema.json +36 -1
  71. package/src/workspace/declaration.test.ts +7 -0
  72. package/src/workspace/declaration.ts +24 -2
@@ -25,17 +25,23 @@
25
25
  * `down` reads the environment's record on chant/lifecycle, checks it names
26
26
  * this pull request's environment, and tears down what `planTeardown` finds
27
27
  * under the record's marker, after dropping any entry whose marker is not
28
- * exactly that one. No gate holds it: closing the pull request is the
29
- * decision, as is the TTL the base set for `sweep`.
28
+ * exactly that one. The lexicons tear down what they own, and the command
29
+ * `ci.prEnvironment.teardown` names tears down the rest (#4330). No gate
30
+ * holds it: closing the pull request is the decision, as is the TTL the base
31
+ * set for `sweep`.
32
+ *
33
+ * The runs themselves are ../../components/pr-env-run.ts, which a product
34
+ * calls with an adapter of its own (#4330). This file supplies the
35
+ * components adapter and the CLI's ports.
30
36
  */
31
37
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
32
38
  import { join, resolve } from "node:path";
33
39
  import { loadChantConfig } from "../../config.js";
34
40
  import { ENV_VAR } from "../../env.js";
35
41
  import { isEmptyChangeSet } from "../../change-set.js";
36
- import { PR_ENV_EXIT, PR_ENV_GATE, PR_ENV_LEDGER_DIR, PR_ENV_LEDGER_FILE, PR_ENV_RECORD_FILE, PR_ENV_REPORT_DIR, acceptHandedRecord, handedPrEnvReport, PR_ENV_TEMPLATE_VAR, derivePrEnvironment, expired, livePrEnvironments, parsePrEnvRecords, prEnvApproveCommand, prEnvNoteMarker, prEnvStatusContext, prEnvStatusDescription, prEnvStatusState, prEnvironmentName, renderPrEnvNote, teardownComplete, teardownCounts, tearDownPrEnvironment, ttlMs, } from "../../components/pr-environment.js";
37
- import { applyPrSet, approvalOf, decidePrGate, readOnlyLedger } from "../../components/pr-run.js";
38
- import { gitGateLedgerPort } from "../../op/gate.js";
42
+ import { PR_ENV_EXIT, PR_ENV_GATE, PR_ENV_RECORD_FILE, PR_ENV_REPORT_DIR, acceptHandedRecord, handedPrEnvReport, PR_ENV_TEMPLATE_VAR, derivePrEnvironment, prEnvApproveCommand, prEnvStatusState, prEnvironmentName, prEnvironmentSite, renderPrEnvNote, ttlMs, } from "../../components/pr-environment.js";
43
+ import { commandTeardownAdapter, forgePrEnvPublisher, lifecyclePrEnvPorts, prEnvDown as prEnvDownRun, prEnvOp, prEnvSweep as prEnvSweepRun, prEnvUp as prEnvUpRun, } from "../../components/pr-env-run.js";
44
+ import { applyPrSet } from "../../components/pr-run.js";
39
45
  import { prOp } from "../../pr-loop.js";
40
46
  import { FORGE_KINDS, forgeFromEnv, forgePrincipalOf } from "../../pr-forge.js";
41
47
  import { formatError, formatInfo, formatWarning } from "../format.js";
@@ -77,36 +83,29 @@ function actor() {
77
83
  function memberOf(ctx) {
78
84
  return ctx.args.members?.length === 1 ? ctx.args.members[0] : undefined;
79
85
  }
80
- // ── the ledger ─────────────────────────────────────────────────────────────
81
- async function readRecords() {
82
- const { fetchLifecycle, readBlobFromPath } = await import("../../lifecycle/git.js");
83
- await fetchLifecycle().catch(() => false);
84
- return parsePrEnvRecords(await readBlobFromPath(PR_ENV_LEDGER_DIR, PR_ENV_LEDGER_FILE));
85
- }
86
+ // ── the ports ──────────────────────────────────────────────────────────────
87
+ const log = (line) => console.error(formatInfo(line));
88
+ const warn = (message) => console.error(formatWarning({ message }));
86
89
  /**
87
- * Append `record` to chant/lifecycle and push it. With `--no-push` (#4295)
88
- * the record is written to `pr-env-record.json` under `--output` instead,
89
- * for `pr-env post` to append from a job that runs none of the change's
90
- * code. A failure warns: what was applied or torn down stands.
90
+ * The ports `pr-env` runs with (../../components/pr-env-run.ts): the records
91
+ * and the gate ledger on chant/lifecycle here, and the report written under
92
+ * `--output` and posted through `forge`. With `--no-push` (#4295) the record
93
+ * is written to `pr-env-record.json` under `--output` instead, for `pr-env
94
+ * post` to append from a job that runs none of the change's code.
91
95
  */
92
- async function appendRecord(ctx, record) {
93
- if (ctx.args.noPush) {
94
- const dir = resolve(ctx.args.output ?? PR_ENV_REPORT_DIR);
95
- mkdirSync(dir, { recursive: true });
96
- writeFileSync(join(dir, PR_ENV_RECORD_FILE), JSON.stringify(record, null, 2) + "\n");
97
- return;
98
- }
99
- const { appendLedgerLine, fetchLifecycle, pushLifecycleReport } = await import("../../lifecycle/git.js");
100
- try {
101
- await fetchLifecycle().catch(() => false);
102
- await appendLedgerLine(PR_ENV_LEDGER_DIR, PR_ENV_LEDGER_FILE, JSON.stringify(record), `Pull request environment ${record.env} ${record.kind} (${record.result})`);
103
- const pushed = await pushLifecycleReport();
104
- if (pushed.pushWarning)
105
- console.error(formatWarning({ message: pushed.pushWarning }));
106
- }
107
- catch (err) {
108
- console.error(formatWarning({ message: `could not record ${record.env}'s ${record.kind} on chant/lifecycle: ${err instanceof Error ? err.message : String(err)}` }));
109
- }
96
+ function cliPorts(ctx, forge) {
97
+ const lifecycle = lifecyclePrEnvPorts({ ...(forge ? { forge } : {}), log, warn });
98
+ return {
99
+ ...lifecycle,
100
+ async appendRecord(record) {
101
+ if (!ctx.args.noPush)
102
+ return lifecycle.appendRecord(record);
103
+ const dir = resolve(ctx.args.output ?? PR_ENV_REPORT_DIR);
104
+ mkdirSync(dir, { recursive: true });
105
+ writeFileSync(join(dir, PR_ENV_RECORD_FILE), JSON.stringify(record, null, 2) + "\n");
106
+ },
107
+ publish: (report) => finish(ctx, forge, report),
108
+ };
110
109
  }
111
110
  // ── the report and the note ────────────────────────────────────────────────
112
111
  async function finish(ctx, forge, report) {
@@ -117,27 +116,8 @@ async function finish(ctx, forge, report) {
117
116
  writeFileSync(join(dir, "pr-env-note.md"), note);
118
117
  if (ctx.args.json)
119
118
  console.log(JSON.stringify(report, null, 2));
120
- if (!forge)
121
- return;
122
- if (report.head) {
123
- try {
124
- await forge.setStatus(report.head, {
125
- context: prEnvStatusContext(report.member),
126
- state: prEnvStatusState(report),
127
- description: prEnvStatusDescription(report),
128
- ...(forge.runUrl ? { url: forge.runUrl } : {}),
129
- });
130
- }
131
- catch (err) {
132
- console.error(formatWarning({ message: `could not set the ${prEnvStatusContext(report.member)} status: ${err instanceof Error ? err.message : String(err)}` }));
133
- }
134
- }
135
- try {
136
- await forge.upsertNote(report.pr, prEnvNoteMarker(report.env, report.member), note);
137
- }
138
- catch (err) {
139
- console.error(formatWarning({ message: `could not post the note on #${report.pr}: ${err instanceof Error ? err.message : String(err)}` }));
140
- }
119
+ if (forge)
120
+ await forgePrEnvPublisher(forge, warn)(report);
141
121
  }
142
122
  // ── up ─────────────────────────────────────────────────────────────────────
143
123
  async function prEnvUp(ctx) {
@@ -159,7 +139,6 @@ async function prEnvUp(ctx) {
159
139
  const derived = derivePrEnvironment(config, setting.template, pr);
160
140
  if ("refusal" in derived)
161
141
  return fail(derived.refusal);
162
- const ttl = ttlMs(setting.ttl) ?? ttlMs("72h");
163
142
  // The build sees pr-<n> as its environment and the template's name beside it.
164
143
  process.env[ENV_VAR] = derived.env;
165
144
  process.env[PR_ENV_TEMPLATE_VAR] = derived.template;
@@ -168,108 +147,77 @@ async function prEnvUp(ctx) {
168
147
  args: { ...args, env: derived.env, param: [...(args.param ?? []).filter((p) => !p.startsWith(`${derived.param}=`)), `${derived.param}=${derived.env}`] },
169
148
  };
170
149
  console.error(formatInfo(`pr-env up: ${derived.env}, derived from ${derived.template}${derived.endpoint ? ` at ${derived.endpoint}` : ""}, marker ${derived.stack}/${derived.env}`));
171
- return withComponentEndpoint(envCtx, () => up(envCtx, pr, derived, ttl), { config: { ...config, environments: derived.environments }, environment: derived.env });
150
+ return withComponentEndpoint(envCtx, () => up(envCtx, pr, derived, setting.ttl), { config: { ...config, environments: derived.environments }, environment: derived.env });
172
151
  }
173
152
  async function up(ctx, pr, derived, ttl) {
174
153
  const { prepare, planAll, placeHooks, runStageHook } = await import("./pr.js");
175
154
  const p = await prepare(ctx, "plan");
176
155
  if (typeof p === "number")
177
156
  return p;
178
- const forge = p.forge;
179
- const op = prOp(pr, p.member);
180
157
  // ci.hooks (#4288), read at base as the other pull-request jobs read them, around the plan and the apply.
181
- placeHooks(ctx, p, "apply", op);
182
- const base = {
183
- stage: "up",
158
+ placeHooks(ctx, p, "apply", prEnvOp(pr, p.member));
159
+ const result = await prEnvUpRun({
184
160
  pr,
185
- env: derived.env,
186
- ...(p.member ? { member: p.member } : {}),
187
- template: derived.template,
188
161
  head: p.head,
189
- op,
190
- gate: PR_ENV_GATE,
191
- digest: "",
192
- status: "nothing",
193
- ...(derived.endpoint ? { endpoint: derived.endpoint } : {}),
194
- components: [],
195
- };
196
- if (p.plan.order.length === 0) {
197
- await finish(ctx, forge, { ...base, ...(p.routedAway ? { message: p.routedAway } : {}) });
198
- console.error(formatInfo(`pr-env up: nothing this change touches is deployed by a component, so ${derived.env} gets nothing`));
199
- return PR_ENV_EXIT.done;
200
- }
201
- const set = await planAll(p);
202
- const rows = (status) => p.plan.order.map((component) => {
203
- const ms = set.members.filter((m) => m.component === component);
204
- const sum = (k) => ms.reduce((n, m) => n + m.counts[k], 0);
205
- return { component, status: status(component), create: sum("create"), update: sum("update"), replace: sum("replace"), delete: sum("delete") };
206
- });
207
- const digest = set.doc.digest;
208
- if (set.failed) {
209
- await finish(ctx, forge, { ...base, digest, status: "plan-failed", ...(p.hookFailed ? { message: p.hookFailed } : {}), components: rows((c) => (set.members.some((m) => m.component === c && m.status === "plan-failed") ? "plan failed" : "planned")) });
210
- return PR_ENV_EXIT.failed;
211
- }
212
- // ws-080, ws-104: a non-empty plan applies only under a person's approval of its digest. An empty one passes.
213
- let approvedBy;
214
- if (!isEmptyChangeSet(set.doc)) {
215
- let approval;
216
- try {
217
- approval = approvalOf(await decidePrGate(readOnlyLedger(gitGateLedgerPort()), { op, gate: PR_ENV_GATE, digest, description: `${derived.env}: ${p.plan.order.join(", ")}` }));
218
- }
219
- catch (err) {
220
- return fail(`could not read the gate ledger, so ${derived.env} does not apply: ${err instanceof Error ? err.message : String(err)}`);
221
- }
222
- if (approval.status !== "approved") {
223
- const status = approval.status === "changed" ? "changed" : "waiting";
224
- await finish(ctx, forge, { ...base, digest, status, components: rows(() => "planned") });
225
- console.error(formatInfo(`pr-env up: ${derived.env} waits for an approval of ${digest}`));
226
- console.error(formatInfo(`approve : ${prEnvApproveCommand(op, digest)}`));
227
- return PR_ENV_EXIT.waiting;
228
- }
229
- approvedBy = approval.approvedBy ?? [];
230
- }
231
- const hookStop = runStageHook(p, "before-apply", p.plan.order, set);
232
- if (hookStop) {
233
- await finish(ctx, forge, { ...base, digest, status: "failed", message: hookStop, components: rows(() => "planned"), ...(approvedBy ? { approvedBy } : {}) });
234
- return PR_ENV_EXIT.failed;
235
- }
236
- const applied = await applyPrSet({ components: p.components, plan: p.plan, registry: p.registry, env: derived.env, set, gate: PR_ENV_GATE });
237
- const afterHook = runStageHook(p, "after-apply", p.plan.order, set, "the environment stands as applied");
238
- const status = (component) => applied.members.find((m) => m.component === component)?.status ?? "planned";
239
- const ok = applied.status === "applied";
240
- const now = new Date();
241
- const expiresAt = new Date(now.getTime() + ttl).toISOString();
242
- // A copy that failed part way is live too: what applied is torn down on close or at expiry like the rest.
243
- await appendRecord(ctx, {
244
- version: 1,
245
- kind: "up",
246
- pr,
247
- env: derived.env,
248
- ...(p.member ? { member: p.member } : {}),
249
162
  template: derived.template,
250
- marker: { stack: derived.stack, env: derived.env },
251
- commit: p.head,
252
- components: p.plan.order,
253
- planDigest: digest,
254
- result: ok ? "applied" : "failed",
255
- by: actor(),
256
- timestamp: now.toISOString(),
257
- expiresAt,
258
- ...(approvedBy ? { approvedBy } : {}),
259
- releaseTarget: false,
260
- ...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
163
+ ttl,
164
+ stack: derived.stack,
165
+ ...(p.member ? { member: p.member } : {}),
166
+ ...(derived.endpoint ? { endpoint: derived.endpoint } : {}),
167
+ adapter: componentsPrEnvAdapter(p, { planAll, runStageHook }),
168
+ ports: cliPorts(ctx, p.forge),
169
+ actor: actor(),
170
+ ...(p.forge?.runUrl ? { runUrl: p.forge.runUrl } : {}),
261
171
  });
262
- await finish(ctx, forge, {
263
- ...base,
264
- digest,
265
- status: ok ? "applied" : "failed",
266
- components: rows(status),
267
- ...(approvedBy ? { approvedBy } : {}),
268
- expiresAt,
269
- ...(ok ? (afterHook ? { message: afterHook } : {}) : { message: applied.status === "waiting" ? "A component read an upstream output that moved when it applied; run the job again to plan it against the new value." : "A component failed to apply; what applied stays in the environment and is torn down with it." }),
172
+ if (result.report.status === "waiting" || result.report.status === "changed")
173
+ console.error(formatInfo(`approve : ${prEnvApproveCommand(result.report.op, result.report.digest)}`));
174
+ return result.exit;
175
+ }
176
+ /**
177
+ * The components as a pull request environment's adapter: the plan is
178
+ * `pr-plan`'s, with the plan-side hooks around it, and the apply is the
179
+ * fan-out's, with the apply-side hooks around it. Each row carries the
180
+ * component's site in `pr-<n>`, carried over from the template's (#4330,
181
+ * `prEnvironmentSite`).
182
+ */
183
+ function componentsPrEnvAdapter(p, run) {
184
+ let set;
185
+ const rows = (target, status) => p.plan.order.map((component) => {
186
+ const ms = (set?.members ?? []).filter((m) => m.component === component);
187
+ const sum = (k) => ms.reduce((n, m) => n + m.counts[k], 0);
188
+ const found = prEnvironmentSite(p.sites?.[component], target.template, target.env);
189
+ const site = found ? { ...(found.runtime ? { runtime: found.runtime } : {}), ...(found.url ? { url: found.url } : {}), ...(found.domain ? { domain: found.domain } : {}) } : undefined;
190
+ return { component, status: status(component), create: sum("create"), update: sum("update"), replace: sum("replace"), delete: sum("delete"), ...(site && Object.keys(site).length > 0 ? { site } : {}) };
270
191
  });
271
- console.error((ok ? formatInfo : (m) => formatWarning({ message: m }))(`pr-env up: ${derived.env} ${ok ? "applied" : applied.status}; it expires ${expiresAt}`));
272
- return ok && !afterHook ? PR_ENV_EXIT.done : PR_ENV_EXIT.failed;
192
+ return {
193
+ async plan(target) {
194
+ if (p.plan.order.length === 0)
195
+ return { digest: "", empty: true, rows: [], ...(p.routedAway ? { message: p.routedAway } : {}) };
196
+ set = await run.planAll(p);
197
+ const planned = set;
198
+ return {
199
+ digest: planned.doc.digest,
200
+ empty: isEmptyChangeSet(planned.doc),
201
+ ...(planned.failed ? { failed: true } : {}),
202
+ rows: rows(target, (c) => (planned.failed && planned.members.some((m) => m.component === c && m.status === "plan-failed") ? "plan failed" : "planned")),
203
+ ...(p.hookFailed ? { message: p.hookFailed } : {}),
204
+ };
205
+ },
206
+ async apply(target) {
207
+ const planned = set;
208
+ const hookStop = run.runStageHook(p, "before-apply", p.plan.order, planned);
209
+ if (hookStop)
210
+ return { status: "stopped", rows: rows(target, () => "planned"), message: hookStop };
211
+ const applied = await applyPrSet({ components: p.components, plan: p.plan, registry: p.registry, env: target.env, set: planned, gate: PR_ENV_GATE });
212
+ const afterHook = run.runStageHook(p, "after-apply", p.plan.order, planned, "the environment stands as applied");
213
+ const status = (component) => applied.members.find((m) => m.component === component)?.status ?? "planned";
214
+ return {
215
+ status: applied.status === "applied" ? "applied" : applied.status === "waiting" ? "waiting" : "failed",
216
+ rows: rows(target, status),
217
+ ...(afterHook ? { afterFailure: afterHook } : {}),
218
+ };
219
+ },
220
+ };
273
221
  }
274
222
  // ── post ───────────────────────────────────────────────────────────────────
275
223
  /**
@@ -319,7 +267,7 @@ async function prEnvPost(ctx) {
319
267
  code = PR_ENV_EXIT.failed;
320
268
  }
321
269
  else {
322
- await appendRecord({ ...ctx, args: { ...args, noPush: false } }, accepted.record);
270
+ await lifecyclePrEnvPorts({ warn }).appendRecord(accepted.record);
323
271
  if (accepted.record.expiresAt)
324
272
  report.expiresAt = accepted.record.expiresAt;
325
273
  }
@@ -329,6 +277,18 @@ async function prEnvPost(ctx) {
329
277
  return code;
330
278
  }
331
279
  // ── down ───────────────────────────────────────────────────────────────────
280
+ /**
281
+ * What tears the environment down: the lexicons, and the command
282
+ * `ci.prEnvironment.teardown` names in the declaration at this commit
283
+ * (#4330), which the down and sweep jobs check out from the base branch.
284
+ */
285
+ async function teardownSources() {
286
+ const projectPath = resolve(".");
287
+ const { config } = await loadChantConfig(projectPath).catch(() => ({ config: {} }));
288
+ const { scopeSource } = await import("../../workspace/write-scope.js");
289
+ const hook = scopeSource(projectPath, "HEAD").declaration?.ci?.prEnvironment?.teardown;
290
+ return { config, adapters: hook ? [commandTeardownAdapter(hook, { cwd: projectPath })] : [] };
291
+ }
332
292
  async function prEnvDown(ctx) {
333
293
  const { args } = ctx;
334
294
  if (args.pr === undefined)
@@ -339,61 +299,21 @@ async function prEnvDown(ctx) {
339
299
  const forge = forgeOf(ctx);
340
300
  if (typeof forge === "number")
341
301
  return forge;
342
- const live = livePrEnvironments(await readRecords()).get(prEnvironmentName(args.pr));
343
- return teardown(ctx, forge, args.pr, live, reason);
344
- }
345
- async function teardown(ctx, forge, pr, live, reason) {
346
- const env = prEnvironmentName(pr);
347
302
  const member = memberOf(ctx);
348
- const report = { stage: "down", pr, env, ...(member ? { member } : {}), template: live?.template ?? "", head: "", op: prOp(pr, member), gate: PR_ENV_GATE, digest: "", status: "absent", components: [] };
349
- if (!live) {
350
- console.error(formatInfo(`pr-env down: ${env} has no live record, so there is nothing to tear down`));
351
- if (forge)
352
- await finish(ctx, forge, report);
353
- return PR_ENV_EXIT.done;
354
- }
355
- const { config } = await loadChantConfig(resolve(".")).catch(() => ({ config: {} }));
356
- const torn = await tearDownPrEnvironment({ pr, live, config, plugins: ctx.plugins, warn: (message) => console.error(formatWarning({ message })) });
357
- if ("refusal" in torn) {
358
- await finish(ctx, forge, { ...report, template: live.template, status: "refused", message: torn.refusal });
359
- return fail(torn.refusal);
360
- }
361
- const { report: result, dropped, marker } = torn;
362
- const counts = teardownCounts(result);
363
- const complete = teardownComplete(result);
364
- const lexicons = [...new Set(result.outcomes.map((o) => o.lexicon))].sort();
365
- const head = await headCommit();
366
- await appendRecord(ctx, {
367
- version: 1,
368
- kind: "down",
369
- pr,
370
- env,
371
- ...(live.member ? { member: live.member } : {}),
372
- template: live.template,
373
- marker,
374
- commit: head,
375
- components: lexicons,
376
- planDigest: "",
377
- result: complete ? "destroyed" : "incomplete",
378
- by: actor(),
379
- timestamp: new Date().toISOString(),
303
+ const result = await prEnvDownRun({
304
+ pr: args.pr,
380
305
  reason,
381
- outcomes: counts,
382
- releaseTarget: false,
306
+ ...(member ? { member } : {}),
307
+ ports: cliPorts(ctx, forge),
308
+ ...(await teardownSources()),
309
+ plugins: ctx.plugins,
310
+ commit: await headCommit(),
311
+ actor: actor(),
383
312
  ...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
384
313
  });
385
- const why = [];
386
- if (dropped > 0)
387
- why.push(`${dropped} candidate${dropped === 1 ? "" : "s"} whose marker was not ${marker.stack}/${env} left alone`);
388
- if (result.unimplemented.length > 0)
389
- why.push(`no teardown execution in ${result.unimplemented.join(", ")}`);
390
- if (result.plan.holes.length > 0)
391
- why.push(`${result.plan.holes.length} part${result.plan.holes.length === 1 ? "" : "s"} could not be read`);
392
- for (const o of result.outcomes.filter((x) => x.outcome === "failed"))
393
- why.push(`${o.lexicon} ${o.name}: ${o.detail ?? "failed"}`);
394
- await finish(ctx, forge, { ...report, template: live.template, status: complete ? "destroyed" : "incomplete", outcomes: counts, ...(why.length > 0 ? { message: why.join("; ") } : {}) });
395
- console.error((complete ? formatInfo : (m) => formatWarning({ message: m }))(`pr-env down: ${env} ${complete ? "torn down" : "not wholly torn down; it stays live and the sweep tries again"} (${counts.deleted} deleted, ${counts.failed} failed, ${counts.skipped} skipped)`));
396
- return complete ? PR_ENV_EXIT.done : PR_ENV_EXIT.failed;
314
+ if (result.report.status === "refused")
315
+ return fail(result.report.message ?? "refused");
316
+ return result.exit;
397
317
  }
398
318
  async function headCommit() {
399
319
  const { spawnSync } = await import("node:child_process");
@@ -405,32 +325,13 @@ async function prEnvSweep(ctx) {
405
325
  const forge = forgeOf(ctx);
406
326
  if (typeof forge === "number")
407
327
  return forge;
408
- const live = [...livePrEnvironments(await readRecords()).values()];
409
- if (live.length === 0) {
410
- console.error(formatInfo("pr-env sweep: no pull request environment is live"));
411
- return PR_ENV_EXIT.done;
412
- }
413
- const now = new Date();
414
- let code = PR_ENV_EXIT.done;
415
- for (const e of live) {
416
- let reason = expired(e, now) ? "expired" : undefined;
417
- if (!reason && forge?.pullRequestState) {
418
- try {
419
- const state = await forge.pullRequestState(e.pr);
420
- if (state !== "open")
421
- reason = "closed";
422
- }
423
- catch (err) {
424
- console.error(formatWarning({ message: `could not read whether #${e.pr} is open (${err instanceof Error ? err.message : String(err)}); its TTL still holds` }));
425
- }
426
- }
427
- if (!reason) {
428
- console.error(formatInfo(`pr-env sweep: ${e.env} stays; it expires ${e.expiresAt}`));
429
- continue;
430
- }
431
- const c = await teardown(ctx, forge, e.pr, e, reason);
432
- if (c !== PR_ENV_EXIT.done)
433
- code = PR_ENV_EXIT.failed;
434
- }
435
- return code;
328
+ const result = await prEnvSweepRun({
329
+ ports: cliPorts(ctx, forge),
330
+ ...(await teardownSources()),
331
+ plugins: ctx.plugins,
332
+ commit: await headCommit(),
333
+ actor: actor(),
334
+ ...(forge?.runUrl ? { runUrl: forge.runUrl } : {}),
335
+ });
336
+ return result.exit;
436
337
  }
@@ -72,6 +72,7 @@ import type { CommandContext } from "../registry.js";
72
72
  import type { ComponentChangeSignal, FanOutPlan } from "../../components/fan-out.js";
73
73
  import { type DriverComponent } from "../../components/driver.js";
74
74
  import type { CapabilityRegistry } from "../../components/capability.js";
75
+ import type { ComponentEnvironmentDeclaration } from "../../components/component.js";
75
76
  import { type PrHookPlace, type PrLoopHooks } from "../../components/pr-hooks.js";
76
77
  import { type PrLoopPolicy } from "../../components/pr-policy.js";
77
78
  import type { OpWaveHookMoment } from "../../op/op-waves.js";
@@ -97,6 +98,8 @@ export interface Prepared {
97
98
  signal: ComponentChangeSignal;
98
99
  registry: CapabilityRegistry;
99
100
  seededOutputs: Record<string, Record<string, unknown>>;
101
+ /** Component name to the environments it declares (#3153), whose sites `pr-env up` carries over (#4330). */
102
+ sites?: Record<string, ComponentEnvironmentDeclaration[]>;
100
103
  /** `ci.hooks` from the declaration at base (#4288). */
101
104
  hooks: PrLoopHooks;
102
105
  /** Every hook the stage ran so far, for the report's `hooks`. */
@@ -1 +1 @@
1
- {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/pr.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pr.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/pr.ts"],"names":[],"mappings":"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"}
@@ -218,6 +218,7 @@ export async function prepare(ctx, stage) {
218
218
  components: derived.components,
219
219
  plan: routedAway ? { ...derived.plan, order: [], waves: [], seeds: [], indeterminate: [] } : derived.plan,
220
220
  signal: derived.signal,
221
+ ...(derived.sites ? { sites: derived.sites } : {}),
221
222
  registry,
222
223
  seededOutputs,
223
224
  hooks,
@@ -327,6 +327,8 @@ export interface ResolvedComponentTargets {
327
327
  targets: DriverComponent[];
328
328
  /** For a list selector (#3950): the dependencies the closure added that the list did not name, in discovery order. */
329
329
  added?: string[];
330
+ /** Component name to the environments it declares (#3153), for the components that declare any (#4330). */
331
+ sites?: Record<string, ComponentEnvironmentDeclaration[]>;
330
332
  error?: string;
331
333
  }
332
334
  /** Whether `selector` is a comma-separated component list (#3950), as opposed to `all` or one name. */
@@ -1 +1 @@
1
- {"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-support.d.ts","sourceRoot":"","sources":["../../src/components/cli-support.ts"],"names":[],"mappings":"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"}
@@ -284,8 +284,10 @@ buildParams) {
284
284
  const all = discovered.map((component) => toDriverComponent(component));
285
285
  if (isComponentList(selector))
286
286
  return resolveComponentList(selector, discovered, all);
287
- if (selector === "all")
288
- return { success: true, targets: withoutDisabled(discovered, all) };
287
+ if (selector === "all") {
288
+ const sites = Object.fromEntries(discovered.filter((c) => c.environments && c.environments.length > 0).map((c) => [c.name, c.environments.map((e) => ({ ...e }))]));
289
+ return { success: true, targets: withoutDisabled(discovered, all), ...(Object.keys(sites).length > 0 ? { sites } : {}) };
290
+ }
289
291
  const found = all.find((c) => c.name === selector);
290
292
  const disabledByName = discovered.find((c) => c.name === selector && c.enabled === false);
291
293
  if (disabledByName) {
@@ -15,6 +15,7 @@
15
15
  import { type ChangedUnits, type ComponentChangeSignal, type FanOutPlan } from "./fan-out.js";
16
16
  import type { CapabilityRegistry } from "./capability.js";
17
17
  import type { DriverComponent } from "./driver.js";
18
+ import type { ComponentEnvironmentDeclaration } from "./component.js";
18
19
  import type { BuildParamProvenance } from "../provenance.js";
19
20
  import { type ChantConfig } from "../config.js";
20
21
  export interface DeriveFanOutOptions {
@@ -42,6 +43,8 @@ export interface DerivedFanOut {
42
43
  /** What the stack-level signal meant in component terms, `unclaimed` included. */
43
44
  signal: ComponentChangeSignal;
44
45
  plan: FanOutPlan;
46
+ /** Component name to the environments it declares, for the components that declare any (#4330). */
47
+ sites?: Record<string, ComponentEnvironmentDeclaration[]>;
45
48
  error?: string;
46
49
  }
47
50
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"fan-out-support.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAAkC,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,qGAAqG;IACrG,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8HAA8H;IAC9H,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC,kFAAkF;IAClF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,kFAAkF;IAClF,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBvF;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAGpG"}
1
+ {"version":3,"file":"fan-out-support.d.ts","sourceRoot":"","sources":["../../src/components/fan-out-support.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,EAAkC,KAAK,YAAY,EAAE,KAAK,qBAAqB,EAAE,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAC3H,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAmB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAE9D,MAAM,WAAW,mBAAmB;IAClC,uDAAuD;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,qGAAqG;IACrG,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,8HAA8H;IAC9H,WAAW,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACrC,kFAAkF;IAClF,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;OAKG;IACH,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,kFAAkF;IAClF,MAAM,EAAE,qBAAqB,CAAC;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,mGAAmG;IACnG,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,+BAA+B,EAAE,CAAC,CAAC;IAC1D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC,CAkBvF;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAGpG"}
@@ -47,7 +47,7 @@ export async function deriveFanOut(options) {
47
47
  ...(signal.indeterminate.length > 0 ? { indeterminate: signal.indeterminate } : {}),
48
48
  ...(options.canary?.length ? { canary: options.canary } : {}),
49
49
  });
50
- return { success: true, components, signal, plan };
50
+ return { success: true, components, signal, plan, ...(resolved.sites ? { sites: resolved.sites } : {}) };
51
51
  }
52
52
  /**
53
53
  * The capability registry a fan-out dispatches through — the project's own,