name: Publish to npm

# Releases are driven by a tag:
#
#   npm version <patch|minor|major>
#   git push --follow-tags
#
# No npm token is involved. The job authenticates to the registry with a
# short-lived OIDC credential issued to this workflow (trusted publishing),
# which is what `id-token: write` below grants. The registry must be told to
# trust this repository + workflow filename in the package's settings.
on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

permissions:
  contents: read
  id-token: write

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      - uses: actions/setup-node@v7
        with:
          node-version: 24
          registry-url: https://registry.npmjs.org
          cache: npm

      # Trusted publishing needs npm 11.5.1+. The npm bundled with Node usually
      # already satisfies that, so only reach for the network when it does not
      # — an unconditional global install is a needless failure point.
      - name: Ensure npm supports trusted publishing
        run: |
          need=11.5.1
          have="$(npm --version)"
          if [ "$(printf '%s\n%s\n' "$need" "$have" | sort -V | head -n1)" = "$need" ]; then
            echo "npm $have satisfies >= $need"
          else
            echo "npm $have is older than $need, upgrading"
            for attempt in 1 2 3; do
              npm install -g npm@latest && break
              echo "attempt $attempt failed, retrying"; sleep 10
            done
          fi
          npm --version

      - run: npm ci --fetch-retries=5

      # sharp carries a native binary. Fail here with a clear message rather
      # than part-way through the release.
      - name: Smoke-check the native image pipeline
        run: node -e "require('sharp'); console.log('sharp loaded')"

      # A tag that disagrees with package.json would publish the wrong version.
      - name: Check the tag matches package.json
        if: github.event_name == 'push'
        run: |
          tag="${GITHUB_REF_NAME#v}"
          pkg="$(node -p "require('./package.json').version")"
          echo "tag=$tag  package.json=$pkg"
          test "$tag" = "$pkg"

      # Runs prepublishOnly (npm test) first. Provenance is attached
      # automatically because this is a public repository.
      - run: npm publish
