repopilot 0.7.0

Local-first CLI for repository audit, architecture risk detection, baseline tracking, and CI-friendly code review.
Documentation
name: Release

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write

jobs:
  build:
    name: Build ${{ matrix.target }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            archive: tar.gz
          - target: aarch64-unknown-linux-gnu
            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

    steps:
      - uses: actions/checkout@v4

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

      - name: Install cross (Linux aarch64 only)
        if: matrix.target == 'aarch64-unknown-linux-gnu'
        run: cargo install cross --git https://github.com/cross-rs/cross

      - name: Build (cross)
        if: matrix.target == 'aarch64-unknown-linux-gnu'
        run: cross build --release --target ${{ matrix.target }}

      - name: Build (native)
        if: matrix.target != 'aarch64-unknown-linux-gnu'
        run: cargo build --release --target ${{ matrix.target }}

      - name: Package (Unix)
        if: matrix.archive == 'tar.gz'
        run: |
          BINARY_NAME=repopilot
          ASSET_NAME="${BINARY_NAME}-${{ github.ref_name }}-${{ matrix.target }}"
          mkdir -p dist
          cp target/${{ matrix.target }}/release/${BINARY_NAME} dist/
          cd dist
          tar -czf "${ASSET_NAME}.tar.gz" ${BINARY_NAME}
          shasum -a 256 "${ASSET_NAME}.tar.gz" > "${ASSET_NAME}.tar.gz.sha256"
          echo "ASSET=dist/${ASSET_NAME}.tar.gz" >> $GITHUB_ENV
          echo "CHECKSUM=dist/${ASSET_NAME}.tar.gz.sha256" >> $GITHUB_ENV

      - name: Package (Windows)
        if: matrix.archive == 'zip'
        shell: pwsh
        run: |
          $BinaryName = "repopilot"
          $AssetName = "${BinaryName}-${{ github.ref_name }}-${{ matrix.target }}"
          New-Item -ItemType Directory -Force -Path dist
          Copy-Item "target/${{ matrix.target }}/release/${BinaryName}.exe" dist/
          Compress-Archive -Path "dist/${BinaryName}.exe" -DestinationPath "dist/${AssetName}.zip"
          Get-FileHash "dist/${AssetName}.zip" -Algorithm SHA256 | ForEach-Object { "$($_.Hash.ToLower())  ${AssetName}.zip" } | Out-File -Encoding ascii "dist/${AssetName}.zip.sha256"
          echo "ASSET=dist/${AssetName}.zip" | Out-File -FilePath $env:GITHUB_ENV -Append
          echo "CHECKSUM=dist/${AssetName}.zip.sha256" | Out-File -FilePath $env:GITHUB_ENV -Append

      - name: Upload packaged artifact
        uses: actions/upload-artifact@v4
        with:
          name: release-${{ matrix.target }}
          path: |
            ${{ env.ASSET }}
            ${{ env.CHECKSUM }}
          if-no-files-found: error

  verify-crates-package:
    name: Verify crates.io package
    runs-on: ubuntu-latest
    needs: build
    steps:
      - uses: actions/checkout@v4

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

      - name: Publish dry run
        run: cargo publish --dry-run

  release:
    name: Create GitHub Release
    runs-on: ubuntu-latest
    needs:
      - build
      - verify-crates-package
    steps:
      - uses: actions/checkout@v4

      - name: Download packaged artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: release-*
          path: dist
          merge-multiple: true

      - name: Upload to GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          files: |
            dist/*.tar.gz
            dist/*.zip
            dist/*.sha256
          body_path: .github/release_template.md
          generate_release_notes: true

  publish-npm:
    name: Publish npm package
    runs-on: ubuntu-latest
    needs:
      - release
    permissions:
      contents: read
    env:
      NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
    steps:
      - uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: https://registry.npmjs.org

      - name: Test npm wrapper
        run: npm run test:npm

      - name: Verify npm package
        run: npm pack --dry-run

      - name: Publish to npm
        if: ${{ env.NODE_AUTH_TOKEN != '' }}
        run: npm publish

  publish-crates:
    name: Publish to crates.io
    runs-on: ubuntu-latest
    needs:
      - release
    steps:
      - uses: actions/checkout@v4

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

      - name: Publish
        run: cargo publish --token ${{ secrets.CRATES_IO_TOKEN }}

  update-homebrew-tap:
    name: Update Homebrew tap
    runs-on: ubuntu-latest
    needs:
      - release
    steps:
      - uses: actions/checkout@v4

      - name: Download release artifacts
        uses: actions/download-artifact@v4
        with:
          pattern: release-*
          path: dist
          merge-multiple: true

      - name: Extract checksums
        run: |
          V="${{ github.ref_name }}"
          echo "MACOS_ARM=$(awk '{print $1}' dist/repopilot-${V}-aarch64-apple-darwin.tar.gz.sha256)" >> $GITHUB_ENV
          echo "MACOS_X86=$(awk '{print $1}' dist/repopilot-${V}-x86_64-apple-darwin.tar.gz.sha256)" >> $GITHUB_ENV
          echo "LINUX_ARM=$(awk '{print $1}' dist/repopilot-${V}-aarch64-unknown-linux-gnu.tar.gz.sha256)" >> $GITHUB_ENV
          echo "LINUX_X86=$(awk '{print $1}' dist/repopilot-${V}-x86_64-unknown-linux-gnu.tar.gz.sha256)" >> $GITHUB_ENV
          echo "VER=${V#v}" >> $GITHUB_ENV

      - name: Checkout homebrew tap
        uses: actions/checkout@v4
        with:
          repository: MykytaStel/homebrew-repopilot
          path: tap
          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}

      - name: Write formula
        run: |
          sed -e "s/{{VERSION}}/${{ env.VER }}/g" \
              -e "s/{{MACOS_ARM_SHA}}/${{ env.MACOS_ARM }}/g" \
              -e "s/{{MACOS_X86_SHA}}/${{ env.MACOS_X86 }}/g" \
              -e "s/{{LINUX_ARM_SHA}}/${{ env.LINUX_ARM }}/g" \
              -e "s/{{LINUX_X86_SHA}}/${{ env.LINUX_X86 }}/g" \
              Formula/repopilot.rb > tap/Formula/repopilot.rb

      - name: Push formula update
        working-directory: tap
        run: |
          git config user.name "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add Formula/repopilot.rb
          git diff --cached --quiet || git commit -m "repopilot ${{ env.VER }}"
          git push