Repository navigation
ci: encrypt the migration dry-run's connections to its restored snapshot - #3775
Conversation
…hot (BS#3774) Once prod is on PostgreSQL 18, the newest snapshot restores with default.postgres18, which sets rds.force_ssl = 1 and refuses the plaintext connections both postgres-js clients in migrate-dryrun make today. Set PGSSL=require on the shape-probe and dry-run steps, and fail the dry-run step unless pg_stat_ssl reports its connection as encrypted, which proves PGSSL is honored while the snapshots are still 14.22. The restore command is unchanged.
… of dumping an uncaught trace (BS#3774) A timeout, auth or TLS error in the inline check used to surface as a raw Node uncaught-exception trace with no `::error::` annotation. It now prints `::error::sandbox SSL check failed: <message>` and exits 1. Only `err.message` is printed, never the error object, which can carry the connection options.
Schema constraint shape reportno schema or migration changes detected in this PR |
1703f39 to
d7e19ae
Compare
|
Exercised the migration dry-run against the current prod snapshot (the newest automated snapshot, taken 2026-11-03 21:04 PST, engine 14.22). The PR's own CI skips that job because Run: https://github.com/WXYC/Backend-Service/actions/runs/41965162921. Migration Dry-Run (prod-shaped data) passed. The new check logged The head (d7e19ae) also wraps the check in try/catch. A connect or query failure now produces a |
Closes #3774
Keeps the required check
Migration Dry-Run (prod-shaped data)able to connect after prod moves to PostgreSQL 18. The newest snapshot will then restore withdefault.postgres18, whoserds.force_ssl = 1refuses the plaintext connections this job makes today. The fix is on the client side; the restore command is unchanged.What changed
One file,
.github/workflows/test.yml, in themigrate-dryrunjob:PGSSL: requireon the two steps that connect to the sandbox,Probe pre-migration data shapeandRun drizzle:migrate against sandbox. Both use postgres-js with nossloption (scripts/schema-shape-report.mjs,scripts/dryrun-migrate.mjs). No other step connects to the sandbox, and none uses psql or libpq.node scripts/dryrun-migrate.mjs, a short postgres-js check with the same options and env. It fails the step unlessSELECT ssl FROM pg_stat_ssl WHERE pid = pg_backend_pid()returns true, and logssandbox connection ssl: <value>. RDS 14 accepts TLS without forcing it, so this passes on today's 14.22 snapshots and provesPGSSLis honored before the upgrade makes it matter.Why
PGSSLis enoughThe install step resolves
postgresto 3.4.9 (rootpackage.jsonrange^3.4.9; confirmed withnpm install --dry-runusing the step's flags).env['PG' + k.toUpperCase()](src/index.js L476 at v3.4.9).'require'setsrejectUnauthorized: false(src/connection.js L283-L284), so it encrypts without a CA bundle.'prefer'falls back to plaintext (L271).src/index.jsL460 andsecureOptionsinsrc/socket.js.Verification
This PR's own CI will report the dry-run as skipped. The job is gated on the
db-initpaths filter, andtest.ymlis not in it. Aworkflow_dispatchrun would skip it too, because dispatch computes the filter against the merge base. The first migration PR after this merges is the first real run.So I verified the step locally. I extracted its
run:script from the YAML and ran it underbash -eo pipefailagainst a local PostgreSQL 18.6 with TLS on and a self-signed certificate:PGSSLrequiressl: true, exit 0ssl: false,::error::, exit 1requiressl: true, exit 0ssl: false,::error::, exit 1no encryption, exit 1requiressl: true, exit 0"Plaintext rejected" is a
hostnossl ... rejectrule inpg_hba.conf, which stands in forrds.force_ssl = 1.Also checked:
prettier --check(3.9.9, the lockfile version) passes.actionlintreports the same findings as onmain, none on the changed steps.scripts/check-sql-claim-docs.mjspasses.