Make the stable-toolchain signal visible

The advisory job was marked `continue-on-error`, which GitHub renders as
a green check with an annotation — a signal nobody reads. Removed, so a
failure shows as a real red X.

What now keeps it from blocking merges is branch protection: it has to
stay out of the required status checks. That is a repo setting rather
than anything in this file, so it is called out in ci.yml and CLAUDE.md.
Expect the job red occasionally through no fault of the change under
test; that is the cost of it being visible.

Also runs weekly (Mondays 06:00 UTC). A Rust release lands on its own
schedule, so on push/PR alone breakage could sit unnoticed for weeks.
The pinned `test` and `msrv` jobs skip scheduled runs — a pinned
toolchain against a locked dependency graph cannot change on a timer.

Adds a top-level `permissions: contents: read`, since the workflow needs
nothing more.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-10-23 19:14:44 -04:00
co-authored by Claude Opus 5
parent aa802bc40c
commit 935690c8f0
3 changed files with 40 additions and 13 deletions
+21 -5
View File
@@ -4,13 +4,24 @@ on:
push: push:
branches: [main] branches: [main]
pull_request: pull_request:
schedule:
# Mondays 06:00 UTC. A new Rust release lands on its own schedule, so
# without this the advisory `stable` job below only runs when someone
# happens to push, and breakage can sit unnoticed for weeks.
- cron: '0 6 * * 1'
env: env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
permissions:
contents: read
jobs: jobs:
test: test:
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Nothing it covers can change on a timer: the toolchain is pinned and
# the dependencies are locked. The weekly run is for `stable` only.
if: github.event_name != 'schedule'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
# Pinned, and kept in step with `devVersion` in flake.nix, so CI and # Pinned, and kept in step with `devVersion` in flake.nix, so CI and
@@ -27,6 +38,7 @@ jobs:
msrv: msrv:
name: Build on the declared MSRV name: Build on the declared MSRV
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name != 'schedule'
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
# Must match `rust-version` in Cargo.toml and `msrvVersion` in # Must match `rust-version` in Cargo.toml and `msrvVersion` in
@@ -38,11 +50,15 @@ jobs:
stable: stable:
name: Latest stable (advisory) name: Latest stable (advisory)
runs-on: ubuntu-latest runs-on: ubuntu-latest
# Advisory only. The pinned `test` job is the gate; this one exists so # Deliberately NOT `continue-on-error`: a failure here should render as
# that a new stable release breaking the build or firing a new clippy # a real red X, not a green check with an annotation nobody reads.
# lint is visible before the pin moves, without failing a pull request #
# that did not cause it. Check it when bumping `devVersion`. # This job is advisory all the same — it tracks a moving toolchain, so a
continue-on-error: true # new clippy lint can break it through no fault of the change under
# test. **Keep it out of the required status checks** in branch
# protection; that, rather than a flag in this file, is what stops it
# blocking merges. Expect it red sometimes, and fix it when bumping
# `devVersion`.
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable - uses: dtolnay/rust-toolchain@stable
+4 -3
View File
@@ -12,9 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- A declared minimum supported Rust version of **1.88**, verified by running - A declared minimum supported Rust version of **1.88**, verified by running
the test suite against it. The floor comes from the dependency graph the test suite against it. The floor comes from the dependency graph
(`reqwest` → `url` → `idna` → `icu_*`), not from this crate's own code. (`reqwest` → `url` → `idna` → `icu_*`), not from this crate's own code.
CI builds on both the MSRV and the pinned dev toolchain, plus an advisory CI builds on both the MSRV and the pinned dev toolchain, plus a weekly
job on latest stable that reports breakage from a new Rust release advisory job on latest stable that reports breakage from a new Rust
without gating pull requests. release. The advisory job fails visibly rather than silently; it is kept
non-blocking through branch protection rather than `continue-on-error`.
- Wrappers for every one of the API's 34 `Route::resource` groups, plus - Wrappers for every one of the API's 34 `Route::resource` groups, plus
`users` — 265 methods. See `COVERAGE.md` for the per-endpoint inventory. `users` — 265 methods. See `COVERAGE.md` for the per-endpoint inventory.
- `COVERAGE.md`, a detailed record of what is wrapped, what is not, and why, - `COVERAGE.md`, a detailed record of what is wrapped, what is not, and why,
+15 -5
View File
@@ -23,12 +23,22 @@ Two versions are pinned, and **three places must agree** when either moves:
| Dev toolchain | 1.99.1 | `devVersion` in `flake.nix`, `test` job in `ci.yml` | | Dev toolchain | 1.99.1 | `devVersion` in `flake.nix`, `test` job in `ci.yml` |
| MSRV | 1.88 | `msrvVersion` in `flake.nix`, `rust-version` in `Cargo.toml`, `msrv` job in `ci.yml` | | MSRV | 1.88 | `msrvVersion` in `flake.nix`, `rust-version` in `Cargo.toml`, `msrv` job in `ci.yml` |
CI has a third job, `stable`, which tracks latest stable and is marked CI has a third job, `stable`, which tracks latest stable and runs weekly
`continue-on-error`. It is **advisory, not a gate**: it exists so a new (Mondays, via `schedule`) as well as on push and PR. It exists so a new
Rust release that breaks the build or fires a new clippy lint shows up Rust release that breaks the build or fires a new clippy lint shows up
before the pin moves, without failing a pull request that did not cause it. before the pin moves. Check it when bumping `devVersion` — if it is red,
Check it when bumping `devVersion` — if it is red, the bump needs work the bump needs work first. Nothing needs to stay in sync with it.
first. Nothing needs to stay in sync with it.
**It is advisory, but it reports red.** There is deliberately no
`continue-on-error`, because a green check with an annotation is a signal
nobody reads. That means **it must stay out of the required status checks**
in branch protection — that repo setting, not anything in `ci.yml`, is what
keeps it from blocking merges. Expect it red occasionally through no fault
of the change under test; that is the tradeoff for it being visible.
The pinned `test` and `msrv` jobs skip scheduled runs (`if:
github.event_name != 'schedule'`), since a pinned toolchain against a
locked dependency graph cannot change on a timer.
The MSRV is set by the **dependency graph**, not by this crate's code: The MSRV is set by the **dependency graph**, not by this crate's code:
`reqwest` pulls in `url` → `idna` → `idna_adapter` → `icu_*`, and the `icu` `reqwest` pulls in `url` → `idna` → `idna_adapter` → `icu_*`, and the `icu`