Commit graph halkyon/.forgejo/workflows/ci.yaml
Author SHA1 Message Date
9877fba155
ci: throwaway test passwords, analytics off every time
All checks were successful
CI / check (push) Successful in 4m15s
CI / deploy (push) Successful in 5s
The first CI run failed at the server tests: they need the test run mode's passwords,
which passwords.yaml holds on a developer's machine and which is never committed. Without
them Serverpod's test tools exit with code 1 and print nothing. Reproduced in a clean
clone; with the three passwords in the environment (SERVERPOD_DATABASE_PASSWORD,
SERVERPOD_PASSWORD_serverSideSessionKeyHashPepper, SERVERPOD_PASSWORD_serviceSecret) all
checks pass. The job now draws new random ones every time: they only guard the test
database it creates in its own checkout.

Also switch off Flutter's and Dart's usage reports on every job, not only when installing
the SDK: the cancelled first run left an SDK behind before getting that far.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 22:24:05 +02:00
c837cee51f
ci: stop a job whose sandbox leaks, first thing
Some checks failed
CI / check (push) Failing after 2m27s
CI / deploy (push) Has been skipped
Installing the runner on sahaquiel, `useradd --system` gave `runner` user ID 999: the ID
under which PostgreSQL and the server run inside their containers, which Docker doesn't
remap. To the kernel, those processes were the runner's own, so a job could have read the
server's environment (database password, session pepper, GitHub secret) and, through
/proc, PostgreSQL's files and its local socket, which the official image trusts. The
sandbox's other walls don't help there: ProtectProc hides only other users' processes,
IPAddressDeny doesn't cover Unix sockets. Only our own check ran as 999; `runner` now has
user and group ID 61000.

The check job now starts with a Sandbox step that fails unless only the runner's own
processes are visible, all in one process namespace, /home/deploy is invisible, the
Docker socket is unusable and Docker's bridge network unreachable. It would have caught
this; outside a sandbox it fails as it should. The unit and AGENTS.md say how to create
the user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 22:12:31 +02:00
ce2cd42ffe
ci: check every push on sahaquiel and deploy a green main
Some checks failed
CI / check (push) Failing after 3m22s
CI / deploy (push) Has been skipped
Pushes to main were deployed by hand. Now Forgejo Actions runs tool/check.sh on every
push, and a green main deploys learn.halkyon.eu by itself.

The runner (forgejo-runner v13.1.0) runs on sahaquiel as the unprivileged user `runner`,
with jobs directly on the host: containers would take Docker access, which is root on the
production server, and Forgejo warns that host jobs have no isolation from the runner's
user. So its systemd unit (deploy/runner/forgejo-runner.service) provides it: /home and
the Docker socket invisible, Docker's container networks unreachable, no capabilities,
two cores and 3 GB at most, lowest priority. It is registered to this repository only,
with the UUID and token of Forgejo's "Create new runner" (the old `register` is
deprecated); the token reaches it as a systemd credential. The configuration
(deploy/runner/config.yml) was dry-run against v13.1.0, the unit rates 1.8 in
`systemd-analyze security`. CI runs on pushes only: a pull request from a fork would run
its code on the production server.

The deploy job calls deploy/redeploy.sh as `deploy`, through a key that authorized_keys
pins to that script and to connections from sahaquiel itself. The script deploys the
commit CI checked while it is still main's tip, as a fast-forward, only if every new
commit is signed by a key in deploy/allowed-signers (as the deployed checkout lists
them), after dumping the database (the last ten are kept), and fails unless the server
answers afterwards; a failure puts the checkout back. Tested against the local stack:
refusals of a malformed argument, a stale commit, a forged unsigned commit and a
non-fast-forward, a real deploy with its dump, a repeat, and a failed build.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-30 21:49:04 +02:00