Publish (manual) #47
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: Publish (manual) | |
| on: | |
| workflow_dispatch: | |
| concurrency: | |
| group: publish-npm | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| id-token: write | |
| env: | |
| READINESS_CONTRACT_ARTIFACT_NAME: publish-readiness-contract | |
| READINESS_DIAGNOSTICS_ARTIFACT_NAME: publish-readiness-diagnostics | |
| READINESS_CONTRACT_DIR: tmp/publish-contracts/readiness | |
| READINESS_DOWNLOAD_ROOT: tmp/downloaded-contracts/readiness | |
| ARTIFACTS_CONTRACT_ARTIFACT_NAME: publish-artifacts-contract | |
| ARTIFACTS_DIAGNOSTICS_ARTIFACT_NAME: publish-artifacts-diagnostics | |
| ARTIFACTS_CONTRACT_DIR: tmp/publish-contracts/artifacts | |
| ARTIFACTS_DOWNLOAD_ROOT: tmp/downloaded-contracts/artifacts | |
| jobs: | |
| verify_publish_readiness: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| should_publish: ${{ steps.plan.outputs.should_publish }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Fail unless running from main | |
| shell: bash | |
| run: | | |
| # npm Trusted Publishing (OIDC) is typically configured against the workflow file on the default branch. | |
| # Running this workflow from a feature branch can fail with ENEEDAUTH even if id-token is available. | |
| if [ "${GITHUB_REF}" != "refs/heads/main" ]; then | |
| echo "This publish workflow must be run from the main branch." | |
| echo "Current ref: ${GITHUB_REF}" | |
| exit 1 | |
| fi | |
| - name: Setup publish readiness runtime | |
| uses: ./.github/actions/setup-publish-runtime | |
| with: | |
| use-pnpm: "true" | |
| install-dependencies: "true" | |
| update-npm: "true" | |
| required-commands: "node,npm,pnpm" | |
| warn-min-npm-version: "11.5.1" | |
| label: "verify-publish-readiness" | |
| - name: Verify publish readiness | |
| id: plan | |
| run: node ./scripts/publish-plan.mjs --github-output "$GITHUB_OUTPUT" --output-dir "${READINESS_CONTRACT_DIR}" | |
| - name: Upload publish readiness contract | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.READINESS_CONTRACT_ARTIFACT_NAME }} | |
| path: ${{ env.READINESS_CONTRACT_DIR }} | |
| - name: Upload publish readiness diagnostics | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.READINESS_DIAGNOSTICS_ARTIFACT_NAME }} | |
| path: tmp/runtime-checks | |
| build_publish_artifacts: | |
| needs: verify_publish_readiness | |
| if: ${{ needs.verify_publish_readiness.outputs.should_publish == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup artifact build runtime | |
| uses: ./.github/actions/setup-publish-runtime | |
| with: | |
| use-pnpm: "true" | |
| install-dependencies: "true" | |
| update-npm: "false" | |
| required-commands: "node,npm,pnpm" | |
| warn-min-npm-version: "11.5.1" | |
| label: "build-publish-artifacts" | |
| - name: Download publish readiness contract | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ env.READINESS_CONTRACT_ARTIFACT_NAME }} | |
| path: ${{ env.READINESS_DOWNLOAD_ROOT }} | |
| - name: Verify downloaded publish readiness contract | |
| id: readiness_contract | |
| run: | | |
| node ./scripts/verify-publish-contract.mjs \ | |
| --contract "readiness" \ | |
| --artifact-root "${READINESS_DOWNLOAD_ROOT}" \ | |
| --label "build-publish-readiness-contract" \ | |
| --output "tmp/runtime-checks/build-publish-readiness-contract.json" \ | |
| --github-output "$GITHUB_OUTPUT" | |
| - name: Build publish artifacts | |
| run: | | |
| node ./scripts/build-publish-artifacts.mjs \ | |
| --plan "${{ steps.readiness_contract.outputs.publish_plan_path }}" \ | |
| --output-dir "${ARTIFACTS_CONTRACT_DIR}" | |
| - name: Upload publish artifact contract | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACTS_CONTRACT_ARTIFACT_NAME }} | |
| path: ${{ env.ARTIFACTS_CONTRACT_DIR }} | |
| - name: Upload publish artifact diagnostics | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACTS_DIAGNOSTICS_ARTIFACT_NAME }} | |
| path: tmp/runtime-checks | |
| actual_publish: | |
| needs: [verify_publish_readiness, build_publish_artifacts] | |
| if: ${{ needs.verify_publish_readiness.outputs.should_publish == 'true' }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Setup actual publish runtime | |
| uses: ./.github/actions/setup-publish-runtime | |
| with: | |
| use-pnpm: "false" | |
| install-dependencies: "false" | |
| update-npm: "true" | |
| required-commands: "node,npm,git,gh" | |
| min-npm-version: "11.5.1" | |
| label: "actual-publish" | |
| - name: Download built publish artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: ${{ env.ARTIFACTS_CONTRACT_ARTIFACT_NAME }} | |
| path: ${{ env.ARTIFACTS_DOWNLOAD_ROOT }} | |
| - name: Verify downloaded publish artifact contract | |
| id: artifacts_contract | |
| run: | | |
| node ./scripts/verify-publish-contract.mjs \ | |
| --contract "artifacts" \ | |
| --artifact-root "${ARTIFACTS_DOWNLOAD_ROOT}" \ | |
| --label "actual-publish-artifacts-contract" \ | |
| --output "tmp/runtime-checks/actual-publish-artifacts-contract.json" \ | |
| --github-output "$GITHUB_OUTPUT" | |
| - name: Configure git identity for tags | |
| shell: bash | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| - name: OIDC diagnostics | |
| shell: bash | |
| run: | | |
| echo "RAWSQL_PUBLISH_AUTH=oidc" | |
| echo "NPM_CONFIG_PROVENANCE=true" | |
| echo "ACTIONS_ID_TOKEN_REQUEST_URL=${ACTIONS_ID_TOKEN_REQUEST_URL:+(set)}" | |
| echo "ACTIONS_ID_TOKEN_REQUEST_TOKEN=${ACTIONS_ID_TOKEN_REQUEST_TOKEN:+(set)}" | |
| echo "NODE_AUTH_TOKEN=${NODE_AUTH_TOKEN:+(set)}" | |
| npm --version | |
| npm config get registry | |
| npm config get provenance || true | |
| # OIDC Trusted Publishing should not run with token auth. Drop NODE_AUTH_TOKEN for this check. | |
| env -u NODE_AUTH_TOKEN npm whoami && echo "npm auth: token/session is active (unexpected for pure OIDC)" || echo "npm auth: no token/session (expected for OIDC)" | |
| - name: Publish to npm (OIDC-compatible), tag, and create GitHub Releases | |
| shell: bash | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| NPM_CONFIG_PROVENANCE: "true" | |
| RAWSQL_PUBLISH_AUTH: "oidc" | |
| RAWSQL_PUBLISH_OIDC_FALLBACK_TO_TOKEN: "1" | |
| RAWSQL_PUBLISH_MANIFEST: ${{ steps.artifacts_contract.outputs.publish_manifest_path }} | |
| run: | | |
| # Preserve the existing npm token under a separate name so ci-publish.mjs can use it only for explicit retries. | |
| # Then drop NODE_AUTH_TOKEN from the live environment to keep the primary publish path on OIDC. | |
| RAWSQL_PUBLISH_FALLBACK_TOKEN="${NODE_AUTH_TOKEN:-}" env -u NODE_AUTH_TOKEN node ./scripts/ci-publish.mjs | |
| - name: Upload actual publish diagnostics | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: actual-publish-diagnostics | |
| path: tmp/runtime-checks |