ci: restore the Rust cache with rust-cache and a weekly run on main (#234)
The runner's cache server is reachable again since the VPS fix of 2026-10-03 (cache proxy pinned to port 28100, ufw rule scoped to the Docker job networks; diagnosed in #374). Bring caching back to check-rust through Swatinem/rust-cache, as #232 deferred. forgejo-runner v12.7.0 keeps what a pull_request run saves private to that PR, so PR runs alone would only warm later pushes to the same PR. A weekly scheduled run on main (Mondays 06:30 UTC) and workflow_dispatch write the shared entries that every PR falls back to. rust-cache v2.9+ declares node24 and the runner starts JavaScript actions with the container's node, so the job now installs Node.js 24. zstd is installed for faster, smaller cache archives. No npm cache in check-frontend, by decision: with per-PR isolation it would only serve later pushes of a PR, and npm ci takes 9s there. audit.yml loses two comments this change makes false. No CHANGELOG entry: CI configuration only. Refs #234 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
0e4fef5ad7
commit
cf1da2bea0
3 changed files with 60 additions and 26 deletions
|
|
@ -2,14 +2,14 @@ name: Security audit
|
||||||
|
|
||||||
# Daily RustSec coverage (#232).
|
# Daily RustSec coverage (#232).
|
||||||
#
|
#
|
||||||
# check-rust.yml only runs when src-tauri/ changes, which is roughly 1 PR in
|
# check-rust.yml runs on PRs that change src-tauri/ and once a week on main,
|
||||||
# 40 — without this workflow a new advisory published against an unchanged
|
# and its cargo audit step never fails the job — without this workflow a new
|
||||||
# dependency would go unnoticed for weeks.
|
# advisory published against an unchanged dependency would go unnoticed.
|
||||||
#
|
#
|
||||||
# Runs without a Rust toolchain: cargo-audit only reads Cargo.lock, so the
|
# 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
|
# 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
|
# this to ~1 min, where a daily check-rust would hold the capacity-1 runner
|
||||||
# every day on a capacity-1 runner.
|
# for several minutes.
|
||||||
#
|
#
|
||||||
# Note: PATH is deliberately NOT overridden at job level (unlike check-rust,
|
# 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
|
# which needs /root/.cargo/bin for the toolchain) so that the install dir
|
||||||
|
|
@ -44,8 +44,9 @@ jobs:
|
||||||
apt-get update
|
apt-get update
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
curl ca-certificates git tar gzip
|
curl ca-certificates git tar gzip
|
||||||
# Node.js is required by actions/checkout and taiki-e/install-action
|
# Node.js is required by actions/checkout, a JavaScript action that
|
||||||
# (JavaScript actions need `node` in the container PATH).
|
# needs `node` in the container PATH (taiki-e/install-action is a
|
||||||
|
# composite action).
|
||||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||||
apt-get install -y nodejs
|
apt-get install -y nodejs
|
||||||
node --version
|
node --version
|
||||||
|
|
|
||||||
|
|
@ -50,10 +50,11 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: https://github.com/actions/checkout@v4
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
|
||||||
# No npm cache step here, deliberately — same reason as the cargo caches
|
# No npm cache step, by decision (#234). The runner's cache works since
|
||||||
# in check-rust.yml: the restore misses and the save times out against
|
# 2026-10-03, but it keeps what a pull_request run saves private to that
|
||||||
# the runner's cache server (#234), which cost ~23s per run for nothing.
|
# PR, and this workflow runs on PRs only: a cache would serve later
|
||||||
# Restore it together with rust-cache once #234 is fixed.
|
# 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
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,10 @@ name: PR Check — Rust
|
||||||
|
|
||||||
# Rust half of the former check.yml (split in #232).
|
# 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
|
# Runs on PRs that change Rust, plus once a week on main to refresh the shared
|
||||||
# src-tauri/, and the runner has capacity 1 — jobs queue instead of running in
|
# cache (see the note on the triggers). The runner has capacity 1 — jobs queue
|
||||||
# parallel, so every minute spent here is a minute the next PR waits.
|
# 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
|
# No `branches:` filter on purpose. `branches: [main]` never matched a PR
|
||||||
# stacked on top of another feature branch, which is what /autopilot produces:
|
# 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
|
# (rustflags, linker, target dir) would change the Rust build, and an
|
||||||
# exact-path entry would let it skip Rust CI unnoticed.
|
# exact-path entry would let it skip Rust CI unnoticed.
|
||||||
- '.cargo/**'
|
- '.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.
|
# 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
|
# Distinct from the frontend group: a shared group would make the two
|
||||||
|
|
@ -37,22 +58,27 @@ jobs:
|
||||||
env:
|
env:
|
||||||
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
PATH: /root/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
CARGO_TERM_COLOR: always
|
CARGO_TERM_COLOR: always
|
||||||
# Nothing persists between runs (see the caching note below), so
|
# rust-cache keeps the dependencies and drops this crate's own artifacts
|
||||||
# incremental artifacts get written and never reused — pure overhead.
|
# before saving, so incremental data would never be reused — pure
|
||||||
# Test debug info is dead weight here for the same reason.
|
# overhead — and test debug info would only make the cached target/
|
||||||
|
# bigger.
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
CARGO_PROFILE_TEST_DEBUG: 0
|
CARGO_PROFILE_TEST_DEBUG: 0
|
||||||
steps:
|
steps:
|
||||||
- name: Install system dependencies, Node.js and Rust
|
- name: Install system dependencies, Node.js and Rust
|
||||||
run: |
|
run: |
|
||||||
apt-get update
|
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 \
|
apt-get install -y --no-install-recommends \
|
||||||
curl wget git ca-certificates build-essential pkg-config \
|
curl wget git ca-certificates build-essential pkg-config \
|
||||||
libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libssl-dev \
|
libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev libssl-dev \
|
||||||
libdbus-1-dev
|
libdbus-1-dev zstd
|
||||||
# Node.js is required by actions/checkout and taiki-e/install-action
|
# Node.js runs the JavaScript actions: actions/checkout (node20) and
|
||||||
# (they are JavaScript actions and need `node` in the container PATH).
|
# Swatinem/rust-cache (node24 since v2.9). The runner starts them
|
||||||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
# 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
|
apt-get install -y nodejs
|
||||||
# Rust toolchain
|
# Rust toolchain
|
||||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable --profile minimal
|
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
|
- name: Checkout
|
||||||
uses: https://github.com/actions/checkout@v4
|
uses: https://github.com/actions/checkout@v4
|
||||||
|
|
||||||
# No actions/cache step here, deliberately. The job container cannot
|
# Caches ~/.cargo (registry, git, bin) and src-tauri/target, keyed on the
|
||||||
# reach the runner's cache server (#234): the restore times out into a
|
# rustc version, the Cargo manifests and lockfile, and this job. Saved
|
||||||
# miss AND the save times out, so the cache cost ~7 min per run and
|
# only when the job succeeds and the key was not an exact hit. Served by
|
||||||
# returned nothing. Bring caching back through Swatinem/rust-cache once
|
# the runner's cache proxy on port 28100, which ufw opens to the Docker
|
||||||
# #234 is fixed — not before, it shares the same backend.
|
# 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
|
- name: cargo check
|
||||||
run: cargo check --manifest-path src-tauri/Cargo.toml --all-targets
|
run: cargo check --manifest-path src-tauri/Cargo.toml --all-targets
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue