Skip to content

Publish (manual)

Publish (manual) #47

Workflow file for this run

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