msvc-kit 0.2.10

A portable MSVC Build Tools installer and manager for Rust development
name: PR Checks

# Comprehensive checks on PRs to ensure quality before merging.
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]
  workflow_dispatch:

permissions:
  contents: read
  pull-requests: write

concurrency:
  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
  cancel-in-progress: true

env:
  CARGO_TERM_COLOR: always
  CARGO_HTTP_TIMEOUT: "600"
  CARGO_NET_RETRY: "10"
  CARGO_REGISTRIES_CRATES_IO_PROTOCOL: sparse

jobs:
  # Pre-build binaries for all targets
  pre-build:
    name: Pre-build (${{ matrix.target }})
    runs-on: windows-latest
    timeout-minutes: 25
    strategy:
      fail-fast: false
      matrix:
        include:
          - target: x86_64-pc-windows-msvc
            artifact-name: msvc-kit-x86_64-windows
          - target: i686-pc-windows-msvc
            artifact-name: msvc-kit-i686-windows
          - target: aarch64-pc-windows-msvc
            artifact-name: msvc-kit-aarch64-windows
    steps:
      - uses: actions/checkout@v6

      - name: Setup vx
        uses: loonghao/vx@main
        with:
          version: '0.8.0'
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup tools (vx)
        run: vx setup

      - name: Add Rust components
        run: vx rustup component add clippy rustfmt

      - name: Setup MSVC Developer Command Prompt
        uses: ilammy/msvc-dev-cmd@v1

      - name: Fix MSVC linker (remove Git's link.exe)
        run: Remove-Item 'C:\Program Files\Git\usr\bin\link.exe' -Force -ErrorAction SilentlyContinue
        shell: pwsh

      - name: Add Rust target
        run: vx rustup target add ${{ matrix.target }}

      - name: Cache cargo
        uses: Swatinem/rust-cache@v2
        with:
          key: ${{ matrix.target }}

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

      - name: Upload artifact
        uses: actions/upload-artifact@v6
        with:
          name: ${{ matrix.artifact-name }}
          path: target/${{ matrix.target }}/release/msvc-kit.exe
          retention-days: 7

  # Quick checks
  quick-checks:
    name: Quick Checks
    runs-on: windows-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v6

      - name: Setup vx
        uses: loonghao/vx@main
        with:
          version: '0.8.0'
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup tools (vx)
        run: vx setup

      - name: Add Rust components
        run: vx rustup component add clippy rustfmt

      - name: Setup MSVC Developer Command Prompt
        uses: ilammy/msvc-dev-cmd@v1

      - name: Fix MSVC linker (remove Git's link.exe)
        run: Remove-Item 'C:\Program Files\Git\usr\bin\link.exe' -Force -ErrorAction SilentlyContinue
        shell: pwsh

      - name: Cache Rust
        uses: Swatinem/rust-cache@v2

      - name: Check Rust formatting
        run: vx just fmt-check

      - name: Cargo check
        run: vx just check-workspace


  # Clippy lints
  clippy:
    name: Clippy Lints
    runs-on: windows-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v6

      - name: Setup vx
        uses: loonghao/vx@main
        with:
          version: '0.8.0'
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup tools (vx)
        run: vx setup

      - name: Add Rust components
        run: vx rustup component add clippy rustfmt

      - name: Setup MSVC Developer Command Prompt
        uses: ilammy/msvc-dev-cmd@v1

      - name: Fix MSVC linker (remove Git's link.exe)
        run: Remove-Item 'C:\Program Files\Git\usr\bin\link.exe' -Force -ErrorAction SilentlyContinue
        shell: pwsh

      - name: Cache Rust
        uses: Swatinem/rust-cache@v2

      - name: Run Clippy
        run: vx just lint


  # Rust tests
  rust-tests:
    name: Rust Tests
    runs-on: windows-latest
    timeout-minutes: 20
    needs: [quick-checks]
    steps:
      - uses: actions/checkout@v6

      - name: Setup vx
        uses: loonghao/vx@main
        with:
          version: '0.8.0'
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup tools (vx)
        run: vx setup

      - name: Add Rust components
        run: vx rustup component add clippy rustfmt

      - name: Setup MSVC Developer Command Prompt
        uses: ilammy/msvc-dev-cmd@v1

      - name: Fix MSVC linker (remove Git's link.exe)
        run: Remove-Item 'C:\Program Files\Git\usr\bin\link.exe' -Force -ErrorAction SilentlyContinue
        shell: pwsh

      - name: Cache Rust
        uses: Swatinem/rust-cache@v2

      - name: Run tests
        run: vx just test-all-features

      - name: Run doc tests
        run: vx just test-doc


  # Documentation build test
  docs-build:
    name: Docs Build Test
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@v6

      - name: Setup vx
        uses: loonghao/vx@main
        with:
          version: '0.8.0'
          github-token: ${{ secrets.GITHUB_TOKEN }}

      - name: Setup tools (vx)
        run: vx setup

      - name: Install dependencies
        run: vx just docs-install

      - name: Build documentation
        run: vx just docs-build


  # Final gate
  pr-ready:
    name: PR Ready
    runs-on: ubuntu-latest
    needs: [pre-build, quick-checks, clippy, rust-tests, docs-build]
    if: always()
    steps:
      - name: Check results
        env:
          PRE_BUILD_RESULT: ${{ needs.pre-build.result }}
          QUICK_CHECKS_RESULT: ${{ needs.quick-checks.result }}
          CLIPPY_RESULT: ${{ needs.clippy.result }}
          RUST_TESTS_RESULT: ${{ needs.rust-tests.result }}
          DOCS_BUILD_RESULT: ${{ needs.docs-build.result }}
        run: |

          echo "## PR Check Results" >> "$GITHUB_STEP_SUMMARY"

          failed=0

          check_result() {
            local job_name=$1
            local result=$2
            if [[ "$result" == "success" ]]; then
              echo "- ✅ $job_name" >> "$GITHUB_STEP_SUMMARY"
            elif [[ "$result" == "skipped" ]]; then
              echo "- ⏭️ $job_name (skipped)" >> "$GITHUB_STEP_SUMMARY"
            else
              echo "- ❌ $job_name ($result)" >> "$GITHUB_STEP_SUMMARY"
              failed=1
            fi
          }

          check_result "pre-build" "$PRE_BUILD_RESULT"
          check_result "quick-checks" "$QUICK_CHECKS_RESULT"
          check_result "clippy" "$CLIPPY_RESULT"
          check_result "rust-tests" "$RUST_TESTS_RESULT"
          check_result "docs-build" "$DOCS_BUILD_RESULT"

          echo "" >> "$GITHUB_STEP_SUMMARY"

          if [[ $failed -eq 1 ]]; then
            echo "❌ **PR is not ready for merge**" >> "$GITHUB_STEP_SUMMARY"
            exit 1
          fi

          echo "✅ **PR is ready for merge!**" >> "$GITHUB_STEP_SUMMARY"