romele / git-trace public
62 commits · 1 branch · 1 tag · 1 contributor (top: Romele) · first commit 3d ago · last push 20m ago
doc/ci.md
# CI runner
A minimal per-repo continuous integration, opt-in via
`<owner>/<repo>/settings` ("ci" checkbox, admins only). When enabled,
every accepted branch push queues a row in `ci_runs` and a detached
`git-trace ci-run` process executes it:
- the pipeline is `.git-trace-ci`, a plain shell script read **only
from the default branch** — a writer on a feature branch cannot
replace or sabotage it;
- the pushed tree is materialised with `git archive | tar -x` into a
throwaway `/tmp` dir — no checkout, no worktree left behind;
- the script runs as `/bin/sh ci.sh` with a scrubbed environment
(`PATH=/usr/bin:/bin`, `HOME` = the build dir, `CI=1`,
`GIT_TRACE_{REPO,SHA,BRANCH}`) and hard limits: `RLIMIT_CPU` 60s,
`RLIMIT_AS` 512 MiB, `RLIMIT_FSIZE` 32 MiB, `RLIMIT_NPROC` 128,
plus a 300s wall-clock timeout (`GIT_TRACE_CI_TIMEOUT`). The child
is its own process group, so a timeout kills helper processes too;
- results land on `<owner>/<repo>/ci` — status badge
(pass/fail/timeout/error), exit code, and the captured output
(capped at 256 KiB). Finished builds also fire a `ci` webhook
event and a `ci_run` audit row.
Honest threat-model note: CI executes repository-controlled code on
the server by definition. The constraints above bound CPU, memory,
output and time, but the build still runs with the forge daemon's
privileges — enable it on repos whose writers you trust, and prefer
serving under a dedicated OS user (as `deploy/git-trace.service`
already does).