vership 0.2.4

Multi-target release orchestrator
Documentation
name: Release

on:
  push:
    tags:
      - "v[0-9]*.[0-9]*.[0-9]*"
  workflow_dispatch:
    inputs:
      dry_run:
        description: "Dry run (skip publishing)"
        required: false
        default: true
        type: boolean
      skip_crates_io:
        description: "Skip crates.io publish"
        required: false
        default: false
        type: boolean
      skip_pypi:
        description: "Skip PyPI publish"
        required: false
        default: false
        type: boolean

permissions:
  contents: write

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
      - run: cargo check --locked
      - run: cargo test

  build:
    needs: test
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
          - target: aarch64-unknown-linux-gnu
            os: ubuntu-latest
          - target: x86_64-apple-darwin
            os: macos-latest
          - target: aarch64-apple-darwin
            os: macos-latest
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}
      - name: Install cross-compilation tools
        if: matrix.target == 'aarch64-unknown-linux-gnu'
        run: |
          sudo apt-get update
          sudo apt-get install -y gcc-aarch64-linux-gnu
      - name: Install maturin and zig
        run: pip install maturin ziglang
      - name: Build wheel
        shell: bash
        run: |
          case "${{ matrix.target }}" in
            *-gnu)
              maturin build --release --target ${{ matrix.target }} --zig
              ;;
            *)
              maturin build --release --target ${{ matrix.target }}
              ;;
          esac
      - name: Build binary
        run: cargo build --release --target ${{ matrix.target }}
        env:
          CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
      - name: Package binary
        run: |
          ARCHIVE_NAME="vership-${{ github.ref_name }}-${{ matrix.target }}"
          mkdir -p "${ARCHIVE_NAME}"
          cp "target/${{ matrix.target }}/release/vership" "${ARCHIVE_NAME}/"
          tar czf "${ARCHIVE_NAME}.tar.gz" "${ARCHIVE_NAME}"
          shasum -a 256 "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
      - uses: actions/upload-artifact@v4
        with:
          name: build-${{ matrix.target }}
          path: |
            vership-*.tar.gz
            vership-*.tar.gz.sha256
            target/wheels/*.whl

  sdist:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install maturin
        run: pip install maturin
      - name: Build sdist
        run: maturin sdist
      - uses: actions/upload-artifact@v4
        with:
          name: sdist
          path: target/wheels/*.tar.gz

  release:
    needs: [build, sdist]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
        with:
          path: /tmp/artifacts
      - uses: dtolnay/rust-toolchain@stable

      - name: Publish to crates.io
        if: ${{ !inputs.dry_run && !inputs.skip_crates_io }}
        run: cargo publish
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

      - name: Install uv
        uses: astral-sh/setup-uv@v6

      - name: Publish to PyPI
        if: ${{ !inputs.dry_run && !inputs.skip_pypi }}
        run: uv publish /tmp/artifacts/build-*/*.whl /tmp/artifacts/sdist/*.tar.gz
        env:
          UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}

      - name: Create GitHub Release
        if: ${{ !inputs.dry_run }}
        run: |
          gh release create ${{ github.ref_name }} \
            --title "${{ github.ref_name }}" \
            --generate-notes \
            /tmp/artifacts/build-*/*.tar.gz \
            /tmp/artifacts/build-*/*.sha256
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}