Macros close over the context of the template that imports them, at import time. Importing the CAPTCHA component from a child template ran before `base.html` defined `_`, so the noscript translation inside the macro failed with an undefined-not-callable error. Import it from `base.html` like every other component.
One pinned step now installs pnpm, Node.js and the dependencies. `require-lockfile: true` keeps the `--frozen-lockfile` semantics, `cache: true` keeps the pnpm store cache.
`pnpm/setup` reads the runtime version from `package.json` and ignores `.node-version`. With `onFail: download`, pnpm records Node 24.15.0 in the lockfile and downloads it on every install unless `--no-runtime` is passed. The Dockerfile and the docs build pass it, since they already run a pinned Node. `.node-version` stays for the Cloudflare Pages build, which reads it to pick the Node that bootstraps corepack.
`comment_width = 80` counts the whole line, indentation included, which
wraps far more aggressively than intended; the latest nightly rustfmt
(rust-lang/rustfmt#6802) started enforcing it on comments it previously
left alone. Turn `wrap_comments` off rather than reformat everything.
`max_width = 100`, `comment_width = 80` and `use_small_heuristics =
"Default"` are rustfmt's defaults, so drop them too; only the two
nightly-only import options remain.
The oidc-client integration tests read the real system clock through a
`now()` helper. The ID token builder generates a fresh RSA key before
stamping `iat`, while each test captured its own `now` earlier for
verification. Under coverage instrumentation on a loaded CI runner, the
two key generations in `fail_verify_id_token_wrong_auth_time` took more
than the 5 minute `iat` leeway, so verification failed on `iat` before
ever reaching the `auth_time` check the test asserts on.
Make the helper return a frozen `MockClock` timestamp instead. Every
token and verification in the binary now shares one instant, so setup
duration can no longer affect the outcome, and the clippy opt-out for
`Utc::now()` goes away.
Matrix 1.17 requires servers that don't support the legacy
authentication API to reject `m.login.application_service` on
`/login` with a 400 and the `M_APPSERVICE_LOGIN_UNSUPPORTED` error
code. Previously this login type fell through the generic unsupported
credentials path and returned `M_UNKNOWN`, which appservices written
against Matrix 1.17 can't distinguish from an unrelated failure.
Matrix 1.17 requires servers that don't support the legacy
authentication API to reject `m.login.application_service` on
`/login` with a 400 and the `M_APPSERVICE_LOGIN_UNSUPPORTED` error
code. The test fails until the errcode is implemented.
The `rust-toolchain` ecosystem updates the `channel` in `rust-toolchain.toml`, which is now the only place the Rust version is written down. Weekly with the usual 14-day cooldown, so the `.1` point release has usually landed by the time the PR opens.
The builder stage starts from `buildpack-deps` (what the `rust:` image is built on anyway), installs a pinned `rustup-init` with `--default-toolchain none`, copies only `rust-toolchain.toml` and lets rustup install the toolchain it names. The Rust version is now written in exactly one place, shared with CI, so a toolchain bump needs no Dockerfile edit.
The toolchain layer is cached on the content of `rust-toolchain.toml` and the base image, and it is the same bytes we pulled as `rust:` image layers before, so build times are unchanged.
The registry cache mount also moves to `/usr/local/cargo/registry`: the `rust:` image already set `CARGO_HOME=/usr/local/cargo`, so the previous `/root/.cargo/registry` mount never held anything.
Until now only the clippy CI job and the Dockerfile named a Rust version (kept in sync by hand), while every other CI job, the release binaries and the docs build ran on whatever `stable` happened to be that day. Rust 1.98.0 landing on 2026-08-20 broke `build-binaries` overnight because of that (#5935).
`rust-toolchain.toml` pins 1.96.0 with the `minimal` profile plus clippy, and every `rustup toolchain install stable ...` in CI becomes a bare `rustup toolchain install`, which reads the file. Starting at 1.96.0 (the version clippy is already clean against) keeps this change free of lint churn; catching up to 1.98.0 is a follow-up.
rustfmt stays on nightly because `.rustfmt.toml` uses nightly-only options, so that job now invokes `cargo +nightly fmt` explicitly instead of setting a rustup directory override, which would silently take precedence over the toolchain file.
The file does not list the linux cross-compilation targets on purpose: that would make every developer and CI job download `rust-std` they never use. The two consumers that cross-compile add the targets themselves.