CI: nextest, line tables only, one wasm check (#4269)

* CI speed: line tables for workspace crates, no debug info for dependencies

* CI speed: xtask ci runs nextest and doctests, one wasm check, the CLI without default features
This commit is contained in:
aiongg
2026-10-23 13:34:21 -04:00
committed by GitHub
parent cf0f80604f
commit 045c8b39a7
5 changed files with 50 additions and 26 deletions
+6 -6
View File
@@ -89,20 +89,20 @@ dbg_macro = "warn"
todo = "warn"
# `"*"` matches every non-workspace package: crates.io dependencies and the
# vendored crates under `vendor/` (excluded from the workspace). Our own crates
# keep full debug info. Dependencies keep only line tables, so backtraces still
# show file and line, but debug info for the whole dependency graph stays out of
# every test binary (each UI test binary had a 500-600 MB PDB on Windows, #454).
# vendored crates under `vendor/` (excluded from the workspace). Dependencies
# carry no debug info and our own crates only line tables: backtraces and
# panics still show file and line, while test binaries and the target dir stay
# small (each UI test binary had a 500-600 MB PDB on Windows, #454).
[profile.dev.package."*"]
opt-level = 2
debug = "line-tables-only"
debug = false
[profile.dev]
opt-level = 1
debug = "line-tables-only"
[profile.low-disk]
inherits = "dev"
debug = "line-tables-only"
incremental = false
[profile.release]
+5 -2
View File
@@ -1,6 +1,6 @@
# PdfCraft architecture
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-11 · **Change:** minor (shared print spooler; Windows CI passes) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)
> **Last reviewed:** 2026-10-10 · **Last updated:** 2026-10-23 · **Change:** minor (xtask ci: nextest, one wasm check) · **Target:** Adobe Acrobat Pro (Acrobat DC, continuous track 26.002.21931, macOS)
How PdfCraft is built today. The design rationale and the planned crates live in
`plan/architecture.md` and `plan/adr/` (local-only); this file describes what is on `main`. Each
@@ -99,7 +99,9 @@ Every user-facing feature is reachable headlessly (`AGENTS.md` §3):
## Build and quality gates
`cargo xtask ci` runs fmt, clippy (`-D warnings`), tests, the layering check, the WASM check,
`cargo xtask ci` runs fmt, clippy (`-D warnings`), a check of `pdfcraft-cli` without default
features, the tests (`xtask test`: cargo-nextest when installed, else `cargo test`, then the
doctests), the layering check, the WASM check (one `cargo check` over every crate below L8),
`xtask assets` (asset licences and hashes), `xtask parity` (checklist claims must cite real commands,
tools and tests) and `xtask deny` (dependency licences). Other tasks: `xtask fuzz`, `xtask corpus` and `xtask check` (robustness
sweep over the pinned pdf.js corpus), `xtask text-oracle` (word F1 and reading order against `pdftotext`),
@@ -110,4 +112,5 @@ built by `.github/workflows/release.yml` ([releasing.md](releasing.md)).
| Date | Change | Summary |
|---|---|---|
| 2026-10-23 | minor | `xtask ci` runs nextest and doctests, checks the CLI without default features, and checks wasm in one call |
| 2026-10-10 | major | Created from the code on main (crate list, `xtask/src/layers.rs`, crate READMEs, `vendor/README.md`) |
+8 -5
View File
@@ -12,11 +12,14 @@ cargo build --profile low-disk -p pdfcraft-cli
cargo test --profile low-disk -p pdfcraft-cos --lib
```
The profile inherits the normal development settings, including debug assertions and overflow
checks. It uses line-table-only debug information for workspace code, which keeps file and line
numbers in backtraces but omits local-variable and parameter details, and it disables incremental
compilation for this profile only. Ordinary `cargo build`, `cargo test`, and release builds keep
their existing profiles.
The profile inherits the normal development settings, including debug assertions, overflow
checks and line-table-only debug information, and disables incremental compilation for this
profile only. Ordinary `cargo build` and `cargo test` keep incremental compilation.
The development profile itself keeps only line tables for workspace code and no debug information
for dependencies. Backtraces show file and line numbers but no local variables or parameters; for
full debug information in workspace code (for a debugger), build with
`CARGO_PROFILE_DEV_DEBUG=true`.
Cargo stores custom-profile artifacts separately under `target/low-disk`. Switching between the
normal and low-disk profiles can therefore leave both sets of artifacts on disk. To remove only
+24 -11
View File
@@ -78,20 +78,32 @@ pub fn wasm(_: &[String]) -> anyhow::Result<()> {
.filter(|c| matches!(layers::classify(&c.name), Some(layers::Class::Layer(_) | layers::Class::Standalone(_))))
.map(|c| c.name)
.collect();
let mut failed = Vec::new();
// One call over every crate: they share one dependency build, and `--keep-going` reports
// each failing crate instead of stopping at the first.
let mut c = cargo();
c.args(["check", "--target", "wasm32-unknown-unknown", "--keep-going"]);
for pkg in &set {
let mut c = cargo();
c.args(["check", "--target", "wasm32-unknown-unknown", "-p", pkg]);
if run(c, &format!("cargo check --target wasm32-unknown-unknown -p {pkg}")).is_err() {
failed.push(pkg.clone());
}
c.args(["-p", pkg]);
}
if failed.is_empty() {
println!("wasm32: {} crates ok", set.len());
Ok(())
run(c, &format!("cargo check --target wasm32-unknown-unknown --keep-going ({} crates)", set.len()))?;
println!("wasm32: {} crates ok", set.len());
Ok(())
}
/// The workspace tests. Unit and integration tests run under cargo-nextest when it is installed
/// (one process per test, so the run is not held up by its slowest binary), else under
/// `cargo test`; doctests run separately because nextest does not run them. Examples are left
/// out of the test build: clippy `--all-targets` already checks that they compile.
pub fn test(_: &[String]) -> anyhow::Result<()> {
let targets = ["--workspace", "--lib", "--bins", "--tests"];
let nextest = cargo().args(["nextest", "--version"]).output().is_ok_and(|o| o.status.success());
if nextest {
run_args(&[&["nextest", "run", "--no-fail-fast"][..], &targets].concat())?;
} else {
bail!("wasm32 check failed for: {}", failed.join(", "))
eprintln!("test: cargo-nextest is not installed, using cargo test (cargo install cargo-nextest --locked)");
run_args(&[&["test", "--no-fail-fast"][..], &targets].concat())?;
}
run_args(&["test", "--workspace", "--doc"])
}
pub fn ci(_: &[String]) -> anyhow::Result<()> {
@@ -99,7 +111,8 @@ pub fn ci(_: &[String]) -> anyhow::Result<()> {
let steps: Vec<Step> = vec![
("fmt", Box::new(|| run_args(&["fmt", "--all", "--", "--check"]))),
("clippy", Box::new(|| run_args(&["clippy", "--workspace", "--all-targets", "--", "-D", "warnings"]))),
("test", Box::new(|| run_args(&["test", "--workspace"]))),
("cli-no-default-features", Box::new(|| run_args(&["check", "-p", "pdfcraft-cli", "--no-default-features"]))),
("test", Box::new(|| test(&[]))),
("layers", Box::new(|| layers(&[]))),
("wasm", Box::new(|| wasm(&[]))),
("assets", Box::new(|| crate::assets::run(&[]))),
+7 -2
View File
@@ -19,9 +19,14 @@ type Command = fn(&[String]) -> anyhow::Result<()>;
const COMMANDS: &[(&str, &str, Command)] = &[
("version", "Print the workspace version, or `version set X.Y.Z[-pre]` to change it and refresh Cargo.lock", version_cmd),
("layers", "Enforce the crate dependency layering (plan/architecture.md §3)", gates::layers),
("wasm", "cargo check --target wasm32-unknown-unknown for every crate below L8", gates::wasm),
("wasm", "cargo check --target wasm32-unknown-unknown for every crate below L8, in one call", gates::wasm),
("deny", "Dependency licences, bans, sources and advisories (deny.toml; needs cargo-deny)", gates::deny),
("ci", "fmt --check, clippy -D warnings, test, layers, wasm, assets, deny, parity (stops at first failure)", gates::ci),
(
"ci",
"fmt --check, clippy -D warnings, the CLI without default features, test, layers, wasm, assets, deny, parity (stops at first failure)",
gates::ci,
),
("test", "Workspace tests: cargo nextest (cargo test when it is missing), then doctests", gates::test),
("assets", "Enforce the asset policy (AGENTS.md §1) against ATTRIBUTION.toml; --write regenerates ATTRIBUTION.md", assets::run),
("corpus", "Fetch the pinned pdf.js test corpus into corpus/ (git-ignored) and verify it; --update-pin re-records the pin", gates::corpus),
("check", "Robustness sweep over corpus/ with pdfcraft-cli; fails on crashes or regressions vs xtask/baselines", gates::check),