Skip to content

ci: discover the installed MSVC instance for examples #53

ci: discover the installed MSVC instance for examples

ci: discover the installed MSVC instance for examples #53

Workflow file for this run

# 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