@intentius/chant 0.124.39 → 0.124.40

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 (74) hide show
  1. package/dist/cli/component-endpoint.d.ts +20 -0
  2. package/dist/cli/component-endpoint.d.ts.map +1 -0
  3. package/dist/cli/component-endpoint.js +36 -0
  4. package/dist/cli/handlers/fan-out.d.ts.map +1 -1
  5. package/dist/cli/handlers/fan-out.js +10 -1
  6. package/dist/cli/handlers/pr.d.ts.map +1 -1
  7. package/dist/cli/handlers/pr.js +11 -5
  8. package/dist/cli/handlers/promote.d.ts.map +1 -1
  9. package/dist/cli/handlers/promote.js +7 -2
  10. package/dist/cli/handlers/run.d.ts +4 -1
  11. package/dist/cli/handlers/run.d.ts.map +1 -1
  12. package/dist/cli/handlers/run.js +17 -6
  13. package/dist/components/auto-release.d.ts +35 -3
  14. package/dist/components/auto-release.d.ts.map +1 -1
  15. package/dist/components/auto-release.js +29 -2
  16. package/dist/components/cli-support.d.ts +2 -0
  17. package/dist/components/cli-support.d.ts.map +1 -1
  18. package/dist/components/cli-support.js +2 -0
  19. package/dist/components/deploy-units.d.ts.map +1 -1
  20. package/dist/components/deploy-units.js +5 -0
  21. package/dist/components/promote.d.ts.map +1 -1
  22. package/dist/components/promote.js +39 -16
  23. package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
  24. package/dist/lifecycle/__fixtures__/publish-fakes.js +6 -1
  25. package/dist/lifecycle/publish-declaration.d.ts.map +1 -1
  26. package/dist/lifecycle/publish-declaration.js +4 -3
  27. package/dist/lifecycle/publish-npm.d.ts +2 -2
  28. package/dist/lifecycle/publish-npm.d.ts.map +1 -1
  29. package/dist/lifecycle/publish-npm.js +31 -8
  30. package/dist/lifecycle/release-ledger.d.ts +31 -0
  31. package/dist/lifecycle/release-ledger.d.ts.map +1 -1
  32. package/dist/lifecycle/release-ledger.js +19 -1
  33. package/dist/lifecycle/status.d.ts +5 -1
  34. package/dist/lifecycle/status.d.ts.map +1 -1
  35. package/dist/lifecycle/status.js +10 -5
  36. package/dist/live-endpoint.d.ts +18 -0
  37. package/dist/live-endpoint.d.ts.map +1 -1
  38. package/dist/live-endpoint.js +27 -0
  39. package/dist/wave-runtime.mjs +192 -192
  40. package/dist/workspace/ci-run.d.ts +7 -0
  41. package/dist/workspace/ci-run.d.ts.map +1 -1
  42. package/dist/workspace/ci-run.js +21 -3
  43. package/dist/workspace/status.d.ts +3 -1
  44. package/dist/workspace/status.d.ts.map +1 -1
  45. package/dist/workspace/status.js +3 -2
  46. package/dist/workspace/status.schema.json +1 -0
  47. package/package.json +1 -1
  48. package/src/cli/component-endpoint.ts +43 -0
  49. package/src/cli/handlers/fan-out.test.ts +10 -0
  50. package/src/cli/handlers/fan-out.ts +12 -0
  51. package/src/cli/handlers/pr-endpoint.test.ts +169 -0
  52. package/src/cli/handlers/pr.ts +12 -5
  53. package/src/cli/handlers/promote.ts +16 -2
  54. package/src/cli/handlers/run.test.ts +2 -1
  55. package/src/cli/handlers/run.ts +16 -5
  56. package/src/components/auto-release-infra.test.ts +131 -0
  57. package/src/components/auto-release.test.ts +40 -1
  58. package/src/components/auto-release.ts +50 -4
  59. package/src/components/cli-support.ts +4 -0
  60. package/src/components/deploy-units.ts +5 -0
  61. package/src/components/promote.test.ts +39 -0
  62. package/src/components/promote.ts +38 -14
  63. package/src/lifecycle/__fixtures__/publish-fakes.ts +6 -1
  64. package/src/lifecycle/publish-declaration.ts +4 -3
  65. package/src/lifecycle/publish-npm.ts +33 -8
  66. package/src/lifecycle/publish-targets.test.ts +36 -3
  67. package/src/lifecycle/release-ledger.ts +42 -1
  68. package/src/lifecycle/status.test.ts +19 -0
  69. package/src/lifecycle/status.ts +14 -6
  70. package/src/live-endpoint.ts +31 -0
  71. package/src/workspace/ci-run.test.ts +26 -0
  72. package/src/workspace/ci-run.ts +20 -3
  73. package/src/workspace/status.schema.json +1 -0
  74. package/src/workspace/status.ts +7 -3
@@ -38,7 +38,7 @@
38
38
  * the same spirit as `DEPLOY_UNIT_RULES` (./deploy-units.ts).
39
39
  */
40
40
  import { parseWiringRef } from "../lint/rules/comp/support.js";
