Skip to content

Add binary pg_upgrade CI job (existing-mode suite + dependency guard) - #20

Draft
jnasbyupgrade wants to merge 1 commit into
test-install-foundationfrom
pg-upgrade-ci
Draft

Add binary pg_upgrade CI job (existing-mode suite + dependency guard)#20
jnasbyupgrade wants to merge 1 commit into
test-install-foundationfrom
pg-upgrade-ci

Conversation

@jnasbyupgrade

Copy link
Copy Markdown
Contributor

Migrated from fork-internal PR jnasbyupgrade#6 to enable a native same-repo stacked PR (bases off test-install-foundation, which now exists directly on Postgres-Extensions/extension_tools). Original PR: jnasbyupgrade#6


Stack position

Third link in a stack, all in jnasbyupgrade/extension_tools:
fix-cat-tools-install (base, upstream draft PR #10)
test-install-foundation (fork-internal draft PR #4)
pg-upgrade-ci (this PR, based on test-install-foundation).

None of these branches exist yet on Postgres-Extensions/extension_tools, so this PR's own CI may not be meaningfully triggerable/mergeable until the earlier links land somewhere real — flagging this per the task instructions rather than guessing at why a run behaves oddly.

What this builds

Following ~/advanced-extension-testing.md (reference implementation: Postgres-Extensions/cat_tools's current master, specifically its pg-upgrade-test job in ci.yml and bin/test_existing) and ~/test-fixes.md items 1/2/3/5/6:

  1. bin/test_existing — a committed, parameterized script (plant-guard, prepare, run-suite subcommands) factoring the install→guard→pg_upgrade→assert→run-suite flow out of inline YAML.
  2. .github/scripts/pg_upgrade_cluster — the binary-pg_upgrade cluster mechanics (recreate-old, upgrade), generic CI plumbing with nothing extension-specific in it.
  3. pg-upgrade-test job in ci.yml — 3 legs: 12→13, 16→17 (adjacent-major legs near the floor/ceiling) and 12→17 (full span). Each leg installs extension_drop fresh on the old cluster, plants + proves a dependency guard, binary pg_upgrades straight to the new major, then runs the suite in TEST_LOAD_SOURCE=existing mode against the real migrated database.
  4. Dynamic version assertionassert_version() derives expected version from make -s print-PGXNVERSION, with empty-value guards on both sides.
  5. changes job — cheap docs-only gate (fail-safe-first GITHUB_OUTPUT write), gating only the new heavy pg-upgrade-test job (the pre-existing test job is already cheap, so it stays ungated).
  6. Cost gatingpg-upgrade-test needs [changes, test]; workflow-level concurrency group with cancel-in-progress: true.
  7. all-checks-passed needs list updated to [changes, test, pg-upgrade-test].

What I took verbatim / adapted / skipped from cat_tools

  • .github/scripts/pg_upgrade_cluster: taken essentially verbatim — it's pure cluster mechanics (pg_ctlcluster/pg_createcluster/pg_upgrade against the pgxn-tools "test" cluster convention), nothing cat_tools-specific in it.
  • bin/test_existing: adapted and substantially smaller. extension_drop has only ever shipped one real version (1.0.0 — see HISTORY.asc/RELEASE.md; the only PGXN listing, 0.1.x from 2017, predates the current SQL entirely), so:
    • No bridge-update leg — no known pg_upgrade-unsafe old version exists to bridge from (per the doc's own guidance not to build this preemptively).
    • No update-scenario / update-check / update-check-version / diff-fresh subcommands — nothing to update from yet (the foundation PR's TEST_LOAD_SOURCE=update mode is wired up but unexercised for the same reason).
    • No post-upgrade "update to current" step — extversion is already current on both sides of every leg, since only one version has ever existed.
  • Matrix shape (old_pg/new_pg pairs via strategy.matrix.include) and the dependency-guard technique itself (plant a view with a hard pg_depend edge on a stable extension member, prove a non-CASCADE drop is blocked) are the same pattern, unchanged.

Something NOT in cat_tools's model — found by actually running this locally

cat_tools's control file pins schema = 'cat_tools' (non-relocatable), so it has no test that freely retargets the install schema. extension_drop's test/sql/schema.sql (added by the foundation PR) does — it proves the schema-targeting/quoting pipeline by unconditionally doing DROP EXTENSION extension_drop; (non-CASCADE) partway through. That collides for real with a persistent dependency guard: the very first statement in schema.sql failed with the guard's own 2BP01 error when I ran the full suite against a real pg_upgraded database locally. test/sql/zzz_build.sql survives (it does a CASCADE drop) but adds a drop cascades to view ... NOTICE not present in the checked-in expected output. Fix: bin/test_existing's run_suite computes an existing-mode REGRESS list that excludes schema and zzz_build (both already proven by the regular fresh test job on every PostgreSQL major) — derived from test/sql/*.sql's actual contents, not a hardcoded list, so a future new test file is automatically included unless deliberately excluded. Flagging this loudly per the "ultimate goal" section: this is a genuinely new pattern (schema-flexible extension + persistent dependency guard) that cat_tools's own model doesn't need to solve.

Deliberately skipped

  • Single-source PG-major list (§6g) — not built. The test job's PG list (9.3–17, extension_drop's own claimed floor) and pg-upgrade-test's floor (12) are genuinely different lists for a real reason, not accidental duplication: make install unconditionally builds cat_tools from Postgres-Extensions/cat_tools's master (PGXN's published cat_tools is a stale 2017 release extension_drop can't use — see the Makefile's own cat_tools target comment), and that current cat_tools requires PostgreSQL ≥ 12 for a fresh install (its own META.json). Unifying two lists that are supposed to differ would be actively wrong here, so I left them separate and documented why in ci.yml's top-of-file comment.
  • pg-upgrade-stepwise (§6c-bis, every-major climb) — not built. extension_drop has no catalog-touching views/functions (per §7's risk profile), so the incremental value over the 3 existing legs looked low relative to the cost (installing every PG major, N sequential pg_upgrades). Can be added later if that risk profile changes.
  • Automated all-checks-passed needs-list self-check (cat_tools has a Python step verifying its needs: list matches the actual job set) — skipped to keep this PR's diff focused; I manually confirmed [changes, test, pg-upgrade-test] matches the actual 3 non-aggregator jobs.

Local verification

This container has PostgreSQL 12 (port 5412) and 17 (port 5417) running — exactly the floor/ceiling this job uses. I did not use the persistent main clusters; instead created throwaway test-named clusters (matching the pgxn-tools pg-start convention pg_upgrade_cluster expects) on a separate port, ran the actual committed scripts against them, and tore them down afterward:

  1. make install PG_CONFIG=.../12/bin/pg_config (installs extension_drop + git-built cat_tools 0.3.0 on PG12)
  2. bin/test_existing prepare extdrop_upg3 — creates the DB, CREATE EXTENSION ... CASCADE, plants + proves the dependency guard (confirmed non-CASCADE drop blocked with 2BP01).
  3. make install PG_CONFIG=.../17/bin/pg_config (extension_drop/cat_tools are pure SQL, so this just needs to be present in the new cluster's sharedir).
  4. INITDB_OPTS="--data-checksums --auth trust" .github/scripts/pg_upgrade_cluster upgrade 12 17 — real binary pg_upgrade, completed clean.
  5. bin/test_existing run-suite extdrop_upg3 — asserted version (1.0.0 both sides), re-proved the guard survived pg_upgrade, ran make test/make verify-results in existing mode (dependency_guard + simple, schema/zzz_build excluded per above) — all passed, exit code 0. Re-confirmed the guard was still present afterward.

This process caught a real bug before it ever reached CI: my first draft passed REGRESS=$regress through an unquoted flat string, which word-split the multi-value REGRESS="dependency_guard simple" into a bogus simple make target (No rule to make target 'simple'). Fixed by switching to a bash array (existing_args=(...), make test "${existing_args[@]}") — see the comment left at that fix site in bin/test_existing.

No environment quirks unrelated to this change were encountered (the 12 → 13/16 → 17 legs weren't locally re-verified since only PG12/17 binaries are installed in this dev container, but they exercise the identical script paths already proven end-to-end on 12 → 17).

CI status

Pushed to jnasby/pg-upgrade-ci; watching the Actions run now and will report/fix any failures.

…-mode suite

Adds a pg-upgrade-test job (3 legs: 12->13, 16->17, 12->17) that installs
extension_drop on an old cluster, plants a dependency guard, performs a real
binary pg_upgrade, and runs the suite in TEST_LOAD_SOURCE=existing mode
against the migrated database, with a dynamic version assertion and a
docs-only cost gate for the new heavy job. Modeled on
Postgres-Extensions/cat_tools's bin/test_existing and
.github/scripts/pg_upgrade_cluster, substantially simplified: extension_drop
has only ever shipped one real version, so no bridge leg or update-scenario
machinery is needed. Verified end to end locally (PG12 -> PG17) before
committing, which also surfaced a real conflict between a persistent
dependency guard and test/sql/schema.sql's unconditional non-cascade drop,
now handled by excluding schema.sql/zzz_build.sql from the existing-mode
REGRESS list (both are already proven by the fresh-install `test` job).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e14ec857-b116-44ab-ae85-1b941492a4d3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant