Repository navigation
ci: discover the installed MSVC instance for examples #53
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # MSVC Examples CI | |
| # | |
| # Runs all examples/msvc/*.build.ps1 scripts on a real Windows runner with | |
| # MSVC tools pre-installed; discover the installed Visual Studio instance. | |
| # | |
| # Triggered when: | |
| # - examples/msvc/** changes | |
| # - the msvc provider.star changes | |
| # - manually via workflow_dispatch | |
| # - weekly schedule (keeps examples honest against upstream repos) | |
| name: Examples - MSVC | |
| on: | |
| push: | |
| branches: [main, develop] | |
| paths: | |
| - "examples/msvc/**" | |
| - "crates/vx-providers/msvc/**" | |
| - ".github/workflows/examples-msvc.yml" | |
| - "scripts/ensure-msvc-spectre.ps1" | |
| - "scripts/tests/msvc-spectre.Tests.ps1" | |
| pull_request: | |
| paths: | |
| - "examples/msvc/**" | |
| - "crates/vx-providers/msvc/**" | |
| - ".github/workflows/examples-msvc.yml" | |
| - "scripts/ensure-msvc-spectre.ps1" | |
| - "scripts/tests/msvc-spectre.Tests.ps1" | |
| workflow_dispatch: | |
| inputs: | |
| script: | |
| description: "Single script to run (e.g. fmt.build.ps1). Leave empty to run all." | |
| required: false | |
| default: "" | |
| schedule: | |
| - cron: "0 4 * * 1" # Every Monday at 04:00 UTC | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| test-msvc-setup: | |
| name: Test MSVC setup contracts | |
| runs-on: windows-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Test discovery, Spectre fallback, and CMake selection | |
| shell: pwsh | |
| run: | | |
| Import-Module Pester -MinimumVersion 5.0 -ErrorAction Stop | |
| $result = Invoke-Pester -Path scripts/tests/msvc-spectre.Tests.ps1 -Output Detailed -PassThru | |
| if ($result.FailedCount -gt 0) { exit 1 } | |
| exit 0 | |
| build-vx: | |
| name: Build VX (Windows) | |
| needs: test-msvc-setup | |
| runs-on: windows-latest | |
| env: | |
| RUSTC_WRAPPER: sccache | |
| SCCACHE_DIR: ${{ github.workspace }}/.cache/sccache | |
| outputs: | |
| used-release-binary: ${{ steps.download-release.outputs.used_release_binary }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| # ----------------------------------------------------------------------- | |
| # Fast path: for schedule or pure example changes, try to download the | |
| # latest release binary instead of compiling from scratch (~16 min -> ~1 min) | |
| # ----------------------------------------------------------------------- | |
| - name: Try download release binary (fast path) | |
| id: download-release | |
| shell: pwsh | |
| run: | | |
| $useRelease = "false" | |
| # Use release binary for schedule triggers or when only examples changed | |
| if ("${{ github.event_name }}" -eq "schedule") { | |
| $useRelease = "true" | |
| } | |
| # For workflow_dispatch without msvc provider changes, also prefer release | |
| if ("${{ github.event_name }}" -eq "workflow_dispatch" -and "" -eq "${{ inputs.script }}") { | |
| $useRelease = "true" | |
| } | |
| if ($useRelease -eq "true") { | |
| $releaseUrl = "https://github.com/vx-org/vx/releases/latest/download/vx-x86_64-pc-windows-msvc.zip" | |
| Write-Host "Attempting to download release binary from $releaseUrl" | |
| try { | |
| Invoke-WebRequest -Uri $releaseUrl -OutFile "$env:RUNNER_TEMP\vx-release.zip" -MaximumRetryCount 3 -TimeoutSec 60 | |
| Expand-Archive -Path "$env:RUNNER_TEMP\vx-release.zip" -DestinationPath "$env:RUNNER_TEMP\vx-release" -Force | |
| $exePath = Join-Path "$env:RUNNER_TEMP\vx-release" "vx.exe" | |
| if (Test-Path $exePath) { | |
| New-Item -ItemType Directory -Force -Path "target\release" | Out-Null | |
| Copy-Item $exePath "target\release\vx.exe" -Force | |
| & "$exePath" --version | |
| Write-Host "Successfully downloaded release binary" | |
| echo "used_release_binary=true" >> $env:GITHUB_OUTPUT | |
| exit 0 | |
| } | |
| } catch { | |
| Write-Warning "Failed to download release binary: $_" | |
| } | |
| } | |
| echo "used_release_binary=false" >> $env:GITHUB_OUTPUT | |
| - name: Install Rust | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| uses: dtolnay/rust-toolchain@stable | |
| - name: Install sccache | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| uses: taiki-e/install-action@v2 | |
| with: | |
| tool: sccache | |
| - name: Setup sccache path (Windows) | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| shell: pwsh | |
| run: | | |
| $sccachePath = (Get-Command sccache -ErrorAction SilentlyContinue).Source | |
| if ($sccachePath) { | |
| $sccacheDir = Split-Path $sccachePath | |
| echo "$sccacheDir" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| } else { | |
| Write-Warning "sccache not found, disabling RUSTC_WRAPPER" | |
| echo "RUSTC_WRAPPER=" >> $env:GITHUB_ENV | |
| } | |
| - name: Cache sccache | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| uses: actions/cache@v6 | |
| with: | |
| path: ${{ github.workspace }}/.cache/sccache | |
| key: sccache-msvc-examples-${{ hashFiles('Cargo.lock') }} | |
| restore-keys: | | |
| sccache-msvc-examples- | |
| - name: Start sccache server | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| run: sccache --start-server || true | |
| - name: Cache Cargo | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| uses: actions/cache@v6 | |
| with: | |
| path: | | |
| ~/.cargo/bin/ | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| target/ | |
| key: windows-cargo-msvc-examples-${{ hashFiles('**/Cargo.lock') }} | |
| restore-keys: | | |
| windows-cargo-msvc-examples- | |
| - name: Build VX with timings | |
| if: steps.download-release.outputs.used_release_binary != 'true' | |
| run: cargo build --release --timings | |
| env: | |
| # Use thin LTO and more codegen units for faster CI builds | |
| # (trade-off: slightly larger binary, but ~30-50% faster compilation) | |
| CARGO_PROFILE_RELEASE_LTO: thin | |
| CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 16 | |
| - name: Upload VX binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: vx-windows-msvc-examples | |
| path: target/release/vx.exe | |
| retention-days: 1 | |
| - name: Upload cargo build timings | |
| if: always() && steps.download-release.outputs.used_release_binary != 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: cargo-build-timings-windows | |
| path: target/cargo-timings/cargo-timing.html | |
| retention-days: 7 | |
| if-no-files-found: warn | |
| run-examples: | |
| name: Run MSVC Examples | |
| runs-on: windows-latest | |
| needs: build-vx | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download VX binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: vx-windows-msvc-examples | |
| path: ./bin | |
| - name: Add VX to PATH | |
| shell: pwsh | |
| run: | | |
| $binDir = Join-Path $env:GITHUB_WORKSPACE "bin" | |
| echo "$binDir" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append | |
| Write-Host "Added $binDir to PATH" | |
| - name: Verify VX | |
| shell: pwsh | |
| run: vx --version | |
| - name: Verify MSVC and Spectre libraries | |
| shell: pwsh | |
| run: | | |
| New-Item -ItemType Directory -Force examples/msvc/logs | Out-Null | |
| Start-Transcript -Path examples/msvc/logs/msvc-setup.log | |
| try { | |
| . ./scripts/ensure-msvc-spectre.ps1 | |
| $instance = Ensure-MsvcSpectre | |
| $generator = Get-MsvcCMakeGenerator -InstallationVersion $instance.installationVersion | |
| "CMAKE_GENERATOR=$generator" >> $env:GITHUB_ENV | |
| "CMAKE_GENERATOR_INSTANCE=$($instance.installationPath)" >> $env:GITHUB_ENV | |
| Write-Host "CMake generator: $generator" | |
| } finally { | |
| Stop-Transcript | |
| } | |
| - name: Run example — fmt (cmake + MSVC) | |
| shell: pwsh | |
| run: | | |
| if ("${{ inputs.script }}" -ne "" -and "${{ inputs.script }}" -ne "fmt.build.ps1") { | |
| Write-Host "Skipping fmt.build.ps1 (not selected)" | |
| exit 0 | |
| } | |
| & "$env:GITHUB_WORKSPACE\examples\msvc\fmt.build.ps1" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run example — node-pty (native addon) | |
| shell: pwsh | |
| run: | | |
| if ("${{ inputs.script }}" -ne "" -and "${{ inputs.script }}" -ne "node-pty.build.ps1") { | |
| Write-Host "Skipping node-pty.build.ps1 (not selected)" | |
| exit 0 | |
| } | |
| & "$env:GITHUB_WORKSPACE\examples\msvc\node-pty.build.ps1" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run example — dotnet-samples (csc / Roslyn) | |
| shell: pwsh | |
| run: | | |
| if ("${{ inputs.script }}" -ne "" -and "${{ inputs.script }}" -ne "dotnet-samples-csc.build.ps1") { | |
| Write-Host "Skipping dotnet-samples-csc.build.ps1 (not selected)" | |
| exit 0 | |
| } | |
| & "$env:GITHUB_WORKSPACE\examples\msvc\dotnet-samples-csc.build.ps1" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Run example — aionui (Electron + native modules) | |
| shell: pwsh | |
| run: | | |
| if ("${{ inputs.script }}" -ne "" -and "${{ inputs.script }}" -ne "aionui.build.ps1") { | |
| Write-Host "Skipping aionui.build.ps1 (not selected)" | |
| exit 0 | |
| } | |
| & "$env:GITHUB_WORKSPACE\examples\msvc\aionui.build.ps1" | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Upload build logs | |
| if: always() | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: msvc-example-logs | |
| path: examples/msvc/logs/ | |
| retention-days: 7 |