tools/dev-deploy: long-lived dev environment behind host Caddy #2
@@ -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
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user