name: Publish npm package on: push: tags: ["v*"] workflow_dispatch: permissions: contents: read id-token: write concurrency: group: npm-release-${{ github.ref }} cancel-in-progress: false jobs: publish: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: 24 registry-url: https://registry.npmjs.org cache: npm - name: Validate release ref run: | test "${GITHUB_REF_TYPE}" = tag test "${GITHUB_REF_NAME}" = "v$(node -p 'require("./package.json").version')" - run: npm ci - run: npm run check - name: Publish immutable version to latest shell: bash run: | set -euo pipefail package="$(node -p 'require("./package.json").name')" version="$(node -p 'require("./package.json").version')" if npm view "${package}@${version}" version --json > /tmp/registry-version.json 2>/tmp/registry-error.txt; then node -e 'const fs = require("node:fs"); if (JSON.parse(fs.readFileSync("/tmp/registry-version.json", "utf8")) !== process.argv[1]) process.exit(1)' "${version}" echo "${package}@${version} is already published; immutable version left intact." else node -e 'const fs = require("node:fs"); const result = JSON.parse(fs.readFileSync("/tmp/registry-version.json", "utf8")); if (result.error?.code !== "E404") process.exit(1)' || { cat /tmp/registry-error.txt; exit 1; } npm publish --tag latest fi