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:
@@ -1,26 +1,46 @@
|
||||
# Backend migrations
|
||||
|
||||
Goose migrations embedded into the backend binary by `embed.go`. Applied
|
||||
at startup before any listener opens (see `internal/postgres`).
|
||||
Goose (`pressly/goose/v3`) migrations embedded into the backend binary
|
||||
by `embed.go`. Applied at startup before any listener opens — see
|
||||
`internal/postgres`.
|
||||
|
||||
## Pre-production single-file rule
|
||||
## Authoring conventions
|
||||
|
||||
**While the platform is not yet in production, every schema change goes
|
||||
into the existing `00001_init.sql` file** rather than a new
|
||||
`00002_*`-prefixed file. The intent is to keep the schema in one
|
||||
canonical place so reviewers and developers do not have to reconstruct
|
||||
the latest shape from a chain of incremental migrations.
|
||||
- Each schema change is a new file with a monotonically increasing
|
||||
numeric prefix and a snake-case slug:
|
||||
`0000N_short_description.sql`. Reuse of a prefix is forbidden once
|
||||
the file is merged.
|
||||
- `00001_init.sql` is the historical baseline. Treat it as immutable
|
||||
history; do not edit it to land new schema. Squashing the chain back
|
||||
into a fresh `00001` is reserved for the explicit pre-production
|
||||
cut-over.
|
||||
- Every file MUST contain both an `-- +goose Up` and `-- +goose Down`
|
||||
section, even if Down is a single `DROP …` for the same artefacts.
|
||||
Down migrations are exercised by the schema test and serve as the
|
||||
documented rollback path.
|
||||
- Destructive changes (dropping columns/tables, renaming with data
|
||||
loss) MUST be split into at least two migrations so the chain stays
|
||||
rollable forward and backward without coordinated code+schema
|
||||
windows:
|
||||
1. add the new shape, dual-write the data, leave the old shape in
|
||||
place;
|
||||
2. once all readers have switched, drop the old shape in a follow-up
|
||||
migration.
|
||||
- Migrations are applied automatically on backend startup, so a fresh
|
||||
push to `development` plus the `dev-deploy.yaml` workflow brings the
|
||||
long-lived dev database up to head without manual intervention.
|
||||
`make -C tools/dev-deploy clean-data` is only needed when a developer
|
||||
deliberately wants a fresh database.
|
||||
- The integration harness (`backend/internal/postgres/migrations_test.go`)
|
||||
spins up a disposable Postgres per run and asserts the final table
|
||||
set. When a migration adds or removes tables, update the expected
|
||||
list in the same patch.
|
||||
|
||||
Operationally this means that pulling a branch with schema changes
|
||||
requires a fresh database — the only consumer today is local development
|
||||
and integration tests, both of which spin up disposable Postgres
|
||||
instances.
|
||||
## Pre-production squash
|
||||
|
||||
> **Remove this rule before the first production deployment.** From
|
||||
> that point on every schema change must be a new migration file with a
|
||||
> monotonically increasing prefix, and `00001_init.sql` becomes
|
||||
> immutable history.
|
||||
|
||||
If you need to make a change, edit `00001_init.sql` directly. Down
|
||||
migrations should still be kept in sync (they live at the bottom of the
|
||||
file — currently a single `DROP SCHEMA backend CASCADE`).
|
||||
The chain may be squashed back into one clean `00001_init.sql` before
|
||||
the first production deployment. That is a deliberate, one-time
|
||||
operation; until then, additive numbered files are the rule. After the
|
||||
squash this file gets a short note that `00001_init.sql` represents
|
||||
the production baseline and the policy above continues to apply for
|
||||
every later migration.
|
||||
|
||||
Reference in New Issue
Block a user