name: Release

on:
  workflow_dispatch:
  push:
    branches: [main]
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+*'
  pull_request:
    branches: [main]

permissions:
  contents: read

concurrency:
  group: release-${{ github.ref }}
  cancel-in-progress: false

env:
  CARGO_TERM_COLOR: always

jobs:
  dry-run:
    if: github.event_name != 'push' || !startsWith(github.ref, 'refs/tags/')
    name: Dry-run packaging
    runs-on: ubuntu-24.04
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable

      - uses: michaelklishin/rust-build-package-release-action@v3
        with:
          command: publish-crate
          publish-dry-run: 'true'
          locked: 'true'

  validate:
    if: startsWith(github.ref, 'refs/tags/')
    name: Validate
    runs-on: ubuntu-24.04
    timeout-minutes: 5
    outputs:
      version: ${{ steps.validate-version.outputs.version }}
    steps:
      - uses: actions/checkout@v6

      - uses: michaelklishin/rust-build-package-release-action@v3
        with:
          command: validate-changelog

      - uses: michaelklishin/rust-build-package-release-action@v3
        id: validate-version
        with:
          command: validate-version
          validate-cargo-toml: 'true'

  publish:
    if: startsWith(github.ref, 'refs/tags/')
    needs: [validate]
    name: Publish to crates.io
    runs-on: ubuntu-24.04
    environment: release
    timeout-minutes: 15
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v6
      - uses: dtolnay/rust-toolchain@stable

      - name: Authenticate with crates.io
        id: auth
        uses: rust-lang/crates-io-auth-action@v1

      - uses: michaelklishin/rust-build-package-release-action@v3
        with:
          command: publish-crate
          locked: 'true'
        env:
          CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }}

  github-release:
    if: startsWith(github.ref, 'refs/tags/')
    needs: [validate, publish]
    name: GitHub Release
    runs-on: ubuntu-24.04
    timeout-minutes: 5
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v6

      - uses: michaelklishin/rust-build-package-release-action@v3
        with:
          command: extract-changelog
          version: ${{ needs.validate.outputs.version }}

      - uses: softprops/action-gh-release@v2
        with:
          draft: false
          body_path: release_notes.md
