name: Publish

# Publish tate to crates.io when a version tag is pushed.
#   git tag v0.5.0 && git push origin v0.5.0
# The tag version must match the `version` in Cargo.toml.
#
# Requires repo secret CARGO_REGISTRY_TOKEN (Settings → Secrets and variables →
# Actions → New repository secret) holding a crates.io API token.

on:
  push:
    tags: ['v*']

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable

      # Guard: the git tag must match the crate version, so a stale tag can't
      # publish the wrong number.
      - name: Verify tag matches Cargo.toml version
        run: |
          crate_ver=$(grep -m1 '^version' Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')
          tag_ver="${GITHUB_REF_NAME#v}"
          echo "tag=$tag_ver crate=$crate_ver"
          test "$crate_ver" = "$tag_ver" || { echo "::error::tag v$tag_ver != Cargo.toml $crate_ver"; exit 1; }

      - name: Test
        run: cargo test --all-features

      - name: Publish to crates.io
        # --allow-dirty: cargo test / index refresh can touch the tracked
        # Cargo.lock in CI's throwaway checkout; that dirtiness is harmless.
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish --allow-dirty