41
- import { latestPerComponent } from "../lifecycle/release-ledger.js";
41
+ import { isApplyRecord, latestPerComponent } from "../lifecycle/release-ledger.js";
42
42
  import { CapabilityRegistry } from "./capability.js";
43
43
  import { runInterpretDriver, DriverRunFailure, } from "./driver.js";
44
44
  /**
@@ -68,20 +68,35 @@ export const PUBLISH_STEP_KINDS = [
68
68
  * A digest the ledger never recorded for the component is an error.
69
69
  */
70
70
  export function selectRelease(records, component, env, digest) {
71
- const own = records.filter((r) => r.component === component);
72
- if (own.length === 0)
73
- return { error: `no release of "${component}" is recorded in "${env}"` };
71
+ const own = deployableRecords(records, component, env);
72
+ if ("error" in own)
73
+ return own;
74
74
  if (digest === undefined)
75
- return { record: latestPerComponent(own).get(component) };
76
- const matching = own.filter((r) => r.digest === digest);
75
+ return { record: latestPerComponent(own.records).get(component) };
76
+ const matching = own.records.filter((r) => r.digest === digest);
77
77
  if (matching.length === 0) {
78
78
  return {
79
79
  error: `digest ${digest} is not recorded for "${component}" in "${env}"; ` +
80
- `its recorded digests are ${[...new Set(own.map((r) => r.digest))].join(", ")}`,
80
+ `its recorded digests are ${[...new Set(own.records.map((r) => r.digest))].join(", ")}`,
81
81
  };
82
82
  }
83
83
  return { record: latestPerComponent(matching).get(component) };
84
84
  }
85
+ /**
86
+ * The records of `component` a promote, rollback or redeploy can deploy from
87
+ * (#4274): every one but those that only say it applied ({@link isApplyRecord}),
88
+ * whose digest is a plan or deploy-input digest and names no artifact.
89
+ */
90
+ function deployableRecords(records, component, env) {
91
+ const own = records.filter((r) => r.component === component);
92
+ if (own.length === 0)
93
+ return { error: `no release of "${component}" is recorded in "${env}"` };
94
+ const deployable = own.filter((r) => !isApplyRecord(r));
95
+ if (deployable.length === 0)
96
+ return { error: appliesOnly(component, env) };
97
+ return { records: deployable };
98
+ }
99
+ const appliesOnly = (component, env) => `"${component}" has only applies recorded in "${env}", each by a plan or deploy-input digest, so no artifact of it can be deployed again`;
85
100
  /**
86
101
  * Read `--digest <component>=<digest>` values (#2602) into a component-to-
87
102
  * digest map. A value with no `=` is left to the single-component form
@@ -150,7 +165,7 @@ export function planPromotion(input) {
150
165
  return picked;
151
166
  return { from, to, items: [{ component, digest: picked.record.digest, source: picked.record }], notPromoted: [] };
152
167
  }
153
- const latest = latestPerComponent(sourceRecords);
168
+ const latest = latestPerComponent(sourceRecords.filter((r) => !isApplyRecord(r)));
154
169
  const items = [];
155
170
  const notPromoted = [];
156
171
  for (const [name, record] of [...latest].sort(([a], [b]) => a.localeCompare(b))) {
@@ -159,6 +174,10 @@ export function planPromotion(input) {
159
174
  else
160
175
  notPromoted.push({ component: name, reason: "recorded but not declared in this checkout" });
161
176
  }
177
+ // #4274: a component that only applied (infrastructure, no artifact) has nothing to promote.
178
+ for (const name of [...new Set(sourceRecords.filter((r) => isApplyRecord(r) && !latest.has(r.component)).map((r) => r.component))].sort()) {
179
+ notPromoted.push({ component: name, reason: "only applies are recorded, by a plan or deploy-input digest; there is no artifact to promote" });
180
+ }
162
181
  if (items.length === 0) {
163
182
  return { error: `nothing to promote: no component declared here has a release recorded in "${from}"` };
164
183
  }
@@ -175,10 +194,11 @@ export function planRollback(input) {
175
194
  if (!declared.includes(component)) {
176
195
  return { error: `component "${component}" is not declared in this checkout` };
177
196
  }
178
- const own = records.filter((r) => r.component === component);
197
+ const deployable = deployableRecords(records, component, env);
198
+ if ("error" in deployable)
199
+ return deployable;
200
+ const own = deployable.records;
179
201
  const current = latestPerComponent(own).get(component);
180
- if (!current)
181
- return { error: `no release of "${component}" is recorded in "${env}"` };
182
202
  let target;
183
203
  if (digest !== undefined) {
184
204
  const picked = selectRelease(own, component, env, digest);
@@ -226,7 +246,7 @@ export function planReleaseRollback(input) {
226
246
  notPromoted.push({ component, reason: `in release ${name} but not declared in this checkout` });
227
247
  continue;
228
248
  }
229
- const ran = records.filter((r) => r.component === component && r.releaseDigest === release.releaseDigest);
249
+ const ran = records.filter((r) => r.component === component && r.releaseDigest === release.releaseDigest && !isApplyRecord(r));
230
250
  if (ran.length === 0) {
231
251
  neverRan.push(component);
232
252
  continue;
@@ -242,7 +262,7 @@ export function planReleaseRollback(input) {
242
262
  }
243
263
  if (items.length === 0)
244
264
  return { error: `release ${name} has no component declared in this checkout` };
245
- const current = latestPerComponent(records);
265
+ const current = latestPerComponent(records.filter((r) => !isApplyRecord(r)));
246
266
  const already = items.every((i) => {
247
267
  const now = current.get(i.component);
248
268
  return now !== undefined && now.releaseDigest === release.releaseDigest && now.digest === i.digest && !input.unsettled?.has(i.component);
@@ -265,9 +285,10 @@ export function planRedeploy(input) {
265
285
  if (!declared.includes(component)) {
266
286
  return { error: `component "${component}" is not declared in this checkout` };
267
287
  }
268
- const current = latestPerComponent(records.filter((r) => r.component === component)).get(component);
269
- if (!current)
270
- return { error: `no release of "${component}" is recorded in "${env}"` };
288
+ const deployable = deployableRecords(records, component, env);
289
+ if ("error" in deployable)
290
+ return deployable;
291
+ const current = latestPerComponent(deployable.records).get(component);
271
292
  if (digest !== undefined && digest !== current.digest) {
272
293
  return {
273
294
  error: `${digest} is not the current release of "${component}" in "${env}" (that is ${current.digest}); ` +
@@ -589,6 +610,8 @@ function sharedRecord(item, env, run) {
589
610
  ...(run.admission ? { admission: run.admission } : {}),
590
611
  ...(source.manifestDigest ? { manifestDigest: source.manifestDigest } : {}),
591
612
  ...(source.inputDigest ? { inputDigest: source.inputDigest } : {}),
613
+ // #4274: a release's templates digest stays one when it is deployed again.
614
+ ...(source.digestKind ? { digestKind: source.digestKind } : {}),
592
615
  };
593
616
  }
594
617
  /** Name an earlier record the way `promotedFrom`, `restores` and `redeploys` do. */
