From 1049edb17defc6e387bead141fec11127691cc00 Mon Sep 17 00:00:00 2001 From: David J Parrott Date: Tue, 15 Sep 2026 18:24:10 -0400 Subject: [PATCH] fix(opp-bundles): publish the cargo crate before npm and report every publish failure The bundler published the two npm packages first and the cargo crate last, and the first throw ended the run. The two registries share no credential: the crate publishes to CodeArtifact over the OIDC-minted registry token, the npm packages publish to npmjs.org with NPM_TOKEN. Since 2026-09-14 the npm publish fails (E404 on PUT, an auth failure), and every master run since has died before reaching the cargo step, so wire-opp-solana-models never advanced past 1.0.50 even though nothing on the cargo side was broken. Consumers of the SYNDICATE_LIQ / LIQ_YIELD / DESYNDICATE_LIQ types added in #609 (wire-solana #523, wire-tools-ts #98) are blocked on a credential the crate never uses. handlePublish now publishes the cargo crate first, then each npm package, runs every publish to completion, and throws one error carrying all the failures as its cause. A re-run after the npm side is repaired heals npm without re-publishing the crate: publishCargoCrate already treats a duplicate version as success. Verified: tsc -b clean; protobuf-bundler jest 34/34. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01CNDguHHWTwn1UBejDiTAGa Change-Id: Ie6974d6220e088f4d711ed01d718fb7019f19481 --- .../protobuf-bundler/src/commands/bundle.ts | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/libraries/opp/tools/protobuf-bundler/src/commands/bundle.ts b/libraries/opp/tools/protobuf-bundler/src/commands/bundle.ts index db1ee94b78..5073f7cd05 100644 --- a/libraries/opp/tools/protobuf-bundler/src/commands/bundle.ts +++ b/libraries/opp/tools/protobuf-bundler/src/commands/bundle.ts @@ -442,21 +442,56 @@ function publishCargoCrate(dir: string): void { } } +/** + * Publish every publishable target, then fail if any publish failed. + * + * The registries are independent: the cargo crate publishes to CodeArtifact + * over the OIDC-minted registry token, the npm packages publish to npmjs.org + * with NPM_TOKEN. One registry's credential failing must not withhold the + * bundles the other registry would have accepted — every consumer of the + * generated types is blocked until its OWN registry carries the new version, + * and a re-run heals the registry that failed without re-publishing the one + * that succeeded (`publishCargoCrate` treats a duplicate version as success). + * So each publish runs to completion and the failures are reported together. + */ async function handlePublish( args: BundleArgs, baseOutputDir: string ): Promise { + const failures: Error[] = [] + const attempt = (label: string, publish: () => void): void => { + try { + publish() + } catch (err: any) { + log.error("Publish failed for %s: %s", label, err.message) + failures.push(err) + } + } + args.targets - .filter(t => PUBLISHABLE_TARGETS.includes(t)) + .filter(t => CARGO_PUBLISHABLE_TARGETS.includes(t)) .forEach(target => { - publishPackage(Path.join(baseOutputDir, target)) + attempt(`${target} (cargo)`, () => + publishCargoCrate(Path.join(baseOutputDir, target)) + ) }) args.targets - .filter(t => CARGO_PUBLISHABLE_TARGETS.includes(t)) + .filter(t => PUBLISHABLE_TARGETS.includes(t)) .forEach(target => { - publishCargoCrate(Path.join(baseOutputDir, target)) + attempt(`${target} (npm)`, () => + publishPackage(Path.join(baseOutputDir, target)) + ) }) + + if (failures.length > 0) { + throw new Error( + `${failures.length} of the publish steps failed: ${failures + .map(failure => failure.message) + .join("; ")}`, + { cause: failures } + ) + } } function copyDirExcluding(