From 91f5745d339b0ce19bb2b424ba42e60235390ba5 Mon Sep 17 00:00:00 2001 From: "Jeffrey C. Ollie" Date: Thu, 10 Sep 2026 10:22:40 -0500 Subject: [PATCH] Compile everything without running it, with a check step Three programs in this repository are reachable only from steps nobody runs in the ordinary way: the benchmark from `bench`, the documentation server from `docs-serve`, and the range generator from `update-ranges`. `zig build test` builds none of them, so a change to the library that broke one would pass every check the project had and be found by whoever next wanted a benchmark. `zig build check` builds all three and runs nothing, and CI runs it on every push. The generator is inside the lazy-dependency branch, so it is covered once zxml has been fetched and skipped on a fresh clone rather than forcing the fetch on everyone. The workflow also gains `zig fmt --check .`, which the project has always been expected to pass and nothing enforced, and it now runs the scalar tests first, matching the default the previous commit set. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01NJz47vhFE5XcSQUDbfP1N3 --- .tangled/workflows/test.yml | 10 ++++++++-- README.md | 8 ++++++++ build.zig | 16 ++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/.tangled/workflows/test.yml b/.tangled/workflows/test.yml index 106e62e..95f6df5 100644 --- a/.tangled/workflows/test.yml +++ b/.tangled/workflows/test.yml @@ -15,9 +15,15 @@ dependencies: steps: - name: "reuse lint" command: "reuse lint" - - name: "test (simd)" - command: "zig build test -Dsimd=true" + - name: "zig fmt" + command: "zig fmt --check ." - name: "test (scalar)" command: "zig build test -Dsimd=false" + - name: "test (simd)" + command: "zig build test -Dsimd=true" + # Everything `test` builds but never runs: the benchmark, the + # documentation server, and the range generator. + - name: "check" + command: "zig build check" - name: "docs" command: "zig build docs" diff --git a/README.md b/README.md index 225f956..cf389e0 100644 --- a/README.md +++ b/README.md @@ -115,6 +115,14 @@ zig build test The test suite includes unit tests and a fuzz test. +`zig build check` compiles everything that `zig build test` does not +run — the benchmark, the documentation server, and the range generator +— so that none of them can quietly stop compiling. + +`zig build bench` compares the SIMD and scalar check digit +implementations against each other; it calls both directly, so the +`-Dsimd` setting does not affect what it measures. + ## License [MIT](LICENSES/MIT.txt). This project is compliant with the diff --git a/build.zig b/build.zig index 0ace188..45505b9 100644 --- a/build.zig +++ b/build.zig @@ -36,6 +36,14 @@ pub fn build(b: *std.Build) void { const test_step = b.step("test", "Run tests"); test_step.dependOn(&run_mod_tests.step); + // Everything that is built but not run by `zig build test`, gathered + // so that it cannot quietly stop compiling. The tools are reached only + // by steps nobody runs in the ordinary way -- the benchmark by `bench`, + // the documentation server by `docs-serve`, the range generator by + // `update-ranges` -- so without this a change to the library that broke + // one of them would pass CI. + const check_step = b.step("check", "Compile everything without running it"); + // The benchmark selects each implementation explicitly through // computeCheckDigitWith, so a single ReleaseFast module instance // covers both variants regardless of the -Dsimd setting. @@ -64,6 +72,7 @@ pub fn build(b: *std.Build) void { const bench_step = b.step("bench", "Run benchmarks comparing SIMD and scalar check digit computation"); bench_step.dependOn(&run_bench.step); + check_step.dependOn(&bench_exe.step); // -- documentation ------------------------------------------------------- // @@ -112,6 +121,8 @@ pub fn build(b: *std.Build) void { test_step.dependOn(&b.addRunArtifact( b.addTest(.{ .root_module = docs_server.root_module }), ).step); + check_step.dependOn(&docs_server.step); + // The generator runs on the build host and writes into the source // tree, so it ignores -Dtarget and -Doptimize. const update_ranges_step = b.step("update-ranges", "Fetch the ISBN range data and regenerate src/ranges.zig"); @@ -141,5 +152,10 @@ pub fn build(b: *std.Build) void { const update_source = b.addUpdateSourceFiles(); update_source.addCopyFileToSource(generated, "src/ranges.zig"); update_ranges_step.dependOn(&update_source.step); + + // Only reachable when zxml has already been fetched, so `zig build + // check` on a fresh clone covers everything else and picks this up + // the first time `update-ranges` is asked for. + check_step.dependOn(&generate_exe.step); } } -- 2.51.2