@@ -1 +1 @@
1
- {"version":3,"file":"publish-fakes.d.ts","sourceRoot":"","sources":["../../../src/lifecycle/__fixtures__/publish-fakes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish-fakes.d.ts","sourceRoot":"","sources":["../../../src/lifecycle/__fixtures__/publish-fakes.ts"],"names":[],"mappings":"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"}
@@ -179,7 +179,12 @@ if (args[0] === "publish") {
179
179
  const [name, version] = split(args[1]);
180
180
  const p = reg.packages[name];
181
181
  if (!p) { console.error("npm error 404 Not Found - " + name); process.exit(1); }
182
- if (p.lag && p.lag[version] > 0) { p.lag[version] -= 1; save(); }
182
+ if (process.env.FAKE_NPM_VIEW_ERROR && name.includes(process.env.FAKE_NPM_VIEW_ERROR) && p.versions.includes(version)) { console.error("npm error code E500"); console.error("npm error 500 Internal Server Error - GET https://registry.example/" + name); process.exit(1); }
183
+ if (p.lag && p.lag[version] > 0) {
184
+ p.lag[version] -= 1; save();
185
+ // A new package npm does not serve yet answers 404, as the real registry does.
186
+ if (process.env.FAKE_NPM_LAG_404) { console.error("npm error code E404"); console.error("npm error 404 No match found for version " + version); process.exit(1); }
187
+ }
183
188
  else if (p.versions.includes(version)) console.log(version);
184
189
  } else if (args[0] === "dist-tag" && args[1] === "add") {
185
190
  const [name, version] = split(args[2]);
@@ -1 +1 @@
1
- {"version":3,"file":"publish-declaration.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-declaration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;kBAoClB,CAAC;AAEZ,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB;;;;;;;;kBAgBlB,CAAC;AAEZ,wFAAwF;AACxF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;kBAiBpB,CAAC;AAEZ,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAAyF,CAAC;AAE/H,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
1
+ {"version":3,"file":"publish-declaration.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-declaration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB;;;;;;;;;;;;kBAqClB,CAAC;AAEZ,8FAA8F;AAC9F,eAAO,MAAM,gBAAgB;;;;;;;;kBAgBlB,CAAC;AAEZ,wFAAwF;AACxF,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;kBAiBpB,CAAC;AAEZ,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAAyF,CAAC;AAE/H,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AACrE,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACzE,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
@@ -57,9 +57,10 @@ export const NpmPublishSchema = z
57
57
  */
58
58
  tokenEnv: envName.optional(),
59
59
  /**
60
- * Seconds the reveal waits for the registry to serve every version it
61
- * published before installing them to audit (#4244). A registry accepts a
62
- * publish before it serves it. Default 600.
60
+ * A cap, in seconds, on the reveal's wait for the registry to serve every
61
+ * version it published before installing them to audit (#4244). A
62
+ * registry accepts a publish before it serves it. Unset, the wait ends
63
+ * only when every version is served or the registry fails (#4271).
63
64
  */
64
65
  registryWait: z.number().int().min(0).optional(),
65
66
  })
@@ -61,9 +61,9 @@ export declare function npmDistTagArgs(decl: Pick<NpmPublishDeclaration, "regist
61
61
  export declare function npmAuditInstallArgs(decl: Pick<NpmPublishDeclaration, "registry">): string[];
62
62
  /** The arguments of `npm audit signatures`. */
63
63
  export declare function npmAuditSignaturesArgs(decl: Pick<NpmPublishDeclaration, "registry">): string[];
64
- /** Seconds the reveal waits for the registry to serve what it published, by default (#4244). */
65
- export declare const NPM_REGISTRY_WAIT_SECONDS = 600;
66
64
  /** Between polls of the registry while it waits. */
67
65
  export declare const NPM_REGISTRY_POLL_MS = 10000;
66
+ /** Between progress lines while the reveal waits for the registry (#4271). */
67
+ export declare const NPM_REGISTRY_PROGRESS_MS = 60000;
68
68
  export declare function npmTarget(decl: NpmPublishDeclaration, deps: PublishDeps): PublishTarget;
69
69
  //# sourceMappingURL=publish-npm.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"publish-npm.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-npm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,WAAW,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoDnJ,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAUpL;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElI;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE3F;AAED,+CAA+C;AAC/C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE9F;AAuBD,gGAAgG;AAChG,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,oDAAoD;AACpD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAI3C,wBAAgB,SAAS,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,GAAG,aAAa,CAgLvF"}
1
+ {"version":3,"file":"publish-npm.d.ts","sourceRoot":"","sources":["../../src/lifecycle/publish-npm.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAOH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,WAAW,EAAoB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoDnJ,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,QAAQ,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,YAAY,CAAC,EAAE,GAAG,GAAE,MAAsB,GAAG,MAAM,EAAE,CAUpL;AAED,yFAAyF;AACzF,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAElI;AAED,iIAAiI;AACjI,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE3F;AAED,+CAA+C;AAC/C,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,GAAG,MAAM,EAAE,CAE9F;AAuBD,oDAAoD;AACpD,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAC3C,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAM/C,wBAAgB,SAAS,CAAC,IAAI,EAAE,qBAAqB,EAAE,IAAI,EAAE,WAAW,GAAG,aAAa,CAuMvF"}
@@ -148,10 +148,12 @@ function run(bin, args, ctx, cwd = ctx.cwd, env = ctx.env) {
148
148
  });
149
149
  });
150
150
  }
