Bump the workflow image pin to the 2026.06.14 tag that bakes in
wasm-tools. And keep the wasm-tools download/caching steps for the macOS
and Windows jobs — but skip those steps on Linux. So, the Linux jobs use
the wasm-tools copy the image installs.
Follow-up to https://github.com/LadybirdBrowser/ladybird/pull/9972
Cache the wasm-tools binary rather than doing (trying) a re-fetch of it
on every build job. And when we ever do need to re-download it (after a
cache miss), then do it with some sensible retry-with-backoff-and-wait.
Otherwise, a single network hiccup when trying to download wasm-tools
was failing multiple CI jobs at once — before their builds even started.
Let's not depend on a nightly pre-release, especially not just for a
linting option. We can enable the linter option once it lands in the
stable release.
Problem: A new upstream nightly Rust release made all CI lint code
checks fail in the Set Up Environment step
Cause: CI runs “rustup toolchain install nightly --component rustfmt”.
The runner container ships nightly with rustfmt and clippy preinstalled.
But “rustup toolchain install” treats an existing channel as an upgrade
target, and tries to refresh it whenever a newer nightly is available.
The refresh removes the old clippy component first, renaming
/opt/rustup/toolchains/.../share/doc/clippy into /opt/rustup/tmp/, and
those two directories live on different overlayfs mounts in the
container — so the rename fails with EXDEV.
Fix: Replace “rustup toolchain install nightly --component rustfmt” with
“rustup component add rustfmt --toolchain nightly”. That adds the
component to the existing toolchain without checking for or applying a
channel update — so the cross-mount-rename path is never reached.
Because the container already provisions rustfmt + clippy at build time,
the new command is effectively a no-op on healthy containers, and fails
loudly only if a future container loses the nightly toolchain.
By default, `rustfmt` persists the import granularity. In practice, most
Rust code has import granularity "Module" due to LSP's actions.
"Item" gets rid of import groupings and achieves cleaner diffs and
better conflict resolution. Better greppability is a positive side
effect.
Note: it's an unstable rustfmt feature. `cargo +nightly fmt` must be
used instead of `cargo fmt`.
This means running the build inside a Docker container based on a (more)
stable build image.
* The setup action is now largely simplified for Linux.
* We hardcode llvm@21 for macOS since it allows us to get rid of
specifying llvm_version as an input variable. Since we no longer
support switching the LLVM version on Linux via that variable, this
seems like the best course of action.
We use a trick to optionally introduce a container image: `fromJSON()`
allows `null` as a return value, which causes the job to execute on the
runner directly. We need this for macOS and Windows jobs.
The idea is that scripts directly under Meta are meant to be run by
people. Scripts that are only imported or run by other scripts are
moved to a subdirectory.
We switched to macOS since it was easier to install swift-format in CI.
With that removed, let's switch back to Linux, as macOS runners tend to
have higher contention.
To do so, this makes more use of the setup action. This way, the setup
action is the only place that needs to know how to install the apt repos
we need (LLVM in particular).
The Rust-based LibJS codegen is now enabled by default on non-Windows
platforms, so CI runners need rustc and cargo available. Add the
dtolnay/rust-toolchain action to install a stable Rust toolchain.
Set the gcc and llvm versions as variables, and use them anywhere we
install a specific version. We then export these as outputs so that any
interested caller can retrieve the installed versions.
Our check for llvm.list also will have prevented us from upgrading llvm
versions. We now check that it contains the exact version we expect.
This makes it easier to ensure everyone is using the same version of
Swift when building the project, especially for CI environments.
`swiftly install` will automatically read this file and install the
specified version if it is not already installed. It also tells swiftly
what version to use for the project, independent of the global default
version.
Swift jobs were failing a test due to the llvm-symbolizer not being
available in the default location next to the clang binary. swift.org
toolchains don't ship this tool, so LSAN suppressions were not being
applied, failing TestWOFF2.
This was hard to reproduce locally, because I have always had a set of
alternatives set up for the full suite of LLVM tools on my machine.
For our js-benchmarks and libjs-test262 workflow runs, we already know
that they're provisioned with these repositories and can skip adding the
key and repo altogether.
We were using both wget and curl arbitrarily; use curl exclusively since
that is installed by default on our machines and containers. Fixes the
js-benchmarks workflow.