From 860bb195846a9e184b260367d2f85502c674afd2 Mon Sep 17 00:00:00 2001 From: Lokesh Chandra Date: Wed, 5 Aug 2026 16:14:57 +0530 Subject: [PATCH] fix: split publish into siblings-then-bitgo passes Ticket: WCI-1818 --- .github/workflows/npmjs-release.yml | 49 ++++++++++++++++++++++------- .github/workflows/publish.yml | 27 +++++++++++++++- 2 files changed, 64 insertions(+), 12 deletions(-) diff --git a/.github/workflows/npmjs-release.yml b/.github/workflows/npmjs-release.yml index e9b19c51b8..a3052f167b 100644 --- a/.github/workflows/npmjs-release.yml +++ b/.github/workflows/npmjs-release.yml @@ -295,26 +295,53 @@ jobs: - name: Verify all packages exist on npm uses: ./.github/actions/verify-npm-packages - - name: Publish new version + # Version bump only — no publish. Separated from publishing (WCN-1818) so the + # two-phase publish below can run identically whether this step just bumped + # versions (normal path) or recovery-mode skipped it (rel/latest already + # holds the versions to resume from). + - name: Bump version if: ${{ inputs.dry-run == false && !inputs.recovery-mode }} run: | - yarn lerna publish --sign-git-tag --sign-git-commit --include-merged-tags --conventional-commits --conventional-graduate --yes + yarn lerna version --sign-git-tag --sign-git-commit --include-merged-tags --conventional-commits --conventional-graduate --yes + + # Two-phase publish (WCN-1818): bitgo's `prepack` script resolves its + # siblings from the registry, but a single combined `lerna publish` packs + # every package's lifecycle hooks before uploading any of them — so bitgo + # would try to resolve siblings that aren't live yet (this is what broke + # `npm install bitgo` for every consumer, WCI-1200). Hold bitgo back + # (private), publish siblings first, then restore and publish bitgo alone + # once its siblings are actually resolvable. Runs identically for the + # normal path (after the version bump above) and the recovery path (no + # preceding bump) — `from-package` only publishes what's missing from npm + # either way, so re-running is idempotent. + - name: Hold back bitgo umbrella for the siblings publish pass + if: inputs.dry-run == false + run: npx tsx ./scripts/set-umbrella-publishable.ts false + + - name: Publish siblings (pass 1) + if: inputs.dry-run == false + run: | + # `from-package` reads each package.json's `version`, queries npm, + # and publishes only versions missing from the registry. + yarn lerna publish from-package --yes env: NPM_CONFIG_PROVENANCE: true - # Tells bitgo's `prepack` script (scripts/generate-bitgo-shrinkwrap.ts) to - # actually generate npm-shrinkwrap.json — kept opt-in so a plain local - # `npm pack` doesn't force a network install of the full dependency tree. - BITGO_GENERATE_SHRINKWRAP: true - - name: Publish missing versions (recovery) - if: ${{ inputs.dry-run == false && inputs.recovery-mode }} + - name: Restore bitgo umbrella for its own publish pass + if: ${{ always() && inputs.dry-run == false }} + run: npx tsx ./scripts/set-umbrella-publishable.ts true + + - name: Publish bitgo (pass 2) + if: inputs.dry-run == false run: | - # `from-package` reads each package.json's `version`, queries npm, - # and publishes only versions missing from the registry. No bump, - # no tag, no git push. yarn lerna publish from-package --yes env: NPM_CONFIG_PROVENANCE: true + # Tells bitgo's `prepack` script (scripts/generate-bitgo-shrinkwrap.ts) to + # actually generate npm-shrinkwrap.json — kept opt-in so a plain local + # `npm pack` doesn't force a network install of the full dependency tree. + # Siblings published in the pass above are live on the registry by now, + # so resolution succeeds. BITGO_GENERATE_SHRINKWRAP: true - name: Verify recovery published the missing versions diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7f07d072f9..6cd3b47402 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -100,7 +100,16 @@ jobs: - name: Commit Local Changes run: git commit -am "Auto updated ${{ env.preid }} branch" --no-verify || echo "No changes to commit" - - name: Lerna Publish + # Two-phase publish (WCN-1818): bitgo's `prepack` script resolves its siblings + # from the registry, but a single combined `lerna publish` packs every + # package's lifecycle hooks before uploading any of them — so bitgo would + # try to resolve siblings that aren't live yet. Hold bitgo back (private), + # publish siblings first, then restore and publish bitgo alone once its + # siblings are actually resolvable. + - name: Hold back bitgo umbrella for the siblings publish pass + run: npx tsx ./scripts/set-umbrella-publishable.ts false + + - name: Lerna Publish (siblings) # In recovery mode a stuck package's Rekor conflict fails this step outright; let it # continue so Verify Publish below still gets a chance to bump+retry that package. continue-on-error: ${{ inputs.recovery-mode }} @@ -108,6 +117,22 @@ jobs: env: NPM_CONFIG_PROVENANCE: true + - name: Restore bitgo umbrella for its own publish pass + if: always() + run: npx tsx ./scripts/set-umbrella-publishable.ts true + + - name: Lerna Publish (bitgo) + # Siblings published above are now live on the registry, so bitgo's + # `prepack` script (scripts/generate-bitgo-shrinkwrap.ts) can resolve them + # for real. BITGO_GENERATE_SHRINKWRAP is set here (unlike historically on + # this workflow) so alpha/beta actually exercises shrinkwrap generation + # instead of silently no-oping on it. + continue-on-error: ${{ inputs.recovery-mode }} + run: yarn lerna publish from-package --preid ${{ env.preid }} --dist-tag ${{ env.preid }} --force-publish --yes --loglevel silly + env: + NPM_CONFIG_PROVENANCE: true + BITGO_GENERATE_SHRINKWRAP: true + - name: Verify Publish run: npx tsx ./scripts/verify-release.ts ${{ env.preid }} env: