Repository navigation
feat: test against the PostgreSQL 19 beta and refresh pinned tooling - #68
Conversation
- Verifier: POSTGRES_FIXTURE_MAJOR accepts 19, pinned by manifest-list digest to postgres:19beta4-bookworm (PostgreSQL 19 has no release candidate or final release as of 2026-10-11). Each major now carries its own tag, and the fixture fails when the started server's major differs from the requested one. HypoPG 1.4.3-1.pgdg12+2 installs for 19 from the pgdg beta component. - CI: add the non-required Integration (PostgreSQL 19) matrix job. - Release: Node.js 24.15.0 -> 24.21.0 for the npm staging job; github/codeql-action v4.38.2 -> v4.38.3. - Docs: README/CONTRIBUTING/git-workflow/security-posture/CHANGELOG.
Resolve the fixture conflict by keeping main's shared PostgresFixture.Image (used by the new TLS fixture) and pointing it at this branch's tag/digest table, so the TLS scenarios also run on 19beta4. CHANGELOG keeps main's entries first. The roadmap and the pg_stat_statements comment now include 19.
|
Review (AI coding agent under the maintainer's authorization for this task; not a human review). I read the whole diff and the workflow changes line by line, and re-verified the pins upstream: the codeql-action v4.38.3 tag resolves to commit 24c54180…, Node 24.21.0 is LTS in nodejs.org index.json, and the 19beta4/18 manifest digests match the registry. I found no credentials, connection strings, database output or generated artifacts. I merged main after #66/#67; the conflict in PostgresFixture.cs was resolved so the TLS fixture uses this branch's tag/digest table. Local 19/18/17 integration passed after the merge. Hosted on 3ea7ab5: every workflow succeeded, including Integration (PostgreSQL 19) (run 38113954154: ALL MCP INTEGRATION SCENARIOS PASSED, 25 PASS lines including TLS). The flake diagnosis is in the description: the 18 failure came from fixture start without a cached image (the first 18 pull completed only after the batch ended); the 19 failure is unrecoverable, and 19 further runs under heavier concurrency and CPU saturation did not reproduce it. |
Prepares the 0.6.0 release. A minor version, because #67 makes verified TLS the default, which is a breaking change for remote connection strings without `SSL Mode`. This PR does not tag, release or publish anything. After it merges, `v0.6.0` is tagged on the merge commit and `release.yml` is dispatched from `main` with target `all`, as the maintainer authorized for this task. ## Change - `src/PostgreSqlMcp/PostgreSqlMcp.csproj` `Version`, `npm/package.json` `version` and all five platform `optionalDependencies`: 0.5.0 → 0.6.0. - CHANGELOG: the Unreleased entries from #66, #67 and #68 become `## 0.6.0`. The section opens with a bold **upgrade note** for the TLS default: what changes, the errors you will see (`tls_verification_failed`, `tls_unavailable`), running `--validate` before upgrading, and **rollback**, either `SSL Mode=Prefer` on the affected profile or pinning 0.5.0. - README: a callout under "Fastest start" for anyone upgrading from 0.5.0 or earlier. The upgrade section now leads with "0.6.0 breaking change: TLS is verified by default", including both rollback routes, and the install, registration, validation and upgrade commands use 0.6.0. - CONTRIBUTING: 0.6.0 joins the versioning history; the release dispatch and Windows npm approval examples use 0.6.0. Bug template placeholder. - `docs/security-posture.md` owner checklist: item 1 (merged as #67, which is not the maintainer's review of the drafts), item 6 (ships as 0.6.0) and item 7 (no signing key is configured locally or registered on GitHub, so `v0.6.0` is an annotated, unsigned tag). - Unchanged on purpose: historical references such as "Starting with 0.5.0", the 0.4.0 rollback note, `.bestpractices.json` (it describes released state) and the governance, roadmap and assurance-case drafts. Those stay marked as unconfirmed maintainer drafts. ## Compatibility The only behavior change in 0.6.0 is the TLS default described above. Tool names, parameters, environment variables, CLI flags and the targets-file format are unchanged, so 0.5.0 reads the same configuration if a rollback is needed. ## Evidence Local (Linux x64, SDK 10.0.401, Docker 29.1.3) on this branch: | Command | Result | |---|---| | `dotnet build postgresql-sharp-mcp.slnx -c Release -p:RestoreLockedMode=true` | 0 warnings, 0 errors | | `dotnet src/PostgreSqlMcp/bin/Release/net10.0/PostgreSqlMcp.dll --version` | `postgresql-sharp-mcp 0.6.0.0` | | `Build -- package --output <dir>` | main and five platform npm tarballs and the `.nupkg`, all named `0.6.0` | | `Verify -- packages --artifacts <dir>` | passed: local and global npm installs, fresh-cache npx from a loopback registry, NuGet tool, native commands, MCP initialize/tools and shutdown | Hosted checks: see this PR. Publication is verified after the release run, at the registries. ## Authorship Written by an AI coding agent (Claude Code) under the maintainer's authorization for the 0.6.0 release task. ## Checklist - [x] Title follows the commit format in [docs/git-workflow.md](https://github.com/codegiveness/postgresql-sharp-mcp/blob/main/docs/git-workflow.md#commits) - [x] Affected docs, help and `CHANGELOG.md` updated - [x] No credentials, real connection strings, customer SQL or database results anywhere in the change or this description - [x] Workflow changes (if any) pin actions to full commit SHAs and keep least-privilege permissions (no workflow changes) Co-authored-by: AG <288536783+codegiveness@users.noreply.github.com>
Problem
The maintainer asked that the server use and support the latest PostgreSQL and the latest packages and tools. PostgreSQL 19 is not released yet. On 2026-10-11 postgresql.org
versions.jsonlisted 13–18 with 18.6 current; the newest announcement was 19 Beta 4 (2026-09-24); and Docker Hub had19beta1–19beta4but no19or19rc*tag. Nothing verified the server against 19, and a dependency audit was due.Behavior change
No server or runtime change (
src/untouched).POSTGRES_FIXTURE_MAJOR=19is accepted, pinned topostgres:19beta4-bookworm@sha256:4c618d9a30e0b88078b9371a0499d7055da9ab7f5afe386a460758eac9857f06(digest read from the registry'sDocker-Content-Digest), with HypoPG1.4.3-1.pgdg12+2, the same version as 13–18. The fixture now stores a tag and a digest for each major. It fails at start if the container'sserver_version_nummajor differs from the requested one, so a mislabeled digest cannot silently test a different major.'19'(Integration (PostgreSQL 19)). It is not a required check. It is notcontinue-on-erroreither, so a failure shows on the PR without blocking merges.github/codeql-actionis bumped from v4.38.2 to v4.38.3 (24c54180a607b1449ed407dd24f251e4e9147c8d, reached by following the annotated tag to its commit) incodeql.ymlandscorecard.yml. The release npm job's Node goes from 24.15.0 to 24.21.0 (LTS, 2026-09-07); CONTRIBUTING and the security posture are updated to match.19-bookwormwhen 19 ships. CHANGELOG has Unreleased entries.Version audit (2026-10-11)
Already at the latest stable and left unchanged:
sdk:10.0/runtime:10.0digestsdotnet list package --vulnerable --include-transitivereported nothing for all 8 projects. No lock file, notice or license changed.One item is deliberately not updated: FSharp.Core 5.0.2. It is a transitive dependency of FsCheck, at FsCheck's declared minimum, and is used only by the Verify tool, which is not shipped.
Compatibility and security impact
None for users. 19 is documented as a tested pre-release, not a support commitment. The workflow changes are one action SHA bump and the Node pin; permissions and triggers are unchanged. The codeql-action bump applies to both the baseline and candidate scans in the same run, so the raw-SARIF gate still compares like with like. Making the 19 job required is a ruleset change that only the owner can make.
Evidence
Local, Linux x64, .NET SDK 10.0.401, Docker 29.1.3:
POSTGRES_FIXTURE_MAJOR=<m> dotnet run --project tools/PostgreSqlMcp.Verify -c Release -- integrationALL MCP INTEGRATION SCENARIOS PASSEDon 19beta4 (4 runs), 18 (3), 17, 16, 15, 14, 13dotnet restore postgresql-sharp-mcp.slnx --locked-modedotnet build postgresql-sharp-mcp.slnx -c Release --no-restore -warnaserrorrelease-regressions,sarif-regressionsPostgreSqlMcp.Build -- package, thenVerify -- packages --artifacts artifacts/packagesdocker build --pull .thendocker run … --versionpostgresql-sharp-mcp 0.5.0.0index.json24c54180…; LTS, 2026-09-07One earlier batch exited 1 for 19 and 18 while other worktrees were running Docker fixtures at the same time. See "Flake diagnosis" below.
Review, merge with main and re-run (2026-10-11)
An AI coding agent reviewed this PR under the maintainer's authorization for the release task. This is not a human review. It read the whole diff, including the
ci.yml,codeql.yml,scorecard.ymlandrelease.ymlchanges line by line. Permissions, triggers,persist-credentialsand the base/candidate SARIF setup are unchanged; the codeql-action bump applies to both scans in the same run. It re-checked the pins against upstream:v4.38.3is an annotated tag whose commit is24c54180a607b1449ed407dd24f251e4e9147c8d.index.json(2026-09-07, LTS).19beta4-bookwormand18-bookwormreturn the pinnedDocker-Content-Digest;19rc1-bookwormreturns 404.No credentials, real connection strings, database output or generated artifacts are in the diff.
origin/main(with #66 and #67) was merged in. Two files conflicted:PostgresFixture.cs: feat!: verify TLS by default, measure coverage, make packages reproducible and propose Silver answers #67 added a sharedPostgresFixture.Image, which the newTlsFixtureuses, while this PR replaced the digest table with tag/digest pairs. The resolution keepsImageand builds it from this PR's table, so the TLS scenarios also run on 19beta4.CHANGELOG.md: main's entries come first.The roadmap range and the
pg_stat_statementscomment now include 19.Local re-run after the merge, on
3ea7ab5(Linux x64, SDK 10.0.401, Docker 29.1.3):dotnet build postgresql-sharp-mcp.slnx -c Release -p:RestoreLockedMode=truedotnet format style … --verify-no-changes --no-restore --severity warnPOSTGRES_FIXTURE_MAJOR=19/18/17… -- integrationALL MCP INTEGRATION SCENARIOS PASSEDon each; 25PASSlines, including the 3 TLS scenariosFlake diagnosis
What happened: the failing batch ran
for m in 19 18 17 13sequentially on 2026-10-11 between 02:41 and 02:47 UTC, piped throughgrep -E "FAIL|ALL MCP|error|warn|Unhandled|reports server". The verifier reports a failure on stderr as theVerificationExceptionmessage (for exampledocker exited with status N; expected 0. Captured output suppressed …orVerification failed (<type>) …) and exits 1. None of those messages contains a word the case-sensitive filter matched, so the cause was filtered out and cannot be recovered.What the surviving lines show:
privileged-login …PASS line and then exited 1. It failed in one of the last scenarios, after the fixture, HypoPG install and most scenarios had worked.Two separate failure points rule out a single deterministic defect.
18: fixture start without a cached image. The Docker daemon's journal on this VM begins at 02:32:37 UTC that day. It records every completed pull: 17 at 02:35:59, 19beta4 at 02:37:03, 13 at 02:45:54, and 18 only at 02:50:26, after the batch had ended. A pull by digest happens only when the image is absent, so 18 was not cached during the batch. The 18 run's
docker runhad to pull the image and failed fast without completing the pull. The verifier suppressesdocker runoutput (Captured output suppressed to protect credentials), so the registry or network error is not recorded, even unfiltered. It was not a timeout (the fixture allows 180 s) and not Docker Hub's rate limit (the anonymous limit read now is 100 per hour, and only three pulls completed in that hour). A cold pull of the same digest now takes 14 s. The PR'sapt-getsuspicion does not fit:apt-getruns only after the container has started. [INFERENCE] The likely cause is a transient registry or network failure on the first pull.19: late failure with the image cached. This run passed fixture start, HypoPG installation and most scenarios before failing.
Concurrent load at the time, from the session transcripts and the Docker daemon log: three other agent sessions on the same VM were building the solution and running a coverlet-instrumented
coveragerun, the TLS integration suite (with its extra TLS containers) and package verification. The daemon log showspostgresql-sharp-mcp-verify-*and-verify-tls-*containers from other worktrees starting throughout 02:41–02:48.Reproduction attempts on
2ba130e, all with full logs:ALL MCP INTEGRATION SCENARIOS PASSEDIntegration (PostgreSQL 19)and(PostgreSQL 18)on2ba130eConclusion: neither failure reproduces in 19 further local runs (under heavier concurrency and CPU saturation), nor in hosted CI. The 18 failure is explained by an uncached image whose first pull failed; that is an environment failure, not a defect in this branch. Hosted runners start with an empty cache, but the hosted 18 and 19 jobs pulled successfully. For the 19 failure, the most plausible cause is contention from the three concurrent sessions hitting one of the deadline-bound scenarios (request deadlines, pool churn, cancellation within 10 s) [INFERENCE: its failure text is unrecoverable, so this is not proven]. No product or fixture code was changed for either. If it recurs, capture the run's stderr unfiltered; the failing check's message is printed there.
Not verified: the release workflow with Node 24.21.0 (it runs at the 0.6.0 release); HypoPG for 19 on arm64.
Authorship
Written by an AI coding agent (Claude Code) for the maintainer to review.
Checklist
CHANGELOG.mdupdated