Adopt golib/pg for migrations and pool construction #3
Reference in New Issue
Block a user
Delete Branch "benvin/adopt-golib-pg"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
forgebot applied its schema by executing one inline DDL string on every boot: no
version table, no lock, and no place to put the next schema change. Two API
replicas starting together both ran it.
golib/pgalready owns that mechanicfor the estate (adopted by arrproxy in #10), so forgebot should use it and keep
owning only the SQL.
How
migrations/0001_init.sql, embedded viamigrations.FS. TheDDL is verbatim from
internal/database/migrations.go, which is deleted.UPDATEs stay in 0001, unchanged. They areidempotent: each reads only retired statuses (
pending,failed,running,succeeded,cancelled) and writes only current ones, and no current statusappears as a source, so nothing cascades when golib replays 0001 once against
the live database.
TestMigration0001_StatusRewritesAreIdempotentpins thatproperty against
models.TaskStatus, so a future rewrite whose target is alsoa source fails the build rather than the deploy.
database.Newbuilds the pool withpg.NewMigratedandLockName "forgebot-migrations": replicas serialize on the advisory lock,schema_migrationsrecords what ran, and a migration failure closes the pooland fails startup instead of serving a half-migrated database.
database.Newand
apiserver.Newtake a context and logger for it.Config.DatabaseDSNrenders throughpg.DSN, which percent-escapes thecredentials the
fmt.Sprintfbuilder pasted in raw — byte-identical forvalues without reserved characters.
LoadConfigstill reads theenvironment itself rather than calling
pg.DSNFromEnv: the library has nodefaults for user and database name, where forgebot defaults both to
forgebot, and it would newly honourDATABASE_URLand thePG*variables.TestLoadConfig_DatabaseEnvContractsetsDATABASE_URLandPGHOSTandasserts they are ignored.
migrations/drift guard, the lock-key pin(
pg.LockKey("forgebot-migrations")), an additive/idempotent SQL guard, and acolumns-are-selected guard tying the
taskstable to the queries intasks.go. This is the repo's first test package.GOPRIVATE=git.unkin.netfor the first cross-repo Go dependency: exported bythe
Makefile, set in both Dockerfiles and the woodpecker Go steps,documented in the README. No
go env -wstate needed.gofmton the four files that were already unformatted onmain(
agentpool_types.go,providerqueue_types.go,gitea/webhook.go,tui/app.go) — the pre-commit step runstest -z "$(gofmt -l .)"and couldnot pass without it. Whitespace only.
golibpulls pgx v5.7.4 -> v5.9.2 and the usualgolang.org/xbumps.