diff-tui 0.1.1

A terminal-based Git diff viewer with fuzzy search
name: Release

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      version:
        description: "Version to release (e.g., 0.1.0)"
        required: true
        type: string

env:
  CARGO_TERM_COLOR: always
  BINARY_NAME: diff-tui

jobs:
  # バージョン検証
  validate:
    runs-on: ubuntu-latest
    outputs:
      version: ${{ steps.version.outputs.version }}
    steps:
      - uses: actions/checkout@v4

      - name: Get version
        id: version
        run: |
          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
            VERSION="${{ inputs.version }}"
          else
            VERSION="${GITHUB_REF#refs/tags/v}"
          fi
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Release version: $VERSION"

      - name: Verify Cargo.toml version matches
        run: |
          CARGO_VERSION=$(grep -m1 'version = ' Cargo.toml | cut -d'"' -f2)
          if [ "$CARGO_VERSION" != "${{ steps.version.outputs.version }}" ]; then
            echo "Error: Cargo.toml version ($CARGO_VERSION) doesn't match release version (${{ steps.version.outputs.version }})"
            exit 1
          fi

  # マルチプラットフォームビルド
  build:
    needs: validate
    strategy:
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
          - target: x86_64-unknown-linux-musl
            os: ubuntu-latest
            archive: tar.gz
          - target: x86_64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: aarch64-apple-darwin
            os: macos-latest
            archive: tar.gz
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            archive: zip

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - name: Install Rust toolchain
        uses: dtolnay/rust-toolchain@stable
        with:
          targets: ${{ matrix.target }}

      - name: Install musl-tools (Linux musl)
        if: matrix.target == 'x86_64-unknown-linux-musl'
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Build
        run: cargo build --release --target ${{ matrix.target }}

      - name: Prepare artifacts (Unix)
        if: runner.os != 'Windows'
        run: |
          ARTIFACT_DIR="${{ env.BINARY_NAME }}-v${{ needs.validate.outputs.version }}-${{ matrix.target }}"
          mkdir -p "$ARTIFACT_DIR"
          cp "target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}" "$ARTIFACT_DIR/"
          cp README.md LICENSE "$ARTIFACT_DIR/" 2>/dev/null || true
          tar -czvf "$ARTIFACT_DIR.tar.gz" "$ARTIFACT_DIR"
          echo "ARTIFACT=$ARTIFACT_DIR.tar.gz" >> $GITHUB_ENV

      - name: Prepare artifacts (Windows)
        if: runner.os == 'Windows'
        shell: pwsh
        run: |
          $ARTIFACT_DIR = "${{ env.BINARY_NAME }}-v${{ needs.validate.outputs.version }}-${{ matrix.target }}"
          New-Item -ItemType Directory -Path $ARTIFACT_DIR -Force
          Copy-Item "target/${{ matrix.target }}/release/${{ env.BINARY_NAME }}.exe" $ARTIFACT_DIR/
          Copy-Item README.md, LICENSE $ARTIFACT_DIR/ -ErrorAction SilentlyContinue
          Compress-Archive -Path $ARTIFACT_DIR -DestinationPath "$ARTIFACT_DIR.zip"
          echo "ARTIFACT=$ARTIFACT_DIR.zip" >> $env:GITHUB_ENV

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: ${{ env.BINARY_NAME }}-${{ matrix.target }}
          path: ${{ env.ARTIFACT }}
          retention-days: 1

  # crates.io への公開
  publish-crates:
    needs: [validate, build]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      - name: Publish to crates.io
        run: cargo publish --token ${{ secrets.CARGO_REGISTRY_TOKEN }}

  # GitHub Release 作成
  release:
    needs: [validate, build, publish-crates]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Download all artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts

      - name: Prepare release assets
        run: |
          mkdir -p release-assets
          find artifacts -type f \( -name "*.tar.gz" -o -name "*.zip" \) -exec mv {} release-assets/ \;
          ls -la release-assets/

      - name: Generate checksums
        working-directory: release-assets
        run: |
          sha256sum * > SHA256SUMS.txt
          cat SHA256SUMS.txt

      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: v${{ needs.validate.outputs.version }}
          name: v${{ needs.validate.outputs.version }}
          draft: false
          prerelease: ${{ contains(needs.validate.outputs.version, '-') }}
          generate_release_notes: true
          files: |
            release-assets/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  # workflow_dispatch 時のタグ作成
  create-tag:
    if: github.event_name == 'workflow_dispatch'
    needs: [validate, release]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4

      - name: Create and push tag
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git tag -a "v${{ needs.validate.outputs.version }}" -m "Release v${{ needs.validate.outputs.version }}"
          git push origin "v${{ needs.validate.outputs.version }}"