diff --git a/.forgejo/workflows/audit.yml b/.forgejo/workflows/audit.yml index 752c561..34c794e 100644 --- a/.forgejo/workflows/audit.yml +++ b/.forgejo/workflows/audit.yml @@ -2,14 +2,14 @@ name: Security audit # Daily RustSec coverage (#232). # -# check-rust.yml only runs when src-tauri/ changes, which is roughly 1 PR in -# 40 — without this workflow a new advisory published against an unchanged -# dependency would go unnoticed for weeks. +# check-rust.yml runs on PRs that change src-tauri/ and once a week on main, +# and its cargo audit step never fails the job — without this workflow a new +# advisory published against an unchanged dependency would go unnoticed. # # Runs without a Rust toolchain: cargo-audit only reads Cargo.lock, so the # binary is invoked directly instead of as a `cargo` subcommand. That keeps -# this to ~1-2 min rather than the ~22 min a scheduled check-rust would cost -# every day on a capacity-1 runner. +# this to ~1 min, where a daily check-rust would hold the capacity-1 runner +# for several minutes. # # Note: PATH is deliberately NOT overridden at job level (unlike check-rust, # which needs /root/.cargo/bin for the toolchain) so that the install dir @@ -44,8 +44,9 @@ jobs: apt-get update apt-get install -y --no-install-recommends \ curl ca-certificates git tar gzip - # Node.js is required by actions/checkout and taiki-e/install-action - # (JavaScript actions need `node` in the container PATH). + # Node.js is required by actions/checkout, a JavaScript action that + # needs `node` in the container PATH (taiki-e/install-action is a + # composite action). curl -fsSL https://deb.nodesource.com/setup_20.x | bash - apt-get install -y nodejs node --version diff --git a/.forgejo/workflows/check-frontend.yml b/.forgejo/workflows/check-frontend.yml index a5e0905..24ae6c5 100644 --- a/.forgejo/workflows/check-frontend.yml +++ b/.forgejo/workflows/check-frontend.yml @@ -50,10 +50,11 @@ jobs: - name: Checkout uses: https://github.com/actions/checkout@v4 - # No npm cache step here, deliberately — same reason as the cargo caches - # in check-rust.yml: the restore misses and the save times out against - # the runner's cache server (#234), which cost ~23s per run for nothing. - # Restore it together with rust-cache once #234 is fixed. + # No npm cache step, by decision (#234). The runner's cache works since + # 2026-10-03, but it keeps what a pull_request run saves private to that + # PR, and this workflow runs on PRs only: a cache would serve later + # pushes to the same PR, while `npm ci` takes 9s here (run 456) and + # each PR's first run would pay for the save. - name: Install dependencies run: npm ci diff --git a/.forgejo/workflows/check-rust.yml b/.forgejo/workflows/check-rust.yml index 9a66f85..6a4f371 100644 --- a/.forgejo/workflows/check-rust.yml +++ b/.forgejo/workflows/check-rust.yml @@ -2,9 +2,10 @@ name: PR Check — Rust # Rust half of the former check.yml (split in #232). # -# Only runs when Rust actually changes. On this repo roughly 1 PR in 40 touches -# src-tauri/, and the runner has capacity 1 — jobs queue instead of running in -# parallel, so every minute spent here is a minute the next PR waits. +# Runs on PRs that change Rust, plus once a week on main to refresh the shared +# cache (see the note on the triggers). The runner has capacity 1 — jobs queue +# instead of running in parallel, so every minute spent here is a minute the +# next PR waits. # # No `branches:` filter on purpose. `branches: [main]` never matched a PR # stacked on top of another feature branch, which is what /autopilot produces: @@ -19,6 +20,26 @@ on: # (rustflags, linker, target dir) would change the Rust build, and an # exact-path entry would let it skip Rust CI unnoticed. - '.cargo/**' + # The weekly run is what feeds the cache to pull requests (#234). The runner + # (forgejo-runner v12.7.0) isolates what a pull_request run writes to that + # PR's ref: later pushes to the same PR read it back, other PRs never see it. + # A PR run falls back to the shared, non-isolated entries only when nothing + # matches in its own scope. Scheduled and dispatched runs write to the shared + # scope, which makes them this workflow's only writers of it (a merged PR's + # `closed` event would be another, but this workflow does not subscribe to + # it). + # + # The runner deletes an entry unused for 7 days or created more than 30 days + # ago, and the next Monday run saves a fresh one. Cold runs that do not mean + # #234 is back: every new stable Rust until the next Monday (the toolchain + # floats on `stable`, and rustc is part of the cache key); PR runs once an + # entry that only got exact hits, hence never re-saved, reaches 30 days; and, + # after a week without any PR run, possibly the Monday run itself. + # workflow_dispatch re-seeds by hand. + schedule: + # Mondays 06:30 UTC, after audit.yml (06:00 UTC). + - cron: '30 6 * * 1' + workflow_dispatch: # Cancel obsolete runs (e.g. on force-push) so only the latest commit runs. # Distinct from the frontend group: a shared group would make the two @@ -37,22 +58,27 @@ jobs: env: PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin CARGO_TERM_COLOR: always - # Nothing persists between runs (see the caching note below), so - # incremental artifacts get written and never reused — pure overhead. - # Test debug info is dead weight here for the same reason. + # rust-cache keeps the dependencies and drops this crate's own artifacts + # before saving, so incremental data would never be reused — pure + # overhead — and test debug info would only make the cached target/ + # bigger. CARGO_INCREMENTAL: 0 CARGO_PROFILE_TEST_DEBUG: 0 steps: - name: Install system dependencies, Node.js and Rust run: | apt-get update + # zstd: the cache archives are compressed with it when present, + # faster and smaller than the gzip fallback. apt-get install -y --no-install-recommends \ curl wget git ca-certificates build-essential pkg-config \ libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libssl-dev \ - libdbus-1-dev - # Node.js is required by actions/checkout and taiki-e/install-action - # (they are JavaScript actions and need `node` in the container PATH). - curl -fsSL https://deb.nodesource.com/setup_20.x | bash - + libdbus-1-dev zstd + # Node.js runs the JavaScript actions: actions/checkout (node20) and + # Swatinem/rust-cache (node24 since v2.9). The runner starts them + # with whatever `node` the container has, so install the newest + # runtime they declare. taiki-e/install-action is a composite action. + curl -fsSL https://deb.nodesource.com/setup_24.x | bash - apt-get install -y nodejs # Rust toolchain curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal @@ -63,11 +89,17 @@ jobs: - name: Checkout uses: https://github.com/actions/checkout@v4 - # No actions/cache step here, deliberately. The job container cannot - # reach the runner's cache server (#234): the restore times out into a - # miss AND the save times out, so the cache cost ~7 min per run and - # returned nothing. Bring caching back through Swatinem/rust-cache once - # #234 is fixed — not before, it shares the same backend. + # Caches ~/.cargo (registry, git, bin) and src-tauri/target, keyed on the + # rustc version, the Cargo manifests and lockfile, and this job. Saved + # only when the job succeeds and the key was not an exact hit. Served by + # the runner's cache proxy on port 28100, which ufw opens to the Docker + # job networks only; until 2026-10-03 every restore and save timed out + # there (#234, la-compagnie-maximus docs/forgejo-ops.md). What a PR run + # saves stays private to that PR: see the note on the triggers. + - name: Rust cache + uses: https://github.com/Swatinem/rust-cache@v2 + with: + workspaces: "src-tauri -> target" - name: cargo check run: cargo check --manifest-path src-tauri/Cargo.toml --all-targets