Status¶
Accepted
Context¶
Rust compilation is notoriously slow, particularly when building from scratch in CI environments. As the kroki-rs project grows and introduces more features (e.g., native-browser), the CI cycle time has increased, impacting developer productivity and feedback loops.
We need a strategy that:
Reduces Local CI-verify Time: Fast local verification via
./dflow ci-verify.Optimizes GitHub Actions: Minimal compute usage and faster PR checks.
Ensures Portability: Works across Docker, Podman, and GHA.
Supports Multi-Arch: Builds for
linux/amd64andlinux/arm64.
Trade-off Analysis¶
| Strategy | Speed (Cache Hit) | Portability | Pros | Cons |
|---|---|---|---|---|
| cargo-chef | Fast (Layer based) | High (Standard Docker) | Best for GHA; robust for workspaces. | Invalidates on any dependency change. |
| BuildKit Cache | Very Fast (Mount) | Medium (GHA requires setup) | Persists even if layers mismatch. | Can be tricky to share across different CI hosts. |
| sccache | Moderate (Network) | Very High (S3/Cloud) | Global cache across all PRs/Archs. | Linking is still a bottleneck; network overhead. |
| Persistent Volume | Instant (Local) | Low (Host-bound) | No upload/download; real-time reuse. | Not available in ephemeral CI workers. |
Decision¶
We will implement a Dual Caching Strategy:
cargo-chefas the primary layering mechanism in theDockerfile. This ensures that dependencies are cached in standard Docker layers, which is highly effective and portable for GitHub Actions.BuildKit Cache Mounts (
--mount=type=cache) for the Cargo registry and git folders. This provides a secondary speedup for both local and CI builds by persisting downloaded crates and git data even when theCargo.lockchanges.Local Persistent Volume for the
targetdirectory in./dflow ci-verify. This allows for near-instant re-runs locally by bypassing the slow linking phase.
Consequences¶
Positive: PR verification times are expected to drop by 50-70% on warm builds. Local the re-run cycle will be significantly faster.
Negative: The
Dockerfilebecomes more complex with multiple stages (planner,builder,runtime). Initial “cold” builds may be slightly slower due tocargo-chefsetup overhead.
Implementation (2026-02-23): Content-addressable identity and GHA parity¶
Fingerprinting: Base/CI images are tagged by a content hash of
Dockerfile,Makefile,install.sh, andsrc-scripts/(src-scripts/develop/vars/vars.mk). Same algorithm used insrc-scripts/ci-verify/repro-ci.shand.github/workflows/base-image.yml.Ruthless Identity: GHA runs all CI jobs inside the fingerprinted CI container (
ghcr.io/<repo>-ci:latest), so local repro and GitHub Actions share the same environment (Debian, same tooling).Smart pull:
repro-ci.shpulls by hash from ghcr.io first and builds locally only if the image is missing.Makefile: Modularized under
src-scripts/develop/intovars/vars.mk,native/native.mk,container/container.mk,repro/repro.mk. Scripts live undersrc-scripts/setup/andsrc-scripts/ci-verify/.
Benchmarks (Verified 2026-02-23)¶
Cold Rebuild: 16m 7s (Full container and target directory construction)
Warm Rebuild (Code change only): 45s (~21x speedup via persistent
targetvolume)Dependency Change Rebuild: TBD (Expected to be handled by
cargo-cheflayers)