Files
galaxy-game/tools/local-ci/README.md
T
Ilia Denisov f00c8efd18
go-unit / test (pull_request) Failing after 30s
integration / integration (pull_request) Failing after 34s
ui-test / test (pull_request) Failing after 37s
docs: sync project guides to the new CI flow
Aligns the project guides with the branching/CI/environment changes
landed in the previous commits:

- CLAUDE.md: per-stage CI gate now closes against gitea.lan; describes
  the main/development/feature/* flow and the workflow surface
- docs/ARCHITECTURE.md: new section 18 "CI and Environments" covering
  branches, workflows, and the local-dev / dev-deploy / local-ci
  triad; section numbering shifted accordingly
- tools/local-ci/README.md: marked as fallback (offline / runner
  isolation only)
- tools/local-dev/README.md and ui/README.md: cross-link to
  tools/dev-deploy/ for production-shaped testing

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 23:26:57 +02:00

4.2 KiB

Local Gitea CI (fallback)

Status: fallback / opt-in. The primary CI target is now gitea.lan with its host-mode act_runner. The per-stage CI gate closes against gitea.lan, not against this stack. Use this directory when you want to validate .gitea/workflows/* without reaching gitea.lan — for example, when iterating on a workflow file from a flight without LAN access — or when isolating a runner issue from production-shaped infrastructure.

Self-contained Gitea + Actions runner for verifying .gitea/workflows/* honestly before pushing to gitea.lan. Runs natively on arm64 (Apple Silicon) — every image below has an arm64 variant, so Docker pulls the right architecture and the runner executes workflow steps without QEMU emulation.

Prerequisites

  • Docker (Colima or Docker Desktop)
  • python3, curl, bash — all built into macOS

First time

make -C tools/local-ci up

This:

  1. brings up the Gitea container;
  2. creates an admin user (galaxy / galaxy-dev);
  3. creates the galaxy/galaxy repo;
  4. fetches a runner registration token from the Gitea API;
  5. brings up the runner with that token (the runner persists its credentials in a Docker volume and ignores the token on subsequent restarts).

The script is idempotent — re-running it is safe.

Pushing a branch

make -C tools/local-ci push

This adds a local-gitea remote on the first run and then pushes the current HEAD. Equivalent manual flow:

git remote add local-gitea \
    http://galaxy:galaxy-dev@localhost:3000/galaxy/galaxy.git
git push local-gitea HEAD

The Tier 1 workflow fires on push to any branch and the Tier 2 workflow fires on tags matching v*. Watch runs at:

http://localhost:3000/galaxy/galaxy/actions

Operational targets

Target What it does
make up Bring up Gitea + runner (idempotent)
make down Stop both containers (state preserved)
make logs Tail logs from both containers
make status Show container status
make push Push current HEAD to local Gitea
make clean Stop and wipe all local state (full reset)

What's in the box

Component Image Role
Gitea gitea/gitea:1.23 Server with SQLite backend
act_runner gitea/act_runner:0.6.1 Single-capacity runner registered on boot
Workflow catthehacker/ubuntu:act-latest Image spawned per job (multi-arch)

The runner mounts the host Docker socket and spawns workflow containers on the same Docker network as Gitea, so actions/checkout reaches the server at http://gitea:3000 from inside spawned containers.

Caveats

  • Gitea's ROOT_URL is set to http://gitea:3000/ so spawned workflow containers reach the server through the compose network. The web UI works at http://localhost:3000 via port mapping, but copy-paste URLs in the UI may show gitea:3000 instead of localhost:3000. Harmless for local dev; switch the host part by hand when copying.
  • The runner is single-capacity (runner.capacity: 1 in config.yaml). Concurrent jobs queue. Bump if you need parallel jobs.
  • First push from a fresh checkout uploads the full repo history (~tens of MB). Subsequent pushes are deltas.
  • actions/upload-artifact@v4 requires Gitea ≥ 1.21 — we pin 1.23 to stay above the cutoff.
  • Workflow steps run as root inside the spawned container; this matches the upstream catthehacker behaviour. Keep that in mind if you add steps that touch host-mounted directories.
  • On Apple Silicon the runner image and its catthehacker child run natively as arm64. Some pre-built tools that ship in the image are amd64-only and would fall back to QEMU; setup-go, setup-node, and pnpm/action-setup all download arm64 binaries themselves, so the workflow steps we care about stay native.