impel-cli 0.20.63-canary.4 → 0.20.63-canary.6
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/package.json
CHANGED
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
// `publish-canary.yml` runs this in the working tree immediately before
|
|
5
5
|
// `pnpm pack`, after the test suite has run on the unmodified tree. It
|
|
6
6
|
// rewrites the brand DEFAULT in `src/runtimeBrand.js` in place: the channel
|
|
7
|
-
// literal becomes `canary
|
|
8
|
-
// become the canary row of CHANNEL_ORIGINS
|
|
9
|
-
// baked so the row has one source of truth
|
|
7
|
+
// literal becomes `canary`, the three production `defaultOrigin` literals
|
|
8
|
+
// become the canary row of CHANNEL_ORIGINS (read from the very module being
|
|
9
|
+
// baked so the row has one source of truth), and the CLI config namespace
|
|
10
|
+
// becomes `impel-canary` so stable and canary state never share files.
|
|
10
11
|
//
|
|
11
12
|
// It is a one-shot publish step, not a formatter: every literal it replaces
|
|
12
13
|
// must occur exactly once in its shipped form, a file that is already baked
|
|
@@ -51,6 +52,7 @@ async function main() {
|
|
|
51
52
|
const { CHANNEL_ORIGINS } = await importBrandModule(target, "before");
|
|
52
53
|
const rows = [
|
|
53
54
|
['channel: "stable",', CANARY_MARKER],
|
|
55
|
+
['configNamespace: "impel",', 'configNamespace: "impel-canary",'],
|
|
54
56
|
...["gateway", "sessions", "controlPlane"].map((column) => [
|
|
55
57
|
`defaultOrigin: ${JSON.stringify(CHANNEL_ORIGINS.stable[column])}`,
|
|
56
58
|
`defaultOrigin: ${JSON.stringify(CHANNEL_ORIGINS.canary[column])}`,
|
|
@@ -73,10 +75,13 @@ async function main() {
|
|
|
73
75
|
if (RUNTIME_BRAND.channel !== "canary" || mismatch) {
|
|
74
76
|
throw new Error(`baked DEFAULT is not the canary row (${mismatch || "channel"})`);
|
|
75
77
|
}
|
|
78
|
+
if (RUNTIME_BRAND.cli.configNamespace !== "impel-canary") {
|
|
79
|
+
throw new Error(`baked CLI config namespace is not isolated (${RUNTIME_BRAND.cli.configNamespace})`);
|
|
80
|
+
}
|
|
76
81
|
process.stdout.write(
|
|
77
82
|
`bake-canary-brand: ${target} now carries channel canary `
|
|
78
83
|
+ `(gateway ${RUNTIME_BRAND.gateway.defaultOrigin}, sessions ${RUNTIME_BRAND.sessions.defaultOrigin}, `
|
|
79
|
-
+ `controlPlane ${RUNTIME_BRAND.controlPlane.defaultOrigin})\n`,
|
|
84
|
+
+ `controlPlane ${RUNTIME_BRAND.controlPlane.defaultOrigin}, config ${RUNTIME_BRAND.cli.configNamespace})\n`,
|
|
80
85
|
);
|
|
81
86
|
} catch (error) {
|
|
82
87
|
fs.writeFileSync(target, original);
|
|
@@ -5,6 +5,15 @@ import { fileURLToPath } from "node:url";
|
|
|
5
5
|
|
|
6
6
|
const DIST_TAGS_URL = "https://registry.npmjs.org/-/package/impel-cli/dist-tags";
|
|
7
7
|
|
|
8
|
+
// npm accepts a version and returns success before every registry edge exposes
|
|
9
|
+
// its new dist-tag. The post-publish verifier therefore treats a stale canary
|
|
10
|
+
// tag as propagation, not proof that npm publish failed. Five minutes stays
|
|
11
|
+
// comfortably inside the publish job's 15-minute timeout.
|
|
12
|
+
const CANARY_TAG_VERIFY_ATTEMPTS = 20;
|
|
13
|
+
const CANARY_TAG_VERIFY_DELAY_MS = 15_000;
|
|
14
|
+
|
|
15
|
+
class CanaryDistTagMismatchError extends Error {}
|
|
16
|
+
|
|
8
17
|
export function assertCanaryDistTags({ beforeLatest, expectedCanary, tags }) {
|
|
9
18
|
const latest = tags.latest ?? "";
|
|
10
19
|
const canary = tags.canary ?? "";
|
|
@@ -15,11 +24,46 @@ export function assertCanaryDistTags({ beforeLatest, expectedCanary, tags }) {
|
|
|
15
24
|
);
|
|
16
25
|
}
|
|
17
26
|
if (canary !== expectedCanary) {
|
|
18
|
-
throw new
|
|
27
|
+
throw new CanaryDistTagMismatchError(
|
|
28
|
+
`dist-tags.canary is ${canary || "<none>"}, expected ${expectedCanary}.`,
|
|
29
|
+
);
|
|
19
30
|
}
|
|
20
31
|
return { latest, canary };
|
|
21
32
|
}
|
|
22
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Verify npm's public dist-tags after publish while allowing the canary tag to
|
|
36
|
+
* propagate. A moved `latest` remains an immediate failure: that is a release
|
|
37
|
+
* invariant violation, not ordinary registry propagation.
|
|
38
|
+
*/
|
|
39
|
+
export async function verifyCanaryDistTags({
|
|
40
|
+
beforeLatest,
|
|
41
|
+
expectedCanary,
|
|
42
|
+
readTags = readDistTags,
|
|
43
|
+
attempts = CANARY_TAG_VERIFY_ATTEMPTS,
|
|
44
|
+
delayMs = CANARY_TAG_VERIFY_DELAY_MS,
|
|
45
|
+
sleep = (milliseconds) => new Promise((resolve) => setTimeout(resolve, milliseconds)),
|
|
46
|
+
}) {
|
|
47
|
+
let lastObservedCanary = "";
|
|
48
|
+
let lastError;
|
|
49
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
50
|
+
const tags = await readTags({ bustCache: true });
|
|
51
|
+
try {
|
|
52
|
+
return assertCanaryDistTags({ beforeLatest, expectedCanary, tags });
|
|
53
|
+
} catch (error) {
|
|
54
|
+
if (!(error instanceof CanaryDistTagMismatchError)) throw error;
|
|
55
|
+
lastObservedCanary = tags.canary ?? "";
|
|
56
|
+
lastError = error;
|
|
57
|
+
if (attempt < attempts) await sleep(delayMs);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
throw new Error(
|
|
61
|
+
`npm accepted the canary publish but did not expose it after ${attempts} dist-tag checks: `
|
|
62
|
+
+ `${lastError?.message || `last dist-tags.canary was ${lastObservedCanary || "<none>"}.`} `
|
|
63
|
+
+ "This is registry propagation lag, not an unpublished tarball.",
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
23
67
|
async function readDistTags({ allowMissing, bustCache = false } = {}) {
|
|
24
68
|
const url = bustCache ? `${DIST_TAGS_URL}?t=${Date.now()}` : DIST_TAGS_URL;
|
|
25
69
|
let lastError;
|
|
@@ -67,8 +111,7 @@ async function main([command, ...args]) {
|
|
|
67
111
|
}
|
|
68
112
|
if (command === "assert-canary" && args.length === 2) {
|
|
69
113
|
const [expectedCanary, beforeLatest] = args;
|
|
70
|
-
const
|
|
71
|
-
const { latest } = assertCanaryDistTags({ expectedCanary, beforeLatest, tags });
|
|
114
|
+
const { latest } = await verifyCanaryDistTags({ expectedCanary, beforeLatest });
|
|
72
115
|
appendSummary([
|
|
73
116
|
"## Canary published",
|
|
74
117
|
"",
|
package/src/runtimeBrand.js
CHANGED