chore(ci): tidy CI/dev infra — drop local-ci, lift migration rule, scope by galaxy.stack label
Five connected cleanups across the dev/CI infrastructure:
1. Drop tools/local-ci/. The standalone Gitea + act_runner stack was
the legacy "offline workflow validator"; the per-stage CI gate now
runs on gitea.lan and the directory was only retained as a
fallback. Removing it leaves no operational dependency: backend,
gateway, and game code have no references; documentation that
pointed at it (CLAUDE.md, docs/ARCHITECTURE.md, ui/docs/testing.md,
tools/dev-deploy/README.md, tools/local-dev/README.md) is updated
in this same change. Historical "Verified on local-ci run N"
markers in ui/PLAN.md are preserved unchanged.
2. Lift the pre-production single-migration rule. The rule forced
every schema delta into 00001_init.sql and required a manual
make clean-data wipe on every backward-incompatible change in
tools/dev-deploy/. Future schema deltas now land as additive
sequence-numbered files (00002_*.sql, …) that goose applies
automatically on backend startup; 00001_init.sql becomes an
immutable baseline. Authoring conventions live in
backend/internal/postgres/migrations/README.md. The chain may be
squashed back into a fresh 00001 as a deliberate one-time
operation before the first production deployment.
3. Document the deployment cadence. The dev environment is
single-tenant: pushes to feature/* run the test workflows
(go-unit, ui-test, integration) only; dev-deploy.yaml fires on
push to development. A workflow_dispatch override on
dev-deploy.yaml lets a developer preview a feature branch on the
shared dev environment before merge; the next merge into
development overwrites the manual deploy idempotently.
4. Scope compose-managed resources by an explicit
galaxy.stack=<local-dev|dev-deploy> label. Both compose files
stamp the label on every service, network, and named volume.
Makefiles in tools/local-dev/ and tools/dev-deploy/ filter their
engine-cleanup operations by (stack-label AND engine OCI title)
so they never touch unrelated workloads on the same daemon.
dev-deploy.yaml gains a pre-`compose up` step that reaps stale
exited/dead containers under the dev-deploy stack label.
5. Backend now stamps the same galaxy.stack=<value> label on every
engine container it spawns, sourced from a new BACKEND_STACK_LABEL
env var (empty → label not applied; legacy-safe). Both compose
files set it to their stack name (local-dev / dev-deploy). The
contract is recorded in docs/ARCHITECTURE.md under
"Container labels". A package-level test in
backend/internal/runtime exercises both the label-present and
label-absent paths.
No tests intentionally regressed: go test ./backend/internal/{config,
runtime,dockerclient} is green, both compose files validate cleanly,
and the backend, gateway, and game modules all build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
-4
@@ -808,10 +808,17 @@ Workflows under `.gitea/workflows/`:
|
||||
| `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/`. |
|
||||
| `dev-deploy.yaml` | push to `development`; `workflow_dispatch` on any ref | 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. |
|
||||
|
||||
Deployment cadence: the dev environment is single-tenant. Pushes to
|
||||
`feature/*` branches run only the test workflows; `dev-deploy.yaml`
|
||||
does not auto-fire. To preview a feature branch on the shared dev
|
||||
environment, trigger `dev-deploy.yaml` manually from the Gitea UI
|
||||
against the desired ref. The deploy is idempotent — the next merge
|
||||
into `development` overwrites the manually deployed state.
|
||||
|
||||
Environments:
|
||||
|
||||
- **`tools/local-dev/`** — single-developer playground. Bound to
|
||||
@@ -823,9 +830,28 @@ Environments:
|
||||
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.
|
||||
### Container labels
|
||||
|
||||
Every Docker resource Galaxy creates carries an opinionated label so
|
||||
that host-side tooling (Makefiles, CI workflows, `preclean.sh`) can
|
||||
scope its operations to Galaxy-owned objects and never touch unrelated
|
||||
workloads on the shared daemon.
|
||||
|
||||
| Label | Values | Set by | Used by |
|
||||
|-------|--------|--------|---------|
|
||||
| `galaxy.stack` | `local-dev`, `dev-deploy`, `integration` | `tools/{local-dev,dev-deploy}/docker-compose.yml` for compose-managed resources; backend reads `BACKEND_STACK_LABEL` and stamps engines it spawns. | `tools/{local-dev,dev-deploy}/Makefile`, `.gitea/workflows/dev-deploy.yaml`. |
|
||||
| `galaxy.backend` | `1` | `backend/internal/dockerclient` adapter on every engine container. | `integration/scripts/preclean.sh`. |
|
||||
| `galaxy.game_id` | `<uuid>` | Backend on engine create. | Reconciler reattach loop. |
|
||||
| `galaxy.engine_version` | `<semver>` | Backend on engine create. | Reconciler version checks. |
|
||||
| `galaxy.test.kind` | `integration-image` | `integration/testenv/images.go` on local image builds. | `integration/scripts/preclean.sh` (filter for `docker rmi`). |
|
||||
| `org.testcontainers` | `true` | `testcontainers-go` (automatic). | `integration/scripts/preclean.sh`. |
|
||||
|
||||
The contract: any Makefile target, CI step, or script that issues
|
||||
`docker rm` / `docker rmi` / `docker network rm` MUST scope itself via
|
||||
one of the labels above. Compose-managed resources are additionally
|
||||
scoped by their compose project name (`galaxy-dev`, `galaxy-local-dev`),
|
||||
which Compose enforces on `docker compose up/down`; the labels make the
|
||||
contract explicit and survive hand-rolled cleanup commands as well.
|
||||
|
||||
## 19. Deployment Topology (informational)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user