🧪 npm publish dry-run #1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: 🧪 npm publish dry-run | |
| # Cascade-owned — every npm-publishing repo carries the byte-identical copy. | |
| # Continuous validation of the RELEASE PATH between releases: a weekly cron | |
| # walks the same chain npm-publish.yml runs (checkout → setup-and-install → | |
| # build → scripts/fleet/npm-publish.mts --staged --dry-run), which packs the | |
| # tarball and validates the manifest without touching the registry. | |
| # | |
| # WHY: a publish leg can rot silently for months when nothing exercises it — | |
| # a package-manager pin that drops a subcommand, a stale firewall build that | |
| # can't parse the registry endpoint, a manifest that stopped packing. Those | |
| # only surface at release time, after the release markers are already cut, | |
| # where the recovery is a burned version. A weekly red run here is a bug | |
| # report; the same failure during a release is a burn. | |
| # | |
| # LEAST PRIVILEGE: no `npm-publish` environment and no `id-token: write`. A | |
| # dry run uploads nothing, so it must not be able to mint a publish token. | |
| on: | |
| schedule: | |
| # Weekly, Monday 09:17 UTC — offset from the top of the hour so the fleet | |
| # does not stampede the runner pool. | |
| - cron: '17 9 * * 1' | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: read | |
| # One validation at a time; a queued second run adds nothing. | |
| concurrency: | |
| group: ${{ github.workflow }} | |
| cancel-in-progress: false | |
| jobs: | |
| dry-run: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| env: | |
| # Socket Firewall + CLI auth for the sfw-wrapped setup + pnpm install — | |
| # sfw and socket-cli read SOCKET_API_KEY from the org-wide secret. | |
| SOCKET_API_KEY: ${{ secrets.SOCKET_API_TOKEN_FOR_CLI_AND_SFW }} | |
| steps: | |
| # First step must be the third-party actions/checkout (GitHub fetches it | |
| # independently) to populate the workspace so the LOCAL | |
| # ./.github/actions/* composite resolves. | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 (2026-05-15) | |
| with: | |
| fetch-depth: 1 | |
| # The bump derivation anchors on registry-latest + the last v-tag; | |
| # a tagless shallow checkout derives from zero on a repo whose | |
| # registry history is empty. | |
| fetch-tags: true | |
| persist-credentials: false | |
| - name: Setup + install | |
| uses: ./.github/actions/fleet/setup-and-install | |
| - name: Build | |
| run: pnpm run build | |
| # The same staged-publish leg the real workflow runs, with --dry-run: | |
| # packs every publishable package and validates its manifest, then | |
| # stops before the upload. No --bump: the dry run must never derive a | |
| # version or write a CHANGELOG. | |
| - name: Dry-run staged publish | |
| run: node scripts/fleet/npm-publish.mts --staged --dry-run |