Files
rdbms-playground/docs/ci/adr/README.md
T
claude@clouddev1 da8bfebc36
ci / gate (push) Successful in 2m33s
docs(ci): establish docs/ci/adr namespace (ci-001 pipeline, ci-002 flake)
Records the CI/release pipeline as ADR-ci-001 and relocates the nix-flake
ADR from main's ADR-0049 to ADR-ci-002 (content unchanged, history note
added). Both live in docs/ci/adr/ with a README index — a dated,
ci-segmented namespace disjoint from main's integer ADR sequence, the
same split the website subproject uses to avoid cross-branch number
collisions. Drops the ADR-0049 entry from docs/adr/README.

ci-001 covers the runner model, the baked nix CI image, the clippy+test
gate, the static-musl release on tag, trigger hygiene, auth, and scope.
2026-06-12 22:38:34 +00:00

4.7 KiB

CI / Build Architecture Decision Records

Decision records for the continuous-integration + release pipeline subproject — the Gitea Actions workflows under .gitea/, the nix CI image, and the release tooling. These are kept in their own namespace, separate from the project-wide ADRs in docs/adr/, so CI decisions never compete with the main global ADR sequence for numbers — the same split the website subproject uses (docs/website/adr/, on the website branch), and for the same reason (see ADR-0000 "Numbering discipline").

Numbering. Files are named <date>-adr-ci-<NNN>.md and referenced in prose as ADR-ci-NNN. The <date> (the ADR's accepted/created day, YYYYMMDD) plus the ci segment keeps the namespace disjoint from main's integers. Assign the next free NNN from this index. Every ADR change updates this index in the same edit (the ADR-0000 index-upkeep rule applies here too).

Index

  • ADR-ci-001 — CI + release pipeline on Gitea ActionsAccepted 2026-06-12 (implemented the same day on the ci branch). Establishes the CI/release pipeline on the self-hosted Gitea instance's Actions runner (ci-public). Runner model (established by a throwaway probe): jobs execute inside a container (catthehacker/ubuntu:act-22.04 by default), as root, so the runner host's nix is not reachable from steps. Toolchain delivery: a baked CI imagenode:22-bookworm-slim (satisfies the act_runner job-container contract: /bin/sleep keep-alive, bash, node for JS actions; a bare nixos/nix image lacks these and won't start) + single-user nix + the flake's devShell pre-warmed — built by build-ci-image.yaml via DinD and pushed to the Gitea container registry as a public package, so CI runs nix develop -c … against the same pinned toolchain as dev (the flake, ADR-ci-002) with a warm store (~1.4 s to a ready toolchain). Gate (ci.yaml): clippy -D warnings + cargo test inside that image on branch pushes + PRs; fmt deliberately not gated (the tree isn't stock-rustfmt-clean — user decision, revisit on main; see ADR-ci-002). Release (release.yaml): on a v* tag, runs the tests, builds the static x86_64-unknown-linux-musl binary (D2: single static binary, no runtime deps — the glibc/nix build is non-portable), strips it, and publishes it + a .sha256 to a Gitea release via the API and the auto-provided GITEA_TOKEN. Triggers: gate + image-build are scoped to branch pushes (branches: ['**']) so a release tag doesn't spuriously re-run them; the image-build additionally path-filters to its inputs (Dockerfile/flake/toolchain); the release owns tags. Auth: a dedicated PAT (REGISTRY_USERNAME/REGISTRY_TOKEN secrets) pushes the image; the auto GITEA_TOKEN publishes releases. Scope this iteration: Linux x86_64 only — the rest of the D1 matrix (aarch64/macOS/Windows), D3 package-manager manifests, CI-speed dependency caching, and the website's static→Cloudflare deploy are deferred, to be added step by step. Verified live: probe → runner facts; image built + checked locally; gate green (2424 tests); release exercised end-to-end (v0.0.0-citest2 published with binary + checksum). Builds on ADR-ci-002 (the nix flake, relocated here from main's ADR-0049 to avoid exactly this cross-branch collision).
  • ADR-ci-002 — Nix flake for a reproducible dev + build environmentAccepted 2026-06-12 (relocated from main's ADR-0049 on the same day — content unchanged — to keep CI/dev-env decisions out of main's integer sequence). The single, version-pinned declaration of the dev and build toolchain so CI never relies on whatever Rust is on the build machine — mirroring datamage ADR 0046, but far simpler (pure-Rust TUI). Root Nix flake with two outputs: devShells.default (pinned Rust 1.95.0 via rust-toolchain.toml + rust-overlay, cargo-sweep, and the musl cc for the static release build) and packages.default (rustPlatform.buildRustPackage from the committed Cargo.lock; doCheck = false). Exact-pin (not floating stable) so nix flake update can't surprise-bump clippy past the -D warnings gate. System inputs near-empty by design (libsqlite3-sys bundled → stdenv cc only; arboardx11rb pure-Rust). .envrc (use flake) for direnv parity. Verified through the flake: nix build yields a working binary, clippy clean, 2424 tests pass / 0 fail / 1 intentional ignored doctest. Consumed by ADR-ci-001 (the pipeline). Alternatives rejected: dev-shell-only; a standard rust:1.95 CI image (a second toolchain definition = drift); rustup on the build host (non-reproducible).