Skip to content

Commit bfefd1e

Browse files
committed
fix(release): retry npm publication probes
1 parent c1d991a commit bfefd1e

2 files changed

Lines changed: 48 additions & 7 deletions

File tree

npm/package.test.mjs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,38 @@ else process.exitCode = 1;
121121
await rm(workspace, { recursive: true, force: true });
122122
}
123123
});
124+
125+
test("publication verification retries transient registry probe failures", async () => {
126+
const workspace = await mkdtemp(join(tmpdir(), "gitcontribute-publication-retry-"));
127+
try {
128+
const client = join(workspace, "registry-client");
129+
const state = join(workspace, "attempts");
130+
await writeFile(client, `#!/usr/bin/env node
131+
const fs = require("node:fs");
132+
const count = fs.existsSync(process.env.GITCONTRIBUTE_TEST_ATTEMPTS) ? Number(fs.readFileSync(process.env.GITCONTRIBUTE_TEST_ATTEMPTS, "utf8")) : 0;
133+
fs.writeFileSync(process.env.GITCONTRIBUTE_TEST_ATTEMPTS, String(count + 1));
134+
if (count === 0) process.exitCode = 1;
135+
else if (process.argv[2] === "view" && process.argv[4] === "dist-tags.latest") process.stdout.write('"1.2.3"\\n');
136+
else if (process.argv[2] === "view" && process.argv[3] === "gitcontribute@1.2.3" && process.argv[4] === "version") process.stdout.write('"1.2.3"\\n');
137+
else if (process.argv[2] === "--yes") process.stdout.write('{"version":"1.2.3"}\\n');
138+
else process.exitCode = 1;
139+
`);
140+
await chmod(client, 0o755);
141+
142+
const result = spawnSync(process.execPath, [join(root, "scripts", "verify-npm-publication.mjs"), "1.2.3"], {
143+
encoding: "utf8",
144+
env: {
145+
...process.env,
146+
GITCONTRIBUTE_NPM_COMMAND: client,
147+
GITCONTRIBUTE_NPX_COMMAND: client,
148+
GITCONTRIBUTE_NPM_PUBLICATION_ATTEMPTS: "2",
149+
GITCONTRIBUTE_NPM_PUBLICATION_DELAY_MS: "1",
150+
GITCONTRIBUTE_TEST_ATTEMPTS: state,
151+
},
152+
});
153+
assert.equal(result.status, 0, result.stderr || result.stdout);
154+
assert.equal(await readFile(state, "utf8"), "4");
155+
} finally {
156+
await rm(workspace, { recursive: true, force: true });
157+
}
158+
});

scripts/verify-npm-publication.mjs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ const npm = process.env.GITCONTRIBUTE_NPM_COMMAND || "npm";
1010
const npx = process.env.GITCONTRIBUTE_NPX_COMMAND || "npx";
1111

1212
for (let attempt = 1; attempt <= attempts; attempt += 1) {
13-
const latest = await output(npm, ["view", "gitcontribute", "dist-tags.latest", "--json", "--prefer-online", `--registry=${registry}`]);
14-
const published = await output(npm, ["view", `gitcontribute@${expectedVersion}`, "version", "--json", "--prefer-online", `--registry=${registry}`]);
15-
if (jsonString(latest) === expectedVersion && jsonString(published) === expectedVersion) {
16-
const metadata = await output(npx, ["--yes", "--prefer-online", "gitcontribute@latest", "metadata", "--json"]);
17-
if (JSON.parse(metadata).version === expectedVersion) {
18-
console.log(`npm release ${expectedVersion} is publicly discoverable`);
19-
process.exit(0);
13+
try {
14+
const latest = await output(npm, ["view", "gitcontribute", "dist-tags.latest", "--json", "--prefer-online", `--registry=${registry}`]);
15+
const published = await output(npm, ["view", `gitcontribute@${expectedVersion}`, "version", "--json", "--prefer-online", `--registry=${registry}`]);
16+
if (jsonString(latest) === expectedVersion && jsonString(published) === expectedVersion) {
17+
const metadata = await output(npx, ["--yes", "--prefer-online", "gitcontribute@latest", "metadata", "--json"]);
18+
if (JSON.parse(metadata).version === expectedVersion) {
19+
console.log(`npm release ${expectedVersion} is publicly discoverable`);
20+
process.exit(0);
21+
}
2022
}
23+
} catch {
24+
// Registry propagation and fresh npx resolution are expected to be
25+
// transient immediately after publication. The bounded retry loop owns
26+
// those probes as one operation.
2127
}
2228
if (attempt < attempts) await new Promise((resolve) => setTimeout(resolve, delayMS));
2329
}

0 commit comments

Comments
 (0)