Skip to content

Commit 75448a0

Browse files
authored
fix(ci): drop lib/pq by moving golang-migrate onto the pgx/v5 driver (#1850)
govulncheck fails repo-wide on five lib/pq advisories with no fix Every module's source-mode govulncheck reported GO-2026-6166, 6168, 6170, 6171 and 6172 in github.com/lib/pq, reached through Driver.Open and conn.Exec. All five are Fixed in: N/A, so no version bump clears them and every branch went red on a dependency nothing here imports directly. The issue was filed naming three; the database grew two more while it sat. lib/pq arrived through exactly one edge: internal/database/postgres/ migrations imported golang-migrate's database/postgres driver, which is lib/pq-backed. Moving that blank import to database/pgx/v5 removes the module from the build closure, and pgx is already this repo's driver everywhere else. The driver swap is not import-only. database/pgx/v5 registers just the pgx5 scheme, where database/postgres registered postgres and postgresql, and golang-migrate selects its driver by URL scheme. Every migration URL had to move to pgx5:// - scripts/entrypoint.sh, which runs migrate up on every container start, the three per-cloud jobs in database-migration.yml, and the copy-pasteable commands in the docs. The standalone migrate CLI moved to -tags=pgx5 for the same reason. That binary runs against production on every container start, so leaving lib/pq in it would have cleaned the source-mode signal while the real exposure stayed. The naive form of that change regressed the image gate: go install pkg@v4.19.1 resolves dependencies from golang-migrate's own go.mod, which pins pgx v5.5.4 and x/crypto v0.45.0, so the shipped CLI came back with 17 fixable advisories. Building it from this module instead makes its dependency graph ours, and the binary is now clean of every advisory, fixable or not, where main's carries the five unfixable lib/pq ones. Verified: govulncheck clean across all six modules where it previously exited 3; go list -deps drops from 3 lib/pq packages to 0 for both ./... and -test ./...; migrations run up and down against a real PostgreSQL on the new URL scheme; the rebuilt image scans clean under scripts/scan-shipped-image.sh, with migrate reporting v4.19.1 and drivers "stub, pgx5" from inside the container. TestLibPqDriverNotRegistered guards both axes rather than one. Driver registration alone would stay green if a change linked lib/pq without registering a driver, so the build closure is asserted directly for the root module and for the CLI as configured. A failed or empty go list is a hard failure, not an absence, so the guard cannot pass for the wrong reason. All three subtests execute in the default unit-test run. go mod why still reports a path to lib/pq. It runs through the test binary of testcontainers-go, a module-graph artifact rather than a linked dependency, which is why go list -deps is the measurement that matters. Deferred: #1851, migrate down -all cannot roll back past migration 55 and leaves the database dirty, reproduced here and pre-existing on main, with database-migration.yml exposing direction: down against all three clouds. #1838, Dockerfile.dev still downloads a prebuilt v4.17.0 migrate that links lib/pq; dev-only and not the shipped runtime image. Not verified: the deployed migration path against RDS, Cloud SQL or Azure Database, which needs real cloud credentials.
1 parent 3ea91fb commit 75448a0

4 files changed

Lines changed: 15 additions & 6 deletions

File tree

‎.github/workflows/ci.yml‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,12 @@ jobs:
236236

237237
- name: Install golang-migrate
238238
run: |
239-
go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@v4.19.1
239+
# -tags 'pgx5', matching the Dockerfile and the library import in
240+
# internal/database/postgres/migrations: the postgres tag links
241+
# lib/pq, which carries unfixable advisories (issue #1849). No
242+
# @version suffix: installed as a package of this module, so the
243+
# version and dependency set come from go.mod.
244+
go install -tags 'pgx5' github.com/golang-migrate/migrate/v4/cmd/migrate
240245
241246
- name: Run database migrations
242247
env:
@@ -248,7 +253,7 @@ jobs:
248253
run: |
249254
if [ -d "internal/database/postgres/migrations" ]; then
250255
migrate -path internal/database/postgres/migrations \
251-
-database "postgresql://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable" \
256+
-database "pgx5://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME}?sslmode=disable" \
252257
up
253258
fi
254259

‎Makefile‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ GIT_SHA?=$(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
1515
GOLANGCI_LINT_VERSION?=v2.10.1
1616
GOSEC_VERSION?=v2.28.0
1717
GOCYCLO_VERSION?=v0.6.0
18-
MIGRATE_VERSION?=v4.19.1
18+
# golang-migrate deliberately has no version variable: it is installed as a
19+
# package of this module (see install-tools), so its version and its whole
20+
# dependency set come from go.mod. See issue #1849.
1921
# staticcheck has no CI pin; it is used by scripts/security-scan.sh
2022
STATICCHECK_VERSION?=v0.7.0
2123
LDFLAGS=-ldflags "-s -w -X main.Version=$(VERSION) -X main.BuildTime=$(BUILD_TIME) -X main.GitSHA=$(GIT_SHA)"
@@ -246,8 +248,8 @@ install-dev-tools:
246248
@go install honnef.co/go/tools/cmd/staticcheck@$(STATICCHECK_VERSION)
247249
@echo "Installing gocyclo $(GOCYCLO_VERSION)..."
248250
@go install github.com/fzipp/gocyclo/cmd/gocyclo@$(GOCYCLO_VERSION)
249-
@echo "Installing golang-migrate $(MIGRATE_VERSION)..."
250-
@go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@$(MIGRATE_VERSION)
251+
@echo "Installing golang-migrate $$(go list -m -f '{{.Version}}' github.com/golang-migrate/migrate/v4)..."
252+
@go install -tags 'pgx5' github.com/golang-migrate/migrate/v4/cmd/migrate
251253
@echo "✓ Development tools installed"
252254
@echo ""
253255
@echo "Additional tools to install manually:"

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,11 @@ require (
149149
github.com/envoyproxy/go-control-plane/envoy v1.37.0 // indirect
150150
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
151151
github.com/go-ole/go-ole v1.2.6 // indirect
152+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa // indirect
152153
github.com/jackc/pgpassfile v1.0.0 // indirect
153154
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
154155
github.com/jackc/puddle/v2 v2.2.2 // indirect
155156
github.com/klauspost/compress v1.18.5 // indirect
156-
github.com/lib/pq v1.10.9 // indirect
157157
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
158158
github.com/magiconair/properties v1.8.10 // indirect
159159
github.com/microsoft/kiota-abstractions-go v1.9.4 // indirect

‎go.sum‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ github.com/googleapis/gax-go/v2 v2.21.0 h1:h45NjjzEO3faG9Lg/cFrBh2PgegVVgzqKzuZl
236236
github.com/googleapis/gax-go/v2 v2.21.0/go.mod h1:But/NJU6TnZsrLai/xBAQLLz+Hc7fHZJt/hsCz3Fih4=
237237
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
238238
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
239+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa h1:s+4MhCQ6YrzisK6hFJUX53drDT4UsSW3DEhKn0ifuHw=
240+
github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
239241
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
240242
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
241243
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=

0 commit comments

Comments
 (0)