name: Publish to crates.io

on:
  release:
    types: [published]
  # Also trigger on manual tag push (for emergency releases outside release-please).
  push:
    tags: ['v*', 'djvu-rs-v*']
  workflow_dispatch:
    inputs:
      tag:
        description: 'Tag to publish (e.g. v0.6.0)'
        required: true

env:
  CARGO_TERM_COLOR: always
  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true

jobs:
  publish:
    name: Publish
    runs-on: ubuntu-latest
    environment: crates-io
    steps:
      - name: Resolve ref
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            echo "PUBLISH_REF=${{ inputs.tag }}" >> "$GITHUB_ENV"
          elif [ "${{ github.event_name }}" = "release" ]; then
            echo "PUBLISH_REF=${{ github.event.release.tag_name }}" >> "$GITHUB_ENV"
          else
            echo "PUBLISH_REF=${GITHUB_REF_NAME}" >> "$GITHUB_ENV"
          fi

      - uses: actions/checkout@v4
        with:
          ref: ${{ env.PUBLISH_REF }}

      - name: Install Rust stable
        uses: dtolnay/rust-toolchain@stable

      - name: Cache Rust dependencies
        uses: Swatinem/rust-cache@v2

      - name: Verify version matches tag
        run: |
          VERSION=$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)
          TAG="${PUBLISH_REF#djvu-rs-v}"
          TAG="${TAG#v}"
          if [ "$VERSION" != "$TAG" ]; then
            echo "::error::Cargo.toml version ($VERSION) does not match tag (v$TAG)"
            exit 1
          fi
          echo "VERSION=$VERSION" >> "$GITHUB_ENV"

      - name: Check if already published
        run: |
          if cargo search "djvu-rs" --limit 1 2>/dev/null | grep -q "^djvu-rs = \"$VERSION\""; then
            echo "ALREADY_PUBLISHED=true" >> "$GITHUB_ENV"
            echo "Version $VERSION already on crates.io — skipping publish."
          else
            echo "ALREADY_PUBLISHED=false" >> "$GITHUB_ENV"
          fi

      - name: Dry-run package
        if: env.ALREADY_PUBLISHED == 'false'
        run: cargo package --allow-dirty

      - name: Run tests
        if: env.ALREADY_PUBLISHED == 'false'
        uses: taiki-e/install-action@cargo-nextest
      - name: cargo nextest run
        if: env.ALREADY_PUBLISHED == 'false'
        run: cargo nextest run --workspace

      - name: Publish to crates.io
        if: env.ALREADY_PUBLISHED == 'false'
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: cargo publish