151
- /** Seconds the reveal waits for the registry to serve what it published, by default (#4244). */
152
- export const NPM_REGISTRY_WAIT_SECONDS = 600;
153
151
  /** Between polls of the registry while it waits. */
154
152
  export const NPM_REGISTRY_POLL_MS = 10000;
153
+ /** Between progress lines while the reveal waits for the registry (#4271). */
154
+ export const NPM_REGISTRY_PROGRESS_MS = 60000;
155
+ /** `npm view`'s answers for a version the registry does not serve yet; any other failure is the registry's error. */
156
+ const NPM_VIEW_NOT_YET = /\bE404\b|\b404 Not Found\b|is not in (this|the npm) registry|No match found for version|\b(ETARGET|notarget)\b/;
155
157
  /** npm's errors for a version the registry does not serve yet. */
156
158
  const NPM_NOT_SERVED = /\b(ETARGET|ERESOLVE|notarget)\b|No matching version found/;
157
159
  export function npmTarget(decl, deps) {
@@ -216,28 +218,49 @@ export function npmTarget(decl, deps) {
216
218
  * `npm audit signatures` there (#4049), which checks each package's
217
219
  * registry signature and provenance attestation.
218
220
  */
221
+ /**
222
+ * Whether the registry serves the version yet, while the reveal waits for
223
+ * it (#4271). A 404, or an answer without the version, is not yet; any other
224
+ * failure of `npm view` is the registry's error and ends the wait.
225
+ */
226
+ const probe = async (ctx, pkg) => {
227
+ const r = await npm(ctx, ["view", `${pkg.name}@${pkg.version}`, "version", ...(decl.registry ? ["--registry", decl.registry] : [])]);
228
+ if (r.code === 0)
229
+ return r.output.some((l) => l.trim() === pkg.version || l.trim() === JSON.stringify(pkg.version));
230
+ if (r.output.some((l) => NPM_VIEW_NOT_YET.test(l)))
231
+ return false;
232
+ const said = r.output.filter((l) => /^npm (error|ERR!)/.test(l)).at(-1) ?? r.output.at(-1) ?? "npm printed nothing";
233
+ throw new PublishTargetError("publish-npm-registry-failed", `npm view ${pkg.name}@${pkg.version} exited ${r.code} while the reveal waited for the registry to serve it, so nothing was audited: ${said}`, "Each package was published. Once the registry answers, run the publish again: it publishes nothing twice and audits again.");
234
+ };
219
235
  /**
220
236
  * Wait until the registry serves every version (#4244): npm accepts a
221
237
  * publish minutes before `npm view` and `npm install` find it, so an
222
- * install straight after fails with ETARGET or ERESOLVE.
238
+ * install straight after fails with ETARGET or ERESOLVE. The wait ends when
239
+ * every version is served or the registry fails (#4271), with a progress
240
+ * line about once a minute. `registryWait` caps it only when declared.
223
241
  */
224
242
  const served = async (ctx, pkgs) => {
225
- const wait = (decl.registryWait ?? NPM_REGISTRY_WAIT_SECONDS) * 1000;
243
+ const cap = decl.registryWait === undefined ? undefined : decl.registryWait * 1000;
226
244
  const start = now();
245
+ let logged;
227
246
  let missing = pkgs;
228
247
  for (;;) {
229
248
  const still = [];
230
249
  for (const pkg of missing)
231
- if (!(await onRegistry(ctx, pkg)))
250
+ if (!(await probe(ctx, pkg)))
232
251
  still.push(pkg);
233
252
  missing = still;
234
253
  if (missing.length === 0)
235
254
  return;
236
255
  const names = missing.map((p) => `${p.name}@${p.version}`).join(", ");
237
- if (now() - start >= wait) {
238
- throw new PublishTargetError("publish-npm-not-served", `the registry did not serve ${names} within ${Math.round(wait / 1000)}s of the publish, so nothing was audited`, "Each package was published. Once npm serves them, run the publish again: it publishes nothing twice and audits again. `registryWait` sets the wait.");
256
+ const waited = now() - start;
257
+ if (cap !== undefined && waited >= cap) {
258
+ throw new PublishTargetError("publish-npm-not-served", `the registry did not serve ${names} within ${Math.round(cap / 1000)}s of the publish, so nothing was audited`, "Each package was published. Once npm serves them, run the publish again: it publishes nothing twice and audits again. `registryWait` sets the wait.");
259
+ }
260
+ if (logged === undefined || now() - logged >= NPM_REGISTRY_PROGRESS_MS) {
261
+ ctx.log(`waiting for the registry to serve ${names}${waited > 0 ? ` (${Math.round(waited / 1000)}s so far)` : ""}`);
262
+ logged = now();
239
263
  }
240
- ctx.log(`waiting for the registry to serve ${names}`);
241
264
  await sleep(NPM_REGISTRY_POLL_MS);
242
265
  }
243
266
  };
@@ -227,7 +227,32 @@ export interface ReleaseRecord {
227
227
  * deploy that was not made from a release.
228
228
  */
229
229
  releaseDigest?: string;
230
+ /**
231
+ * Optional: what `digest` names when it is not an artifact digest (#4274).
232
+ * Absent on a record whose digest is the artifact the deploy promoted, and on
233
+ * every record written before 0.124.35.
234
+ *
235
+ * - `plan`: the component published nothing, and the digest is its plan
236
+ * digest, the one its approval bound (`pr-apply`).
237
+ * - `deploy-input`: the component published nothing and planned nothing, and
238
+ * the digest is its deploy-input digest (`componentInputDigests`,
239
+ * ../components/fan-out-inputs.ts).
240
+ * - `templates`: the digest of the templates the release records for the
241
+ * component (#4222, `releaseTemplatesDigest`).
242
+ *
243
+ * A `plan` or `deploy-input` record says the component applied; it names no
244
+ * artifact, so promote, rollback and redeploy never deploy it
245
+ * ({@link isApplyRecord}).
246
+ */
247
+ digestKind?: ReleaseDigestKind;
230
248
  }
249
+ /** What a release record's `digest` names when it is not an artifact digest (#4274). */
250
+ export type ReleaseDigestKind = "plan" | "deploy-input" | "templates";
251
+ /**
252
+ * Whether `record` only says its component applied (#4274): its digest is a
253
+ * plan or deploy-input digest, not one anything can be deployed from again.
254
+ */
255
+ export declare function isApplyRecord(record: Pick<ReleaseRecord, "digestKind">): boolean;
231
256
  /** Thrown by `appendReleaseRecord` when the record is missing a required field — a release record can never be recorded partially, since it is never editable afterward. */
232
257
  export declare class InvalidReleaseRecordError extends Error {
233
258
  readonly missing: string[];
@@ -270,6 +295,12 @@ export declare function resolveCiRun(env?: NodeJS.ProcessEnv): {
270
295
  runId: string;
271
296
  runOrigin: RunOrigin;
272
297
  } | undefined;
298
+ /** The run id `chant ci run` hands each step of a job it runs (#4275), the id its run index lists. */
299
+ export declare const CHANT_CI_RUN_ID_ENV = "CHANT_CI_RUN_ID";
300
+ /** The run's origin `chant ci run` hands each step with {@link CHANT_CI_RUN_ID_ENV}: always `chant`. */
301
+ export declare const CHANT_CI_RUN_FORGE_ENV = "CHANT_CI_RUN_FORGE";
302
+ /** The forge's run variables, which a step of a job the chant runner ran never gets (#4275). */
303
+ export declare const FORGE_RUN_ENV: readonly ["GITHUB_RUN_ID", "GITHUB_RUN_ATTEMPT", "GITHUB_JOB", "CI_PIPELINE_ID", "CI_PIPELINE_URL", "CI_JOB_ID"];
273
304
  /**
274
305
  * The CI run the environment names, as {@link resolveCiRun} has it, with the
275
306
  * job within the run and the run's attempt when the forge gives them
@@ -1 +1 @@
1
- {"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAwG,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAElJ,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAG1D,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAC9I,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;;;;;OASG;IACH,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,OAAO,CAAC;IACtD,gHAAgH;IAChH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mFAAmF;IACnF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+HAA+H;IAC/H,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,oGAAoG;AACpG,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD,8HAA8H;AAC9H,eAAO,MAAM,oBAAoB,aAAa,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,6FAA6F;IAC7F,EAAE,EAAE,MAAM,CAAC;IACX,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,oIAAoI;IACpI,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,SAAS,oBAAoB,EAAE,EAC5C,EAAE,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,gBAAgB,CAAA;CAAE,GAAG,SAAS,CAO/D;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,4FAA4F;IAC5F,OAAO,EAAE,CAAC,CAAC;IACX,6FAA6F;IAC7F,SAAS,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;;;OAOG;IACH,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,iOAAiO;IACjO,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,gOAAgO;IAChO,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,UAAU,CAAC;IACvB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,4KAA4K;AAC5K,qBAAa,yBAA0B,SAAQ,KAAK;aACtB,OAAO,EAAE,MAAM,EAAE;IAA7C,YAA4B,OAAO,EAAE,MAAM,EAAE,EAG5C;CACF;AAED,gIAAgI;AAChI,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,OAAO,CAAC,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,CAAC,EAAE,MAAM,EACjB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAQ1C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAyBtH;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CActH;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,kBAAkB,EACzB,IAAI,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACtB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC,CASpD;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,aAAa,EAAE,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAS1D;AAED;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEtF;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CASvF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,EAAE,CAE1F"}
1
+ {"version":3,"file":"release-ledger.d.ts","sourceRoot":"","sources":["../../src/lifecycle/release-ledger.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,13 @@ export function admissionOf(resolutions, at) {
53
53
  admission: { op: at.op, gate: at.gate, resolvedAt: bound.map((r) => r.timestamp).sort().at(-1) },
54
54
  };
55
55
  }
56
+ /**
57
+ * Whether `record` only says its component applied (#4274): its digest is a
58
+ * plan or deploy-input digest, not one anything can be deployed from again.
59
+ */
60
+ export function isApplyRecord(record) {
61
+ return record.digestKind === "plan" || record.digestKind === "deploy-input";
62
+ }
56
63
  /** Thrown by `appendReleaseRecord` when the record is missing a required field — a release record can never be recorded partially, since it is never editable afterward. */
57
64
  export class InvalidReleaseRecordError extends Error {
58
65
  constructor(missing) {
@@ -123,8 +130,19 @@ export function resolveCiRun(env = process.env) {
123
130
  },
124
131
  };
125
132
  }
133
+ // #4275: a step of a job the chant runner ran. The forge branches come first, and the runner
134
+ // strips the forge's run variables from its steps, so neither kind of job is taken for the other.
135
+ if (env[CHANT_CI_RUN_ID_ENV] && env[CHANT_CI_RUN_FORGE_ENV] === "chant") {
136
+ return { runId: env[CHANT_CI_RUN_ID_ENV], runOrigin: { forge: "chant" } };
137
+ }
126
138
  return undefined;
127
139
  }
140
+ /** The run id `chant ci run` hands each step of a job it runs (#4275), the id its run index lists. */
141
+ export const CHANT_CI_RUN_ID_ENV = "CHANT_CI_RUN_ID";
142
+ /** The run's origin `chant ci run` hands each step with {@link CHANT_CI_RUN_ID_ENV}: always `chant`. */
143
+ export const CHANT_CI_RUN_FORGE_ENV = "CHANT_CI_RUN_FORGE";
144
+ /** The forge's run variables, which a step of a job the chant runner ran never gets (#4275). */
145
+ export const FORGE_RUN_ENV = ["GITHUB_RUN_ID", "GITHUB_RUN_ATTEMPT", "GITHUB_JOB", "CI_PIPELINE_ID", "CI_PIPELINE_URL", "CI_JOB_ID"];
128
146
  /**
129
147
  * The CI run the environment names, as {@link resolveCiRun} has it, with the
130
148
  * job within the run and the run's attempt when the forge gives them
@@ -136,7 +154,7 @@ export function resolveCiJob(env = process.env) {
136
154
  if (!ci)
137
155
  return undefined;
138
156
  const github = ci.runOrigin.forge === "github";
139
- const jobId = github ? env.GITHUB_JOB : env.CI_JOB_ID;
157
+ const jobId = github ? env.GITHUB_JOB : ci.runOrigin.forge === "gitlab" ? env.CI_JOB_ID : undefined;
140
158
  const attempt = github ? Number(env.GITHUB_RUN_ATTEMPT) : NaN;
141
159
  return {
142
160
  runId: ci.runId,
@@ -361,7 +361,9 @@ export interface CrossEnvComparison {
361
361
  * environments legitimately render to different bytes, so cross-environment
362
362
  * "is prod running what staging tested" joins on the input side while
363
363
  * `digest` proves the exact bytes each cluster got. Records without it
364
- * compare on `digest` exactly as before.
364
+ * compare on `digest` exactly as before. An apply record (#4274) compares
365
+ * on its `gitSha`, since its plan or deploy-input digest takes in the
366
+ * environment and so differs between any two.
365
367
  */
366
368
  same: boolean;
367
369
  /** The identities `same` was decided on (`inputDigest ?? digest` per side), when both sides had one and they differ from the digests shown. */
@@ -377,6 +379,8 @@ export interface CrossEnvComparison {
377
379
  */
378
380
  mixedDigestForms?: true;
379
381
  }
382
+ /** What two environments' records of a component are compared on: the input side when there is one, the commit for an apply (#4274). */
383
+ export declare function comparableIdentity(record: ReleaseRecord): string;
380
384
  /** Compare the latest recorded digest for `component` between two environments' release records. */
381
385
  export declare function compareAcrossEnvironments(component: string, envA: {
382
386
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAqC,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,+IAA+I;IAC/I,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,gDAAgD;IAChD,cAAc,EAAE,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9E,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D;;;;;OAKG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,uBAAuB,CAAC;IACpC;;;;;OAKG;IACH,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CACjE;AAED,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,4GAA4G;IAC5G,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,qBAAqB;IACpC,4FAA4F;IAC5F,IAAI,EAAE,OAAO,CAAC;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,8HAA8H;IAC9H,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,qCAAqC;IACrC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5C;oFACgF;IAChF,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,YAAY,EAAE,CAAC;IAC5B;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB;aAAK,MAAM,EAAE,QAAQ;aAAE,MAAM,EAAE,QAAQ;CAAW,CAAC;AAExF,qDAAqD;AACrD,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,EAAE,YAAY,GAAG,WAAW,CAAC;IACjC,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA+BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAAG,SAAS,EACpD,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,GAC7C,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CA2BpC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;AAEhE,4HAA4H;AAC5H,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CAGvF;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;CACpB;AA2DD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,SAAS,EACb,WAAW,CAAC,EAAE,eAAe,EAC7B,IAAI,CAAC,EAAE;IACL;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CAC5C,GACA,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAyEpC;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,aAAa,EAAE,EACxB,IAAI,CAAC,EAAE;IACL,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAClD,2DAA2D;IAC3D,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC/C,+MAA+M;IAC/M,oBAAoB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;IACxD,6KAA6K;IAC7K,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,GACA,kBAAkB,EAAE,CA4EtB;AA+DD;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;;;;;;OAWG;IACH,IAAI,EAAE,OAAO,CAAC;IACd,+IAA+I;IAC/I,UAAU,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,IAAI,CAAC;CACzB;AAED,wIAAwI;AACxI,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,MAAM,CAEhE;AAED,oGAAoG;AACpG,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,EAChD,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,GAC/C,kBAAkB,CAkBpB"}
@@ -40,7 +40,7 @@
40
40
  * (`buildIsInBothEnvs`) is the query the epic actually asks for ("which
41
41
  * build is in prod, and is it the one tested in staging").
42
42
  */
43
- import { latestPerComponent } from "./release-ledger.js";
43
+ import { isApplyRecord, latestPerComponent } from "./release-ledger.js";
44
44
  import { isLegacyContentDigest } from "./legacy-digest.js";
45
45
  import { unobservedReasonText } from "../observation.js";
46
46
  /**
@@ -396,7 +396,8 @@ function notBefore(since, recordedAt) {
396
396
  */
397
397
  function contradictsRecord(recorded, evidence) {
398
398
  for (const id of evidence.identities ?? []) {
399
- if (id.digest !== undefined) {
399
+ // #4274: an apply's digest is a plan or deploy-input digest, which no live resource reports.
400
+ if (id.digest !== undefined && !isApplyRecord(recorded)) {
400
401
  const matches = sameDigest(id.digest, recorded.digest) ||
401
402
  (recorded.inputDigest !== undefined && sameDigest(id.digest, recorded.inputDigest));
402
403
  if (!matches)
@@ -425,13 +426,17 @@ function contradictsRecord(recorded, evidence) {
425
426
  return "live configuration has drifted since";
426
427
  return undefined;
427
428
  }
429
+ /** What two environments' records of a component are compared on: the input side when there is one, the commit for an apply (#4274). */
430
+ export function comparableIdentity(record) {
431
+ return isApplyRecord(record) ? `git:${record.gitSha}` : record.inputDigest ?? record.digest;
432
+ }
428
433
  /** Compare the latest recorded digest for `component` between two environments' release records. */
429
434
  export function compareAcrossEnvironments(component, envA, envB) {
430
435
  const latestA = latestPerComponent(envA.records).get(component);
431
436
  const latestB = latestPerComponent(envB.records).get(component);
432
- const idA = latestA ? latestA.inputDigest ?? latestA.digest : undefined;
433
- const idB = latestB ? latestB.inputDigest ?? latestB.digest : undefined;
434
- const comparedOnInputs = (latestA?.inputDigest ?? latestB?.inputDigest) !== undefined;
437
+ const idA = latestA ? comparableIdentity(latestA) : undefined;
438
+ const idB = latestB ? comparableIdentity(latestB) : undefined;
439
+ const comparedOnInputs = (latestA !== undefined && idA !== latestA.digest) || (latestB !== undefined && idB !== latestB.digest);
435
440
  return {
436
441
  component,
437
442
  envA: envA.name,
@@ -88,4 +88,22 @@ export declare function zeroResourcesWarning(lexicon: string, environment: strin
88
88
  resources: Record<string, unknown>;
89
89
  unobserved: Record<string, unknown>;
90
90
  }): string | undefined;
91
+ /**
92
+ * Run `run` with `environment`'s declared endpoint applied, as
93
+ * {@link applyLiveEndpoint} applies it to a `--live` read, and restored after
94
+ * (#4281). The component plan and apply paths (`components pr-plan`,
95
+ * `pr-apply`, `pr-record`, `fan-out`, `promote`, `rollback`, `redeploy` and
96
+ * `chant run --components`) run capabilities that honor the same ambient vars:
97
+ * azure's `arm-deploy` reads `AZURE_ENDPOINT_URL`, gcp's `gcp-apply`
98
+ * `GCP_ENDPOINT_URL`, aws's `cfn-deploy` `AWS_ENDPOINT_URL`. Without this, a
99
+ * plan for an environment declared against an emulator went to the real cloud
100
+ * unless the shell exported the var by hand.
101
+ *
102
+ * `lexicons` is called only when the environment declares an endpoint, so a
103
+ * caller that has to load its plugins pays for that only then.
104
+ */
105
+ export declare function withEnvironmentEndpoint<T>(environments: EnvironmentDeclaration[] | undefined, environment: string, lexicons: () => Promise<readonly EndpointLexicon[]> | readonly EndpointLexicon[], run: () => Promise<T>, options?: {
106
+ warn?: (message: string) => void;
107
+ env?: NodeJS.ProcessEnv;
108
+ }): Promise<T>;
91
109
  //# sourceMappingURL=live-endpoint.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"live-endpoint.d.ts","sourceRoot":"","sources":["../src/live-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEjG;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAErE;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AACD,yHAAyH;AACzH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAsCjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpF,MAAM,GAAG,SAAS,CAKpB"}
1
+ {"version":3,"file":"live-endpoint.d.ts","sourceRoot":"","sources":["../src/live-endpoint.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAuB,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAgC,KAAK,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEjG;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAErE;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,mBAAmB,CAAC;CAChC;AACD,yHAAyH;AACzH,MAAM,WAAW,eAAe;IAC9B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,SAAS,eAAe,EAAE,EACpC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,eAAe,CAsCjB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpF,MAAM,GAAG,SAAS,CAKpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,uBAAuB,CAAC,CAAC,EAC7C,YAAY,EAAE,sBAAsB,EAAE,GAAG,SAAS,EAClD,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,eAAe,EAAE,CAAC,GAAG,SAAS,eAAe,EAAE,EAChF,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACrB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;CAAO,GAC1E,OAAO,CAAC,CAAC,CAAC,CASZ"}
@@ -111,3 +111,30 @@ export function zeroResourcesWarning(lexicon, environment, declaredCount, observ
111
111
  return undefined;
112
112
  return `${lexicon}: 0 live resources for env "${environment}" (${declaredCount} declared) — check the endpoint/credentials`;
113
113
  }
114
+ /**
115
+ * Run `run` with `environment`'s declared endpoint applied, as
116
+ * {@link applyLiveEndpoint} applies it to a `--live` read, and restored after
117
+ * (#4281). The component plan and apply paths (`components pr-plan`,
118
+ * `pr-apply`, `pr-record`, `fan-out`, `promote`, `rollback`, `redeploy` and
119
+ * `chant run --components`) run capabilities that honor the same ambient vars:
120
+ * azure's `arm-deploy` reads `AZURE_ENDPOINT_URL`, gcp's `gcp-apply`
121
+ * `GCP_ENDPOINT_URL`, aws's `cfn-deploy` `AWS_ENDPOINT_URL`. Without this, a
122
+ * plan for an environment declared against an emulator went to the real cloud
123
+ * unless the shell exported the var by hand.
124
+ *
125
+ * `lexicons` is called only when the environment declares an endpoint, so a
126
+ * caller that has to load its plugins pays for that only then.
127
+ */
128
+ export async function withEnvironmentEndpoint(environments, environment, lexicons, run, options = {}) {
129
+ if (!environmentEndpoint(environments, environment))
130
+ return run();
131
+ const applied = applyLiveEndpoint(environments, environment, await lexicons(), options.env);
132
+ if (applied.notice)
133
+ options.warn?.(applied.notice);
134
+ try {
135
+ return await run();
136
+ }
137
+ finally {
138
+ applied.restore();
139
+ }
140
+ }