aegis-scan 0.3.0

Supply chain security CLI for npm — detect malicious packages before installing
Documentation
name: Release

on:
  push:
    tags: ["v*"]

permissions:
  contents: write

jobs:
  # ── Tests ─────────────────────────────────────────────
  test:
    name: Test
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6

      - uses: dtolnay/rust-toolchain@stable

      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: test-cargo-${{ hashFiles('**/Cargo.lock') }}

      - run: cargo test

  # ── Build native binaries ─────────────────────────────
  binaries:
    name: Build ${{ matrix.target }}
    needs: test
    runs-on: ${{ matrix.os }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-unknown-linux-gnu
            os: ubuntu-latest
            artifact: aegis-linux-x86_64
            binary: aegis-scan
          - target: aarch64-apple-darwin
            os: macos-latest
            artifact: aegis-macos-arm64
            binary: aegis-scan
          - target: x86_64-apple-darwin
            os: macos-latest
            artifact: aegis-macos-x86_64
            binary: aegis-scan
          - target: x86_64-pc-windows-msvc
            os: windows-latest
            artifact: aegis-windows-x86_64.exe
            binary: aegis-scan.exe

    steps:
      - uses: actions/checkout@v6

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

      - uses: actions/cache@v5
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: ${{ matrix.target }}-cargo-${{ hashFiles('**/Cargo.lock') }}

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

      - name: Package binary
        shell: bash
        run: |
          mkdir -p dist
          cp target/${{ matrix.target }}/release/${{ matrix.binary }} dist/${{ matrix.artifact }}
          if [[ "${{ matrix.os }}" != "windows-latest" ]]; then
            chmod +x dist/${{ matrix.artifact }}
          fi
          cd dist
          if command -v shasum &> /dev/null; then
            shasum -a 256 ${{ matrix.artifact }} > ${{ matrix.artifact }}.sha256
          else
            sha256sum ${{ matrix.artifact }} > ${{ matrix.artifact }}.sha256
          fi

      - uses: actions/upload-artifact@v7
        with:
          name: ${{ matrix.artifact }}
          path: dist/

  # ── Publish to crates.io ──────────────────────────────
  crates:
    name: Publish to crates.io
    needs: test
    runs-on: ubuntu-latest
    timeout-minutes: 30
    steps:
      - uses: actions/checkout@v6

      - uses: dtolnay/rust-toolchain@stable

      - name: Publish to crates.io
        env:
          CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
        run: |
          VERSION=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[] | select(.name=="aegis-scan") | .version')

          if cargo search aegis-scan 2>/dev/null | grep -q "\"$VERSION\""; then
            echo "✓ aegis@$VERSION already published, skipping"
            exit 0
          fi

          echo "📦 Publishing aegis@$VERSION..."
          cargo publish

  # ── Create GitHub Release ─────────────────────────────
  release:
    name: Create Release
    needs: [binaries, crates]
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v8
        with:
          path: artifacts/

      - uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          files: |
            artifacts/**/*
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}