@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.
- package/dist/cli/component-endpoint.d.ts +20 -0
- package/dist/cli/component-endpoint.d.ts.map +1 -0
- package/dist/cli/component-endpoint.js +36 -0
- package/dist/cli/handlers/fan-out.d.ts.map +1 -1
- package/dist/cli/handlers/fan-out.js +10 -1
- package/dist/cli/handlers/pr.d.ts.map +1 -1
- package/dist/cli/handlers/pr.js +11 -5
- package/dist/cli/handlers/promote.d.ts.map +1 -1
- package/dist/cli/handlers/promote.js +7 -2
- package/dist/cli/handlers/run.d.ts +4 -1
- package/dist/cli/handlers/run.d.ts.map +1 -1
- package/dist/cli/handlers/run.js +17 -6
- package/dist/components/auto-release.d.ts +35 -3
- package/dist/components/auto-release.d.ts.map +1 -1
- package/dist/components/auto-release.js +29 -2
- package/dist/components/cli-support.d.ts +2 -0
- package/dist/components/cli-support.d.ts.map +1 -1
- package/dist/components/cli-support.js +2 -0
- package/dist/components/deploy-units.d.ts.map +1 -1
- package/dist/components/deploy-units.js +5 -0
- package/dist/components/promote.d.ts.map +1 -1
- package/dist/components/promote.js +39 -16
- package/dist/lifecycle/__fixtures__/publish-fakes.d.ts.map +1 -1
- package/dist/lifecycle/__fixtures__/publish-fakes.js +6 -1
- package/dist/lifecycle/publish-declaration.d.ts.map +1 -1
- package/dist/lifecycle/publish-declaration.js +4 -3
- package/dist/lifecycle/publish-npm.d.ts +2 -2
- package/dist/lifecycle/publish-npm.d.ts.map +1 -1
- package/dist/lifecycle/publish-npm.js +31 -8
- package/dist/lifecycle/release-ledger.d.ts +31 -0
- package/dist/lifecycle/release-ledger.d.ts.map +1 -1
- package/dist/lifecycle/release-ledger.js +19 -1
- package/dist/lifecycle/status.d.ts +5 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/status.js +10 -5
- package/dist/live-endpoint.d.ts +18 -0
- package/dist/live-endpoint.d.ts.map +1 -1
- package/dist/live-endpoint.js +27 -0
- package/dist/wave-runtime.mjs +192 -192
- package/dist/workspace/ci-run.d.ts +7 -0
- package/dist/workspace/ci-run.d.ts.map +1 -1
- package/dist/workspace/ci-run.js +21 -3
- package/dist/workspace/status.d.ts +3 -1
- package/dist/workspace/status.d.ts.map +1 -1
- package/dist/workspace/status.js +3 -2
- package/dist/workspace/status.schema.json +1 -0
- package/package.json +1 -1
- package/src/cli/component-endpoint.ts +43 -0
- package/src/cli/handlers/fan-out.test.ts +10 -0
- package/src/cli/handlers/fan-out.ts +12 -0
- package/src/cli/handlers/pr-endpoint.test.ts +169 -0
- package/src/cli/handlers/pr.ts +12 -5
- package/src/cli/handlers/promote.ts +16 -2
- package/src/cli/handlers/run.test.ts +2 -1
- package/src/cli/handlers/run.ts +16 -5
- package/src/components/auto-release-infra.test.ts +131 -0
- package/src/components/auto-release.test.ts +40 -1
- package/src/components/auto-release.ts +50 -4
- package/src/components/cli-support.ts +4 -0
- package/src/components/deploy-units.ts +5 -0
- package/src/components/promote.test.ts +39 -0
- package/src/components/promote.ts +38 -14
- package/src/lifecycle/__fixtures__/publish-fakes.ts +6 -1
- package/src/lifecycle/publish-declaration.ts +4 -3
- package/src/lifecycle/publish-npm.ts +33 -8
- package/src/lifecycle/publish-targets.test.ts +36 -3
- package/src/lifecycle/release-ledger.ts +42 -1
- package/src/lifecycle/status.test.ts +19 -0
- package/src/lifecycle/status.ts +14 -6
- package/src/live-endpoint.ts +31 -0
- package/src/workspace/ci-run.test.ts +26 -0
- package/src/workspace/ci-run.ts +20 -3
- package/src/workspace/status.schema.json +1 -0
- 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
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
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
|
|
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
|
|
269
|
-
if (
|
|
270
|
-
return
|
|
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":"AAAA;;;;;;;GAOG;AAUH,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,0EAA0E;IAC1E,QAAQ,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IAChF,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,0FAA0F;AAC1F,wBAAsB,iBAAiB,CAAC,KAAK,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAmE3H;AAED,gGAAgG;AAChG,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,SAAgB,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAqB7G;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;CACpF;AAED,8EAA8E;AAC9E,eAAO,MAAM,mBAAmB,QAAS,MAAM,WAA2B,CAAC;AAE3E,oCAAoC;AACpC,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAGhE;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI,CAEhF;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,
|
|
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 (
|
|
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;;;;;;;;;;;;
|
|
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
|
-
*
|
|
61
|
-
* published before installing them to audit (#4244). A
|
|
62
|
-
* publish before it serves it.
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
|
|
238
|
-
|
|
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":"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
|
|
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
|
package/dist/lifecycle/status.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
433
|
-
const idB = latestB ? latestB
|
|
434
|
-
const comparedOnInputs = (latestA
|
|
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,
|
package/dist/live-endpoint.d.ts
CHANGED
|
@@ -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"}
|
package/dist/live-endpoint.js
CHANGED
|
@@ -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
|
+
}
|