name: crates-release
run-name: >-
  ${{ format('crates publish {0}',
       case(github.event_name == 'workflow_dispatch', inputs.tag,
            github.ref_name)) }}

on:
  push:
    tags:
      - v*
  workflow_dispatch:
    inputs:
      tag:
        description: Release tag to publish (e.g. v0.6.0)
        required: true
        type: string
      dry-run:
        description: Dry run only (no upload to crates.io)
        required: false
        default: false
        type: boolean

permissions:
  contents: read

env:
  CARGO_TERM_COLOR: always

jobs:
  publish:
    name: publish to crates.io
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    environment:
      name: crates-io
      url: https://crates.io/crates/runner-run
    env:
      RELEASE_TAG: >-
        ${{ case(github.event_name == 'workflow_dispatch', inputs.tag,
             github.ref_name) }}
      INPUT_DRY_RUN: ${{ inputs.dry-run || 'false' }}
    steps:
      - uses: actions/checkout@v6
        with:
          ref: refs/tags/${{ env.RELEASE_TAG }}
          persist-credentials: false

      - name: install rust toolchain
        uses: dtolnay/rust-toolchain@stable

      - name: rust cache
        uses: Swatinem/rust-cache@v2

      - name: verify tag matches Cargo.toml version
        run: |
          set -euo pipefail
          tag_version="${RELEASE_TAG#v}"
          manifest_version=$(cargo metadata --no-deps --format-version 1 \
            | jq -r '.packages[] | select(.name == "runner-run") | .version')
          if [[ "${tag_version}" != "${manifest_version}" ]]; then
            echo "error: tag ${RELEASE_TAG} (${tag_version}) does not match Cargo.toml version ${manifest_version}" >&2
            exit 1
          fi
          echo "ok: tag ${RELEASE_TAG} matches Cargo.toml version ${manifest_version}"

      - name: cargo publish (dry-run verification)
        run: cargo publish --locked --dry-run

      - name: mint crates.io token (trusted publishing)
        if: env.INPUT_DRY_RUN != 'true'
        id: auth
        uses: rust-lang/crates-io-auth-action@v1

      - name: cargo publish
        if: env.INPUT_DRY_RUN != 'true'
        env:
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}
        run: cargo publish --locked
