Files
webstudio/packages/cli/scripts/release-smoke-registry.ts
Oleg Isonen 57d9ad14cd fix: Retry published CLI registry lookup (#6013)
## What changed

- Retry npm version and integrity resolution inside the CLI registry
smoke test.
- Keep retry timing injectable so the propagation race is covered by a
fast unit test.
- Preserve the final npm error when all registry attempts are exhausted.

## Why

CLI 0.286.0 was published successfully, but npm briefly exposed
integrity metadata while the exact version lookup still returned 404.
The post-publish smoke failed and the dependent docs publication job was
skipped.

The 0.286.0 documentation snapshot has been recovered directly on the
`docs` branch.

Ref #6007

## Verification

- [x] Regression test demonstrated failing before the implementation and
passing afterward
- [x] CLI registry/versioning tests: 3 passed
- [x] CLI typecheck
- [x] Formatting and diff checks
- [x] Documentation impact reviewed: no product-doc source change is
needed in this PR; the missed 0.286.0 snapshot was published separately
to `docs`
2026-08-05 22:03:26 +02:00

63 lines
1.6 KiB
TypeScript

export type ReleaseTarget = {
source: "local" | "registry";
version: string;
installSpec: string;
integrity?: string;
};
type ResolveRegistryTargetOptions = {
readNpmJson: (args: string[]) => Promise<unknown>;
attempts?: number;
delay?: () => Promise<void>;
};
const defaultDelay = () =>
new Promise<void>((resolve) => setTimeout(resolve, 10_000));
export const resolveRegistryTarget = async (
spec: string,
{
readNpmJson,
attempts = 30,
delay = defaultDelay,
}: ResolveRegistryTargetOptions
): Promise<ReleaseTarget> => {
let lastError: unknown;
for (let attempt = 1; attempt <= attempts; attempt += 1) {
try {
const version = await readNpmJson(["view", spec, "version", "--json"]);
const integrity = await readNpmJson([
"view",
spec,
"dist.integrity",
"--json",
]);
if (typeof version !== "string" || version.length === 0) {
throw new Error(`Could not resolve registry package ${spec}.`);
}
if (typeof integrity !== "string" || integrity.length === 0) {
throw new Error(
`Registry package webstudio@${version} has no integrity.`
);
}
return {
source: "registry",
version,
installSpec: `webstudio@${version}`,
integrity,
};
} catch (error) {
lastError = error;
if (attempt < attempts) {
await delay();
}
}
}
const message =
lastError instanceof Error ? lastError.message : String(lastError);
throw new Error(
`Could not resolve registry package ${spec} after ${attempts} attempts: ${message}`,
{ cause: lastError }
);
};