CI deployed every Steam game from scratch on each run, downloading the whole game from Steam each time. scripts/boot-test.sh now runs the new `gbrgames boot-test ID`, the builder's own deploy path: the same payload and node-agent BootTest, but Steam games start from the cache volume (gbr-steamcache-<app>, kept by RUNNER.md's prune). The cache is updated at most once a day (a timestamp in the cache volume, not copied into servers), so a repeat run within a day doesn't ask Steam for an update at all; the node-agent's own install still checks the files and fetches anything newer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3.0 KiB
Boot-test runner setup
Boot tests run on a dedicated Gitea Actions runner labelled game-test. It deploys each changed game
with the node-agent's real deploy code, inside a Docker network that can reach the internet (Steam,
Mojang, plugin downloads) but not private networks or the host. scripts/boot-test.sh refuses to
run if that network is missing, so a half-configured runner can't boot servers on the LAN.
Everything here runs on the runner VM as root.
1. Isolated network
mkdir -p /opt/gbr-boottest
cp scripts/runner/setup-boottest-network.sh /opt/gbr-boottest/
chmod +x /opt/gbr-boottest/setup-boottest-network.sh
cp scripts/runner/gbr-boottest-network.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable --now gbr-boottest-network
Check it from a throwaway container: the first command should print an IP, the second should time out.
docker run --rm --network gbr-boottest curlimages/curl -s --max-time 5 https://ifconfig.me
docker run --rm --network gbr-boottest curlimages/curl -s --max-time 5 http://192.168.1.1 || echo blocked
2. The runner
- In Gitea: gbreed-public → Settings → Actions → Runners → Create new runner, and copy the token.
- On the VM:
mkdir -p /opt/gitea-game-test-runner && cd /opt/gitea-game-test-runner
cp <repo>/scripts/runner/docker-compose.yml <repo>/scripts/runner/config.yaml .
echo "GITEA_RUNNER_REGISTRATION_TOKEN=<token>" > .env
docker compose up -d
The runner shows up as game-test in the org's runner list. It takes one job at a time; the build
runner keeps handling everything else.
3. Secrets
Games whose test.yaml maps a value under secrets are skipped until that Actions secret exists in
the org or repo, and the workflow passes it through (see the env: of the boot-test step).
| Secret | Game | What |
|---|---|---|
DRAGONWILDS_OWNER_ID |
RuneScape: Dragonwilds | A Player ID; the server won't start without one |
Housekeeping
Game images and SteamCMD downloads add up; each test removes its own container and volume. Clean up weekly (cron or a systemd timer) with:
docker container prune -f
docker image prune -af --filter "until=168h"
docker volume prune -af --filter "label!=gbr.cache"
Not docker system prune: it also deletes the gbr-boottest network whenever no container is using it,
and boot tests then refuse to run until systemctl restart gbr-boottest-network.
Steam download cache
Boot tests of Steam games (installMethod: STEAMCMD) start from a cached install, one Docker volume per
app (gbr-steamcache-<app id>, label gbr.cache=steam), the same cache the AI builder uses. The
cache is updated at most once a day; the node-agent's own install then only checks the files and
fetches what changed. So Steam isn't asked for the whole game on every run, which keeps traffic from
this machine's address low. The prune above keeps these volumes. To drop one game's cache:
docker volume rm gbr-steamcache-<app id>; STEAM_CACHE=off turns the cache off.