oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1# CI
2
3`ci.d/10-gate` is the only CI this repo has. It runs on every push to the
4amadan remote, and it is the same script you can run locally — one
5definition rather than two that drift.
6
7It requires a Rust toolchain with the `wasm32-unknown-unknown` target and
8the `rustfmt` component, Go with `CGO_ENABLED=0`, and Node with `npm` on
9`PATH`. The gate sources `~/.cargo/env` itself and checks every tool up
10front, so a missing dependency fails on the first line with its own name
11rather than fifty lines in as `cargo: command not found`.
12
13The runner clones a fresh worktree per branch, so `fixtures/node_modules`
14never carries over — the gate runs `npm ci` itself, against
15`fixtures/package-lock.json`, so the installed `yjs` is always exactly
1613.6.27 rather than whatever a bare `npm install` would resolve.
17
18**Known tradeoff:** that `npm ci` needs the npm registry reachable at run
19time. It is the right fix for the fresh-worktree-per-branch problem above,
20and the lockfile is committed so the *version* resolved never drifts, but
21it does mean the gate is not fully offline-capable the way the Rust and Go
22steps are once their caches are warm. If the registry is ever unreachable
23from the runner, that is the failure this line produces — not a bug in
24the gate itself.
25
26## The runner
27
28Jobs are claimed by an `amadan runner` on the machine that has one. Two
29things about it were wrong when this repo was created, and both fail
30silently rather than loudly:
31
32- **The runner must be told to serve this repo.** `amadan runner -repo …`
33 is an allowlist. A repo nobody listed gets `amadan ci status` exit 3
34 forever — "no status recorded", which reads like the gate has not run yet
35 rather than like nothing will ever run it.
36- **The runner's `PATH` is the systemd unit's, not your shell's.**
37 `~/.cargo/bin` is not on it by default.
38
39Both were fixed on `DOCS-T1` on 2026-08-30 by editing
40`~/.config/systemd/user/amadan-runner.service` and restarting. A restart
41abandons any job already running, so check it is idle first.
42
43The gate fails if `internal/core/testdata/docs_core.wasm` differs from a
44fresh build, because `go:embed` will otherwise embed a stale module and the
45tests will pass against it.
46
47It also fails if regenerating the Yjs fixtures changes them. Fixtures are
48the wire contract, not an output: a deliberate rule change regenerates them
49in the same commit as the change.
50
51## The app, not just the core
52
53`go vet ./...` and `go test ./...` already cover `cmd/docs` and
54`internal/docs` — the rastrillo app built on top of `internal/core` — but
55neither one proves the app actually links into a runnable binary. The gate
56also runs `CGO_ENABLED=0 go build ./...` for that.
57
58There used to be a further step here: a separate `-tags release` build,
59run with `-dev-auth` on its command line, asserting it refused to start —
60proving a release binary had no code path that could turn a
61development-only stand-in identity on. That identity
62(`internal/docs/devauth.go`) had zero readers once rastrillo/auth's
63`RequireSession` started guarding every document route unconditionally
64(a fix round on Task 1, once real per-person sign-in existed), so it was
65deleted rather than kept as dead code — and the `release` build tag it
66was the only user of went with it. There is no release/non-release
67distinction left for this gate to hold apart; `go test` covers the
68fail-closed properties that matter now
69(`TestNewRefusesMissingInstanceKeyOutsideDevelopment`,
70`TestNewRefusesMissingMailOutsideDevelopment`,
71`TestSignInRequiredForEverything` — all `internal/docs/auth_test.go`).
72`scripts/run-dev.sh` builds and runs the ordinary binary with `-env
73development`, a fixed port, and a scratch database — one command to see
74the app in a browser, signed in for real via a magic link logged to the
75terminal instead of mailed.
76
77The embedded WASM is built on Linux amd64 using fixed `/work`,
78`/usr/local/cargo` and `/usr/local/rustup` paths. Rust/Cargo's crate identities
79otherwise change code ordering across hosts, even with remapped source paths.
80Linux amd64 uses unprivileged bubblewrap when available; other hosts use the
81pinned Rust Docker image. Install Docker on development Macs. Both the artifact
82builder and containment tests use this path; the freshness comparison remains
83byte-for-byte. Docker caches and writable targets are separate from source.
84