feat(windows-ci): self-provisioning toolchain for the shared unom/infra runner
windows-drivers / driver-build (push) Failing after 14s
windows-host / package (push) Failing after 7s
windows-drivers / probe-and-proto (push) Successful in 39s
windows-msix / package (x64, C:\Users\Public\ffmpeg, x86_64-pc-windows-msvc, C:\t) (push) Failing after 7s
windows-msix / package (arm64, C:\Users\Public\ffmpeg-arm64, aarch64-pc-windows-msvc, C:\t-a64) (push) Failing after 7s
android / android (push) Successful in 4m20s
ci / web (push) Successful in 54s
deb / build-publish (push) Successful in 3m30s
decky / build-publish (push) Successful in 25s
apple / swift (push) Successful in 1m8s
windows / build (aarch64-pc-windows-msvc) (push) Successful in 1m15s
ci / rust (push) Successful in 4m48s
ci / docs-site (push) Successful in 58s
apple / screenshots (push) Successful in 5m36s
ci / bench (push) Successful in 4m39s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 32s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 2m38s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 2m54s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 54s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 2m23s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 9m18s
windows / build (x86_64-pc-windows-msvc) (push) Failing after 15s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 9m14s
docker / deploy-docs (push) Successful in 21s

The Windows CI runner (home-windows-runner-1, vmid 210) is now provisioned/owned by
unom/infra and can be rebuilt or joined by additional windows-amd64-labeled runners at
any time - a manually-dispatched provisioning workflow has no way to target a specific
runner instance, so it could land on an already-provisioned box instead of the one that
needed it. Replace windows-drivers-provision.yml / windows-punktfunk-provision.yml with
scripts/ci/ensure-windows-toolchain.ps1, a shared idempotent pre-flight (WDK/cargo-wdk,
FFmpeg, Inno Setup, ARM64 rustup target) that every Windows workflow now runs at job
start - a fast no-op once already provisioned, so any runner self-heals on first real use.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 11:41:31 +02:00
parent e78805798d
commit 246552b75e
12 changed files with 166 additions and 241 deletions
@@ -1,27 +0,0 @@
# One-shot provisioning of the WDK + cargo-wdk onto the persistent self-hosted windows-amd64 runner, so
# the all-Rust UMDF drivers can build there (design/windows-host-rewrite.md, M0). The runner has the base
# Windows SDK + MSVC + LLVM + Rust but NOT the WDK (no km/wdf/iddcx headers) or cargo-wdk.
#
# Dispatch manually (workflow_dispatch). Idempotent: re-running is a near no-op once provisioned. The
# install persists on the runner (real box, not an ephemeral container), so this runs once, not per build.
name: windows-drivers-provision
on:
workflow_dispatch:
push:
branches: [main]
paths:
- 'scripts/ci/provision-windows-wdk.ps1'
- '.gitea/workflows/windows-drivers-provision.yml'
jobs:
provision:
runs-on: windows-amd64
timeout-minutes: 60
defaults:
run:
shell: pwsh
steps:
- uses: actions/checkout@v4
- name: Install WDK + cargo-wdk on the runner
run: ./scripts/ci/provision-windows-wdk.ps1
+10 -8
View File
@@ -1,5 +1,5 @@
# Windows driver workspace CI — runs on the self-hosted Windows runner (home-windows-1, host mode;
# label windows-amd64). Part of the Windows-host rewrite (design/windows-host-rewrite.md, M0).
# Windows driver workspace CI — runs on a self-hosted Windows runner (home-windows-runner-1, host
# mode; label windows-amd64). Part of the Windows-host rewrite (design/windows-host-rewrite.md, M0).
#
# Stage 1 (this file): PROBE the runner's driver toolchain (WDK / EWDK / cargo-make / LLVM / the
# inf2cat/stampinf/devgen/signtool tools) so we know what's provisioned BEFORE writing driver code,
@@ -26,7 +26,8 @@ on:
- 'crates/pf-driver-proto/**'
- 'packaging/windows/drivers/**'
# Driver builds need the WDK on the runner (provision once via windows-drivers-provision.yml).
# Driver builds need the WDK on the runner - the driver-build job below self-provisions it via
# scripts/ci/ensure-windows-toolchain.ps1, a fast no-op once already present.
jobs:
probe-and-proto:
@@ -124,11 +125,12 @@ jobs:
# retired that — see design/windows-build-and-packaging.md.
steps:
- uses: actions/checkout@v4
- name: Ensure WDK + cargo-wdk (idempotent self-provision)
# Run the provisioning script here too so driver-build is self-sufficient and never races a
# separate provision run on the single runner. Path is relative to the job working-directory
# (packaging/windows/drivers). Near-noop once the toolchain is present.
run: ../../../scripts/ci/provision-windows-wdk.ps1
- name: Ensure Windows toolchain (WDK, FFmpeg, Inno Setup, ARM64 target)
# Shared self-provision step (also used by windows.yml/windows-msix.yml/windows-host.yml) so
# driver-build is self-sufficient on any windows-amd64 runner and never races a manually
# dispatched provisioning workflow landing on a different one. Path is relative to the job
# working-directory (packaging/windows/drivers). Near-noop once the toolchain is present.
run: ../../../scripts/ci/ensure-windows-toolchain.ps1
- name: cargo build the driver workspace (wdk-probe + wdk-iddcx + pf-vdisplay)
# Whole workspace: wdk-probe (toolchain/surface-assert probe) + wdk-iddcx (DDI wrappers) +
# pf-vdisplay (the real IddCx driver). pf-vdisplay linking proves the IddCx call sites resolve
+8 -11
View File
@@ -1,8 +1,9 @@
# Build the punktfunk Windows HOST as a signed Inno Setup installer and publish it to Gitea's generic
# package registry, so a Windows GPU box can install the streaming host (SYSTEM service + bundled
# pf-vdisplay virtual-display driver + the web management console, run by a scheduled task on a bundled
# bun) from one signed setup.exe. Runs on the self-hosted Windows runner
# (host mode; scripts/ci/setup-windows-runner.ps1) — same MSVC/Windows-SDK/LLVM env as windows.yml.
# bun) from one signed setup.exe. Runs on a self-hosted windows-amd64 runner
# (host mode; same MSVC/Windows-SDK/LLVM env as windows.yml — generic from unom/infra's
# windows-runner/, FFmpeg/Inno Setup self-provision via the "Ensure Windows toolchain" step below).
#
# Why an installer and not MSIX (like the client): the host installs a LocalSystem SCM service that
# CreateProcessAsUserW's into the interactive session for secure-desktop capture, and bundles a
@@ -57,6 +58,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Ensure Windows toolchain (WDK, FFmpeg, Inno Setup, ARM64 target)
shell: pwsh
run: ./scripts/ci/ensure-windows-toolchain.ps1
- name: Locale-safety gate (installer-run scripts must be ASCII)
shell: pwsh
# The installer runs these via powershell.exe (Windows PowerShell 5.1) and cmd.exe on the END
@@ -82,7 +87,7 @@ jobs:
"CARGO_TARGET_DIR=C:\t" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
"CARGO_WORKSPACE_DIR=$env:GITHUB_WORKSPACE" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
# FFMPEG_DIR: the same BtbN lgpl-shared x64 tree the Windows CLIENT links against (provisioned
# by scripts/ci/setup-windows-runner.ps1). The host's AMD/Intel AMF/QSV encode backend
# by scripts/ci/provision-windows-punktfunk-extras.ps1). The host's AMD/Intel AMF/QSV encode backend
# (--features amf-qsv) link-imports avcodec/avutil/swscale from it; pack-host-installer.ps1
# then bundles its bin\*.dll into the installer. LIBCLANG_PATH is in the runner daemon env.
if (-not $env:FFMPEG_DIR) {
@@ -125,14 +130,6 @@ jobs:
cargo clippy --release -- -D warnings; if ($LASTEXITCODE) { throw "pf-vkhdr-layer clippy" }
Pop-Location
- name: Ensure Inno Setup
shell: pwsh
run: |
if (-not (Test-Path 'C:\Program Files (x86)\Inno Setup 6\ISCC.exe') -and -not (Get-Command iscc -ErrorAction SilentlyContinue)) {
Write-Output "installing Inno Setup via choco"
choco install innosetup -y --no-progress
}
- name: Fetch portable bun runtime (build tool + bundled to run the console)
shell: pwsh
run: |
+8 -3
View File
@@ -1,8 +1,9 @@
# Build the punktfunk Windows client as signed MSIX packages (x64 + ARM64) and publish them to
# Gitea's generic package registry, so Windows boxes can download + install a real package (Start
# tile, clean install/uninstall) instead of a loose exe. Runs on the self-hosted Windows runner
# (host mode; scripts/ci/setup-windows-runner.ps1) — the MSVC/WinUI/FFmpeg toolchain + the Windows
# SDK's makeappx/signtool are baked into the runner's daemon env, same as windows.yml.
# tile, clean install/uninstall) instead of a loose exe. Runs on a self-hosted windows-amd64
# runner (host mode; the MSVC/WinUI toolchain comes from unom/infra's windows-runner/, FFmpeg
# self-provisions via the "Ensure Windows toolchain" step below, same as windows.yml) — the
# Windows SDK's makeappx/signtool are baked into the runner's daemon env.
#
# Both arches come off the ONE x64 runner: x86_64 natively, aarch64 cross-compiled (the x64 MSVC
# toolset has the ARM64 cross compiler; the matrix points FFMPEG_DIR at the ARM64 FFmpeg tree). See
@@ -62,6 +63,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Ensure Windows toolchain (WDK, FFmpeg, Inno Setup, ARM64 target)
shell: pwsh
run: ./scripts/ci/ensure-windows-toolchain.ps1
- name: Configure + version
shell: pwsh
run: |
+10 -3
View File
@@ -1,5 +1,8 @@
# Windows client CI — runs on the self-hosted Windows runner (home-windows-1, host mode; see
# scripts/ci/setup-windows-runner.ps1). Build + clippy + fmt + test the WinUI 3 client
# Windows client CI — runs on a self-hosted windows-amd64 runner (host mode; the generic runner +
# toolchain come from unom/infra's windows-runner/; punktfunk's own extras - FFmpeg, WDK, Inno
# Setup, the ARM64 rustup target - self-provision via the "Ensure Windows toolchain" step below, a
# fast no-op once already present, so any runner with that label works with no manual dispatch
# step first). Build + clippy + fmt + test the WinUI 3 client
# (windows-reactor + D3D11/SwapChainPanel + WASAPI + SDL3).
#
# Two architectures from ONE x64 runner: x86_64-pc-windows-msvc natively and
@@ -61,6 +64,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Ensure Windows toolchain (WDK, FFmpeg, Inno Setup, ARM64 target)
shell: pwsh
run: ./scripts/ci/ensure-windows-toolchain.ps1
- name: Configure + toolchain versions
shell: pwsh
run: |
@@ -68,7 +75,7 @@ jobs:
# Per-arch short target root (dodges MAX_PATH; keeps the two legs from sharing target\).
$td = if ('${{ matrix.target }}' -eq 'aarch64-pc-windows-msvc') { 'C:\t-a64' } else { 'C:\t' }
"CARGO_TARGET_DIR=$td" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
# Per-arch FFmpeg import libs (the runner provisions both — setup-windows-runner.ps1).
# Per-arch FFmpeg import libs (provision-windows-punktfunk-extras.ps1 fetches both).
$ff = if ('${{ matrix.target }}' -eq 'aarch64-pc-windows-msvc') { 'C:\Users\Public\ffmpeg-arm64' } else { 'C:\Users\Public\ffmpeg' }
"FFMPEG_DIR=$ff" | Out-File -FilePath $env:GITHUB_ENV -Append -Encoding utf8
rustup target add ${{ matrix.target }}