diskr 0.1.12

Lightweight terminal file explorer and disk/storage manager for macOS
name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write

env:
  CARGO_TERM_COLOR: always

jobs:
  publish:
    runs-on: macos-latest

    steps:
      - uses: actions/checkout@v6.0.2
        with:
          fetch-depth: 0

      - uses: dtolnay/rust-toolchain@stable
        with:
          components: rustfmt, clippy

      - name: Read crate metadata
        id: meta
        run: |
          python - <<'PY' >> "$GITHUB_OUTPUT"
          import json
          import subprocess

          metadata = json.loads(
              subprocess.check_output(
                  ["cargo", "metadata", "--no-deps", "--format-version", "1"],
                  text=True,
              )
          )
          package = metadata["packages"][0]
          print(f"name={package['name']}")
          print(f"version={package['version']}")
          PY

      - name: Verify tag matches crate version
        env:
          CRATE_VERSION: ${{ steps.meta.outputs.version }}
        run: |
          tag_version="${GITHUB_REF_NAME#v}"
          if [ "$tag_version" != "$CRATE_VERSION" ]; then
            echo "tag $GITHUB_REF_NAME does not match Cargo.toml version $CRATE_VERSION" >&2
            exit 1
          fi

      - name: Verify release tag points to main
        run: |
          git fetch origin main
          if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
            echo "release tags must point to a commit reachable from origin/main" >&2
            exit 1
          fi

      - run: cargo fmt -- --check
      - run: cargo clippy --locked --all-targets --all-features -- -D warnings
      - run: cargo test --locked
      - run: cargo package --locked
      - run: cargo publish --dry-run --locked

      - name: Check crates.io for existing version
        id: crates
        env:
          CRATE_NAME: ${{ steps.meta.outputs.name }}
          CRATE_VERSION: ${{ steps.meta.outputs.version }}
        run: |
          status_code="$(
            curl -s -o /dev/null -w "%{http_code}" \
              -H "User-Agent: diskr-release-workflow" \
              -H "Accept: application/json" \
              "https://crates.io/api/v1/crates/$CRATE_NAME/$CRATE_VERSION"
          )"
          if [ "$status_code" = "200" ]; then
            echo "already_published=true" >> "$GITHUB_OUTPUT"
          elif [ "$status_code" = "404" ]; then
            echo "already_published=false" >> "$GITHUB_OUTPUT"
          else
            echo "unexpected crates.io status: $status_code" >&2
            exit 1
          fi

      - name: Publish to crates.io
        if: steps.crates.outputs.already_published != 'true'
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
        run: |
          if [ -z "$CARGO_REGISTRY_TOKEN" ]; then
            echo "CARGO_REGISTRY_TOKEN secret is not configured" >&2
            exit 1
          fi
          cargo publish --locked

      - name: Create GitHub release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          tag_name: ${{ github.ref_name }}
          name: ${{ github.ref_name }}