tools/dev-deploy: long-lived dev environment behind host Caddy #2

Merged
developer merged 4 commits from feature/ci-reorg-and-dev-deploy into development 2026-05-13 22:10:24 +00:00
5 changed files with 107 additions and 31 deletions
Showing only changes of commit f00c8efd18 - Show all commits
+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,
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
Every completed stage from any `PLAN.md` (per-service or `ui/PLAN.md`)
must be exercised on the local Gitea Actions runner before being
declared done. The runbook lives in `tools/local-ci/README.md`; the
short version is:
must be exercised on `gitea.lan` before being declared done. The
short version:
1. Commit the stage changes.
2. `make -C tools/local-ci push` pushes `HEAD` to the local Gitea
instance and triggers every workflow that matches the changed
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
1. Commit the stage changes on the feature branch.
2. `git push gitea …` to publish the branch.
3. Poll the latest run in the Gitea UI (or the API) until it leaves
`running`. Inspect the log on failure.
4. Only after the run is `success` may the stage be marked done in
the corresponding `PLAN.md`.
4. Only after every workflow that fired is `success` may the stage be
marked done in the corresponding `PLAN.md`.
This applies even when the local unit-test suite is green —
workflow-only failures (path filters, action-version mismatches,
missing secrets, runner-only environment differences) are cheap to
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.
`tools/local-ci/` is now an opt-in fallback for testing workflow
changes without `gitea.lan` (offline iterations, runner-isolation
debugging). It is no longer required for the per-stage gate.
## Decisions during stage implementation
+45 -2
View File
@@ -751,7 +751,50 @@ addition.
`GET /readyz` (Postgres reachable, migrations applied, gRPC listener
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`
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.
- Docker-socket-proxy sidecar fronting Docker daemon access.
## 19. Glossary
## 20. Glossary
- **device_session_id** — opaque identifier of an authenticated client
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
`.gitea/workflows/*` honestly before pushing to a real Gitea instance.
Runs natively on arm64 (Apple Silicon) — every image below has an
arm64 variant, so Docker pulls the right architecture and the runner
`.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
+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
Mailpit's web UI for inspection.
This stack is **not** a CI gate (that role belongs to
[`tools/local-ci/`](../local-ci/README.md), which boots a Gitea +
Actions runner and replays workflow files). The two stacks are
independent and can coexist on the same machine; they bind different
ports and use different networks.
This stack is **not** a CI gate (the per-stage CI gate now lives on
`gitea.lan`; see project-level `CLAUDE.md`). It is also distinct from
the **long-lived dev environment** at
[`tools/dev-deploy/`](../dev-deploy/README.md), which is redeployed on
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
+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
[`../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
Topic docs live under `ui/docs/` and are added per phase as they're