name: Release

on:
  push:
    tags:
      - 'v*'

permissions:
  # `checks: write` is required by ci.yml's `audit` job (which uses
  # `rustsec/audit-check@v2.0.0` to post a Check Run). When ci.yml is
  # invoked via `workflow_call: ./.github/workflows/ci.yml`, GitHub
  # validates that the **called workflow's per-job permissions do not
  # exceed the caller's**. If the called job requests `checks: write`
  # but the caller doesn't grant it, the entire reusable-workflow run
  # is rejected at startup with a `startup_failure` (no logs, no jobs).
  # Granting it here keeps the per-job override in ci.yml working
  # without elevating the publish-crate or github-release jobs (those
  # carry their own narrower per-job permissions).
  contents: read
  checks: write

env:
  CARGO_TERM_COLOR: always

jobs:
  ci:
    name: CI
    uses: ./.github/workflows/ci.yml

  publish-crate:
    name: Publish to crates.io
    needs: ci
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - name: Validate tag matches Cargo.toml version
        run: |
          TAG="${GITHUB_REF#refs/tags/v}"
          VERSION=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[0].version')
          if [ "$TAG" != "$VERSION" ]; then
            echo "::error::Tag v$TAG does not match Cargo.toml version $VERSION"
            exit 1
          fi
      - name: Publish
        # `--locked` forbids any Cargo.lock modification at publish time.
        # `cargo publish` otherwise re-resolves the lockfile to package the
        # crate, which produces an "uncommitted Cargo.lock" error. Releases
        # must be deterministic against the committed lockfile anyway, so
        # this is the right gate.
        run: cargo publish --locked
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

  github-release:
    name: GitHub Release
    needs: publish-crate
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - name: Create GitHub Release
        run: gh release create "$GITHUB_REF_NAME" --generate-notes
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
