Conversation
Windows CI rebuilds everything from scratch on every run for one reason: the set-cargo-target-dir anchor sends Linux to $HOME/actions-runner/_work/target, outside the workspace, and everything else to $GITHUB_WORKSPACE/target -- which checkout wipes each run. Windows also never had sccache enabled at all. Point Windows at C:/actions-runner/_work/target and enable sccache there, mirroring the Linux setup already on master. The Windows branch is gated on the runner work directory existing, so GitHub-hosted windows-latest jobs keep their current workspace-local behaviour. RUSTC_WRAPPER is set to an explicit C:/sccache/sccache.exe rather than the result of `command -v`: these steps run under Git Bash, whose `command -v` returns an MSYS path (/c/sccache/sccache.exe) that Cargo, a native Windows process, cannot execute. The `command -v` guard is kept only to detect whether the runner image was warmed, so an unwarmed image degrades to a cold but working build instead of failing. The Windows-only actions/cache entries for rusty_v8 and vendored OpenSSL are deliberately left in place for this iteration. Requires a runner image warmed by warm-cache-windows.ps1 in clockworklabs/infra. Without it these paths are simply empty and builds behave as they do today.
jdetter
marked this pull request as draft
September 16, 2026 04:35
Points upload-build-artifacts-windows, smoketest_build_windows and smoketest_partitions_windows at spacetimedb-windows-runner-staging so this PR can be qualified against runner image vm26, which carries the warmed sccache store and dependency-only Cargo target. This commit exists only to measure the effect and MUST be reverted before merge. Leaving it in would send all production Windows CI to the staging pool. The windows-latest matrix in the update-flow job is deliberately untouched -- it runs on GitHub-hosted runners and has no warmed image. Revert with: git revert <this commit>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description of Changes
Windows CI rebuilds everything from scratch on every run, and the cause is a single
elsebranch.The
set-cargo-target-diranchor sends Linux to$HOME/actions-runner/_work/target— outside the workspace, so it survives — and sends everything else to$GITHUB_WORKSPACE/target, whichactions/checkoutwipes at the start of each run. Windows also never had sccache enabled at all: theConfigure sccachestep is gatedif: runner.os == 'Linux'.This change points Windows at
C:/actions-runner/_work/targetand enables sccache there, mirroring the Linux setup already onmaster. Three steps touched, +29/−5:&set-cargo-target-dir— adds a Windows branch. Gated on the runner work directory existing, so GitHub-hostedwindows-latestjobs (theupdate-flowmatrix) keep their current workspace-local behaviour. macOS unchanged.Configure sccache— widened fromrunner.os == 'Linux'to also cover Windows, withSCCACHE_DIR=C:/actions-runner/_work/sccache.Show sccache statistics— widened the same way.These are shared YAML anchors, so the Linux path is worth checking explicitly in review; it is unchanged in effect, but the diff touches code Linux jobs execute.
RUSTC_WRAPPERis set to an explicitC:/sccache/sccache.exerather than the output ofcommand -v. These steps run under Git Bash, whosecommand -vreturns an MSYS path (/c/sccache/sccache.exe) that Cargo — a native Windows process — cannot execute. Thecommand -vguard is kept purely to detect whether the runner image was warmed, so an unwarmed image degrades to a cold but working build rather than failing outright.The Windows-only
actions/cacheentries for rusty_v8 objects and vendored OpenSSL are deliberately left in place for this iteration, as cheap insurance while the warmed image is unproven. They are the obvious follow-up removal once hit rates are demonstrated.Measured on the golden image, so expectations are calibrated
Comparing the warm's population pass against its seed pass (cold target, warm sccache — roughly what a CI job sees):
The read-only verifier reports 100% hit rate, but on a small cacheable set — sccache logged 930 calls non-cacheable for
crate-typeduring the warm. sccache cannot cache linking, build-script output, or proc macros, and on Windows the release link ofspacetimedb-cliandspacetimedb-standalonedominates. The larger win should come from the warm target directory carrying rusty_v8 and vendored OpenSSL, which sccache structurally cannot help with.Measured staging qualification
Measured in Actions run 35128480324 using warmed image
github-windows-runner-vm26.qcow2. The baseline is the median job wall time from three successfulmasterruns on the production vm25 pool. Durations exclude queue time.mastermedianFor a production-sized pool, the Windows pipeline critical path is upload + smoketest build + the slowest partition. Using the same medians, that falls from 22m29s to 18m30s, a 17.7% reduction. The staging pool had only one Windows VM, so its observed queue-to-finish wall clock is not representative of production concurrency.
The release artifact build is the strongest cache signal: it beat the fastest of the three baseline runs (3m15s versus 3m45s). The smoketest build's 20-second regression remains inside the baseline's existing 3m11s–4m08s spread. Partition jobs do not compile Rust, so their gains should be treated as runner/run variance rather than attributed to the Cargo cache.
sccache itself contributed almost nothing:
The meaningful improvement therefore comes from the baked Cargo target avoiding compiler requests entirely, not from sccache serving objects. This is consistent with the image being warmed at commit
37476b30while this branch builds a later commit, and with workspace-owned artifacts being deliberately pruned before sealing.API and ABI breaking changes
None. CI configuration only — no crate, module, client SDK, or on-disk format is touched.
Rollback safety impact
n/a
Expected complexity level and risk
1 - this is just a CI change
Testing
The warm and verification have been exercised end to end on the Windows golden image (details and logs in infra#1349), and the complete Windows path passed on the staging vm26 runner in Actions run 35128480324.
All warmed sccache probes passedrust-toolchain.tomlrather than the image default 1.94.1 — warming on the wrong compiler yields a 100% miss rate while still appearing to succeedci.ymlparses as valid YAML, and the Linux branches of all three modified steps are unchanged in effectspacetimedb-windows-runner-staging, all six Windows jobs passed and the measured results are recorded abovemaster703a08cc1Authored by OpenClaw (an AI agent) on John Detter's infrastructure, at his direction. Reviewed by no human yet — please read it as you would any unreviewed change.