ci: add Windows and Linux canary workflows with caching#2642
Open
wpfleger96 wants to merge 4 commits into
Open
ci: add Windows and Linux canary workflows with caching#2642wpfleger96 wants to merge 4 commits into
wpfleger96 wants to merge 4 commits into
Conversation
Adds windows-canary.yml and linux-canary.yml — workflow_dispatch builds that produce unsigned installable artifacts (NSIS .exe, .deb + .AppImage) from any ref without touching the release pipeline. Also retrofits signed-macos-canary.yml with the same caching (Rust + pnpm) so all three canary builds warm quickly on repeat dispatches. Key design decisions: - Both new workflows accept a ref input (default: main); no Require-main guard needed because they are unsigned, contents:read, and zero-secrets. The macOS canary requires main because it runs OIDC signing/notarization. - Rust cache uses Swatinem/rust-cache with workspaces covering both the workspace root (sidecar --release builds) and desktop/src-tauri (Tauri build). shared-key is scoped per platform + canary-release so dispatched runs share cache without colliding with CI's debug-profile keys (CI Windows does clippy/check, not --release). - pnpm caching uses the explicit store restore/save pattern from ci.yml (not setup-node package-manager-cache) for consistency across all three canaries. Safe here because all three jobs are contents:read and artifact-only; release-windows disables pnpm caching because that job is contents:write feeding a signed installer (cache poisoning vector). - Linux job mirrors release-linux: same ubuntu:22.04 container + apt deps, pinned appimagetool 1.9.1 + type2-runtime 20251108, rui314/setup-mold for faster link times, fix-appimage.sh run without signing env vars (script guards on TAURI_SIGNING_PRIVATE_KEY and skips re-signing when absent — repacking still removes the Mesa/GLib/GStreamer conflict libs). - createUpdaterArtifacts: false in all canary configs; no signing keys, updater endpoints, or GitHub Release machinery required. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
rust-toolchain.toml pins channel = 1.95.0; windows-latest runners ship with rustup preinstalled and honor it automatically. The dtolnay action is unnecessary here and triggers a zizmor impostor-commit error because its SHA cannot be verified through normal git history traversal. Matches the pattern used by the ci.yml windows-rust job, which also relies on the preinstalled rustup without the dtolnay action. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
SHA df4cb1c069e1874edd31b4311f1884172cec0e10 is exactly tag v6.0.3; update the comment in all three canary files to match so zizmor's ref-version-mismatch audit passes cleanly. Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
workflow_dispatch executes on the dispatch ref, so github.ref/github.sha stay main-scoped even when inputs.ref checks out a feature branch. Without a guard, a dispatch from main with a non-main inputs.ref and an unchanged lockfile writes into the main-scoped pnpm and Rust cache namespaces under the same keys as CI — a cache-poisoning path. Fix in windows-canary.yml and linux-canary.yml: - rust-cache: add save-if that requires both github.ref == refs/heads/main and inputs.ref == main; restores stay unconditional - pnpm actions/cache/save: same if: condition - add Capture source SHA step (git rev-parse HEAD → step output) after checkout; use steps.source.outputs.sha in artifact names and env-var indirection (SOURCE_SHA) in run: bodies for the log line - update file header comments to explain the cache safety model signed-macos-canary.yml is unchanged (its main-only guard makes all cache saves trusted by construction). Co-authored-by: Will Pfleger <pfleger.will@gmail.com> Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
wpfleger96
enabled auto-merge (squash)
July 23, 2026 23:28
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.
Adds
windows-canary.ymlandlinux-canary.yml—workflow_dispatchjobs that produce unsigned installable artifacts (.exe NSIS installer, .deb + .AppImage) from any ref without touching the release pipeline. Also retrofitssigned-macos-canary.ymlwith Rust and pnpm caching so all three canary builds warm quickly on repeat dispatches.What this adds
windows-canary.yml—windows-latestrunner,rust-toolchain.tomlin the repo root pins the toolchain via preinstalled rustup (rustup target addto register the MSVC target),pnpm install --frozen-lockfile, sidecarscargo build --release,pnpm tauri build --bundles nsiswithcreateUpdaterArtifacts:false. Uploads the NSIS.exeas artifactbuzz-windows-canary-<source-sha>, 7-day retention. No mesh-llm (release-windows doesn't build it).linux-canary.yml— sameubuntu:22.04container as the release job, same apt deps block, pinnedappimagetool 1.9.1+type2-runtime 20251108, hermit, mold,just desktop-install-ci, sidecars,pnpm tauri build --bundles deb,appimage. Runsfix-appimage.shwithout signing env vars (the script detects their absence and skips re-signing; repacking still removes the Mesa/GLib/GStreamer conflict libs). Uploads.deb+.AppImageasbuzz-linux-canary-<source-sha>, 7-day retention.signed-macos-canary.yml— addsSwatinem/rust-cache(workspace root +desktop/src-tauri) and the pnpm store restore/save pattern. The existing mesh-llama cache is unchanged.Design decisions vs.
signed-macos-canary.ymlThe macOS canary has a
Require mainguard because it runs OIDC signing/notarization — the OIDC token scope is tied to the ref. The Windows and Linux canaries arecontents: read, unsigned, and zero-secrets, so building arbitrary refs is safe and is the entire point: pre-merge Windows/Linux testing without local toolchains.Caching rationale
Swatinem/rust-cachewithworkspaces: . \n desktop/src-tauricovering both the sidecar--releasebuild and the Tauri build.shared-keyscoped to<platform>-canary-release— canary runs warm each other without colliding with CI's debug-profile keys (CI Windows runs clippy/check, not--release).ci.yml:149-196. Restores are unconditional (a cold miss is safe). Saves are conditional:workflow_dispatchexecutes on the dispatch ref, sogithub.ref/github.shastay main-scoped even wheninputs.refchecks out a feature branch. Without a guard, a dispatch from main with a non-maininputs.refand an unchanged lockfile would write into the main-scoped pnpm cache under the same key as CI — a cache-poisoning path. Theactions/cache/savestep and the rust-cachesave-ifboth requiregithub.ref == 'refs/heads/main' && inputs.ref == 'main'.signed-macos-canary.ymlis unaffected (its main-only guard makes all saves trusted).rui314/setup-moldon Linux to reduce link time, matching the Linux Rust CI jobs.timeout-minutes: 60on all three — generous enough for the cold path.Artifact provenance
github.shastays the dispatch-ref (main) SHA regardless ofinputs.ref. A "Capture source SHA" step immediately after checkout resolvesgit rev-parse HEADinto a step output; artifact names and log lines use that resolved SHA so an artifact built from a feature branch is unambiguously named.Zizmor hygiene
All three workflows: every action pinned by full commit SHA (matching
ci.yml/release.ymlpins),persist-credentials: falseon checkouts, top-levelpermissions: contents: read, no${{ }}interpolation directly inrun:bodies (env-var indirection throughout),if: github.repository == 'block/buzz'on jobs,refinput flows throughactions/checkout ref:.