docs: sync project guides to the new CI flow
go-unit / test (pull_request) Failing after 30s
integration / integration (pull_request) Failing after 34s
ui-test / test (pull_request) Failing after 37s

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>
This commit is contained in:
Ilia Denisov
2026-05-13 23:26:57 +02:00
parent f316952c12
commit f00c8efd18
5 changed files with 107 additions and 31 deletions
+35 -20
View File
@@ -34,32 +34,47 @@ This repository hosts the Galaxy Game project.
deeper than what fits in `README.md` (per-feature design notes, deeper than what fits in `README.md` (per-feature design notes,
protocol specs, runbooks). Not stage-by-stage history. protocol specs, runbooks). Not stage-by-stage history.
## Branching and CI flow
Branches:
- `main` — production-track. Direct pushes are disallowed; the only
way in is a PR merge from `development`. A merge fires
`prod-build.yaml` which packages the artifacts; production rollout
is manual through `deploy-prod.yaml`.
- `development` — long-lived dev integration branch. Every merge into
it auto-deploys to the dev environment via `dev-deploy.yaml`
(reachable at `https://www.galaxy.lan` / `https://api.galaxy.lan`).
- `feature/*` — short-lived branches off `development`. Merged back
via PR; only then do they reach the dev environment.
Workflows in `.gitea/workflows/`:
| File | Trigger | What it does |
|------|---------|--------------|
| `go-unit.yaml` | push + PR matching Go paths | Fast Go unit tests. |
| `ui-test.yaml` | push + PR matching `ui/**` | Vitest + Playwright. |
| `integration.yaml` | PR to `development`/`main`; push to `development` | testcontainers integration suite. |
| `dev-deploy.yaml` | push to `development` | Build images + (re)deploy to `tools/dev-deploy/`. |
| `prod-build.yaml` | push to `main` | Build prod images and `docker save` into artifacts. |
| `deploy-prod.yaml` | `workflow_dispatch` | Manual rollout (placeholder until prod host exists). |
## Per-stage CI gate ## Per-stage CI gate
Every completed stage from any `PLAN.md` (per-service or `ui/PLAN.md`) Every completed stage from any `PLAN.md` (per-service or `ui/PLAN.md`)
must be exercised on the local Gitea Actions runner before being must be exercised on `gitea.lan` before being declared done. The
declared done. The runbook lives in `tools/local-ci/README.md`; the short version:
short version is:
1. Commit the stage changes. 1. Commit the stage changes on the feature branch.
2. `make -C tools/local-ci push` pushes `HEAD` to the local Gitea 2. `git push gitea …` to publish the branch.
instance and triggers every workflow that matches the changed 3. Poll the latest run in the Gitea UI (or the API) until it leaves
paths.
3. Poll the latest run via the API snippet in `ui/docs/testing.md`
(or the Gitea UI on `http://localhost:3000`) until it leaves
`running`. Inspect the log on failure. `running`. Inspect the log on failure.
4. Only after the run is `success` may the stage be marked done in 4. Only after every workflow that fired is `success` may the stage be
the corresponding `PLAN.md`. marked done in the corresponding `PLAN.md`.
This applies even when the local unit-test suite is green — `tools/local-ci/` is now an opt-in fallback for testing workflow
workflow-only failures (path filters, action-version mismatches, changes without `gitea.lan` (offline iterations, runner-isolation
missing secrets, runner-only environment differences) are cheap to debugging). It is no longer required for the per-stage gate.
catch here and expensive to catch on a remote PR. The push step is
implicitly authorised: do not ask for confirmation on every stage.
If `tools/local-ci` is not running, bring it up first
(`make -C tools/local-ci up`); do not skip this gate. The single
exception is when the user explicitly waives it for a stage.
## Decisions during stage implementation ## Decisions during stage implementation
+45 -2
View File
@@ -751,7 +751,50 @@ addition.
`GET /readyz` (Postgres reachable, migrations applied, gRPC listener `GET /readyz` (Postgres reachable, migrations applied, gRPC listener
bound). Probes are excluded from anti-replay and rate limiting. bound). Probes are excluded from anti-replay and rate limiting.
## 18. Deployment Topology (informational) ## 18. CI and Environments
The repository is monorepo and intentionally so — semver tags and
per-service rollouts are achievable without splitting the code into
multiple repositories.
Branches:
- `main` — production-track. Direct pushes are disallowed; the only
way in is a PR merge from `development`.
- `development` — long-lived dev integration branch. Every merge
triggers an auto-deploy into the long-lived dev environment on the
CI host, reachable through the host Caddy at
`https://www.galaxy.lan` and `https://api.galaxy.lan`.
- `feature/*` — short-lived branches off `development`. Merged back
via PR; PRs run unit + integration checks before merge.
Workflows under `.gitea/workflows/`:
| File | Trigger | Purpose |
|------|---------|---------|
| `go-unit.yaml` | push + PR matching Go paths | Fast Go unit tests. |
| `ui-test.yaml` | push + PR matching `ui/**` | Vitest + Playwright. |
| `integration.yaml` | PR to `development` / `main`; push to `development` | testcontainers integration suite. |
| `dev-deploy.yaml` | push to `development` | Build images, seed UI volume, `compose up` against `tools/dev-deploy/`. |
| `prod-build.yaml` | push to `main` | Build production images and persist `docker save` bundles as artifacts. |
| `deploy-prod.yaml` | manual `workflow_dispatch` | Placeholder for the future SSH-based production rollout. |
Environments:
- **`tools/local-dev/`** — single-developer playground. Bound to
host ports, Vite dev server runs on the host. Not driven by CI.
- **`tools/dev-deploy/`** — long-lived dev environment behind
`*.galaxy.lan`, redeployed on every merge into `development`.
- **production** — future. Images come from the
`galaxy-images-commit-<sha>` artifact produced by `prod-build.yaml`
and are shipped to the production host via `docker save`
`ssh prod docker load``docker compose up -d`.
`tools/local-ci/` remains as an opt-in fallback runner for testing
workflow changes without `gitea.lan`. It is no longer part of the
per-stage CI gate; see `CLAUDE.md` for the gate definition.
## 19. Deployment Topology (informational)
- MVP runs three executables: one `gateway` instance, one `backend` - MVP runs three executables: one `gateway` instance, one `backend`
instance, and N `galaxy-game-{game_id}` containers managed by backend. instance, and N `galaxy-game-{game_id}` containers managed by backend.
@@ -770,7 +813,7 @@ Future scale-out hooks (not in MVP):
- mTLS between gateway and backend. - mTLS between gateway and backend.
- Docker-socket-proxy sidecar fronting Docker daemon access. - Docker-socket-proxy sidecar fronting Docker daemon access.
## 19. Glossary ## 20. Glossary
- **device_session_id** — opaque identifier of an authenticated client - **device_session_id** — opaque identifier of an authenticated client
device; primary key of the device session record. device; primary key of the device session record.
+12 -4
View File
@@ -1,9 +1,17 @@
# Local Gitea CI # 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 Self-contained Gitea + Actions runner for verifying
`.gitea/workflows/*` honestly before pushing to a real Gitea instance. `.gitea/workflows/*` honestly before pushing to `gitea.lan`. Runs
Runs natively on arm64 (Apple Silicon) — every image below has an natively on arm64 (Apple Silicon) — every image below has an arm64
arm64 variant, so Docker pulls the right architecture and the runner variant, so Docker pulls the right architecture and the runner
executes workflow steps without QEMU emulation. executes workflow steps without QEMU emulation.
## Prerequisites ## Prerequisites
+9 -5
View File
@@ -10,11 +10,15 @@ FlatBuffers wire, every authenticated call verifies the response
signature against the dev keypair, and every email passes through signature against the dev keypair, and every email passes through
Mailpit's web UI for inspection. Mailpit's web UI for inspection.
This stack is **not** a CI gate (that role belongs to This stack is **not** a CI gate (the per-stage CI gate now lives on
[`tools/local-ci/`](../local-ci/README.md), which boots a Gitea + `gitea.lan`; see project-level `CLAUDE.md`). It is also distinct from
Actions runner and replays workflow files). The two stacks are the **long-lived dev environment** at
independent and can coexist on the same machine; they bind different [`tools/dev-deploy/`](../dev-deploy/README.md), which is redeployed on
ports and use different networks. every merge into `development` and is reachable as
`https://www.galaxy.lan` / `https://api.galaxy.lan`. The three stacks
(`tools/local-dev/`, `tools/dev-deploy/`, and the fallback
`tools/local-ci/`) coexist on the same host because every name —
compose project, container, network, volume — is distinct.
## Bring it up ## Bring it up
+6
View File
@@ -153,6 +153,12 @@ The stack accepts a fixed dev code (`123456`) in addition to the
real Mailpit-delivered one. Full runbook in real Mailpit-delivered one. Full runbook in
[`../tools/local-dev/README.md`](../tools/local-dev/README.md). [`../tools/local-dev/README.md`](../tools/local-dev/README.md).
For testing the production-shaped surface — Caddy in front of the
gateway, statically served UI bundle, real `https://*.galaxy.lan`
hostnames — use the long-lived dev environment at
[`../tools/dev-deploy/`](../tools/dev-deploy/README.md). It is
redeployed by Gitea Actions on every merge into `development`.
## Per-phase docs ## Per-phase docs
Topic docs live under `ui/docs/` and are added per phase as they're Topic docs live under `ui/docs/` and are added per phase as they're