CI
Four jobs on every push to main and every pull request, defined in
.github/workflows/ci.yml.
Zig is pinned to 0.16.0.
zig fmt --check build.zig src tests examplesFormatting is not a review topic.
Runs on ubuntu-latest, macos-latest, and windows-latest, with
fail-fast: false so one platform failing still reports the others.
zig build test --summary allzig build example-01 # and 02, 03, 04zig buildzig build test also builds every example, so a stale one fails here. The
examples are then run, because building proves they compile and running proves
they work.
CLI round trip
Section titled “CLI round trip”Path handling and the atomic write differ per platform, so the CLI is exercised end to end rather than trusted to unit tests:
zpack pack examples/example-assets ci.zpakzpack list ci.zpakzpack verify ci.zpakzpack unpack ci.zpak ci-outzpack manifest ci.zpak > /dev/nullzpack ids ci.zpak > /dev/null
diff -r examples/example-assets ci-outThat diff -r is the round-trip guarantee, checked on three operating systems
every time.
Rejecting damaged archives
Section titled “Rejecting damaged archives”The most interesting job. A damaged archive must fail cleanly - a non-zero
exit with a named error, never a crash. Three kinds of damage are manufactured
and fed to verify:
| Damage | How | Must produce |
|---|---|---|
| A flipped byte mid-data | dd one byte to 0xff, or 0x00 if it was already 0xff |
HashMismatch |
| Truncation | head -c $((size - 64)) |
CorruptArchive |
| Not an archive at all | printf 'NOTZPAK' |
BadMagic |
Each is checked three ways: the exit status must be non-zero, the output must
not contain panic, and the corruption itself must not have been a no-op -
cmp confirms the flipped file actually differs before the test means anything.
That last check is the sort of thing that keeps a test honest. A byte flip that silently did nothing would produce a passing test that proves nothing.
Cross-compiles every release target on every PR:
x86_64-linux-musl aarch64-linux-muslx86_64-macos aarch64-macosx86_64-windows aarch64-windowszig build -Dtarget=$TARGET -Doptimize=ReleaseSafe -DstripBuilding all six on every change means a portability break surfaces on the change that caused it, rather than at tag time when someone is trying to ship.
Builds this site:
cd docsbun install --frozen-lockfilebun run buildThe build runs starlight-links-validator, so a link to a page that was renamed
or never written fails the check rather than shipping as a 404.
What is not in CI
Section titled “What is not in CI”Benchmarks. There is no performance regression suite.
Fuzzing. The corruption job manufactures three specific kinds of damage, not
random mutation. A fuzzing harness over Archive.open would be a genuinely
useful contribution.
Large archives. Everything runs against the small examples/example-assets
tree. Behaviour past 4 GB, or past maxInt(u32) entries, is bounded by code
review rather than by test.
Release checks
Section titled “Release checks”Tagging runs a separate workflow with its own gate - see releasing.