From d550caee94b14b328c66b18ed321cd0fa254f568 Mon Sep 17 00:00:00 2001 From: jnasbyupgrade Date: Sun, 2 Aug 2026 17:42:43 -0500 Subject: [PATCH] Add post-tag-version-bump to freeze default_version after a release Committing versioned SQL files (sql/{ext}--{version}.sql) means ongoing development after a release can silently regenerate and overwrite the file that was just released, since `make` always regenerates whatever file matches the current default_version. New target `post-tag-version-bump` bumps each extension's default_version to a placeholder alias (`stable` by default) via the new `bump-default-version.sh` script, so a subsequent `make` freezes the released file instead of overwriting it. Deliberately a separate, explicit step rather than wired into `tag`/`dist`: both of those run routinely outside of an actual release (including from this project's own test suite), and `dist` is documented/tested to leave the repository clean -- auto-bumping on every such run would both break that guarantee and risk bumping default_version on a version nobody meant to release yet. Controlled via two new variables, following the existing PGXNTOOL_ENABLE_*/PGXNTOOL_* override pattern: - PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP (default yes) makes the target a no-op when set to no - PGXNTOOL_POST_TAG_VERSION (default stable) controls the placeholder value _.gitignore now ignores sql/*--stable.sql to match the default placeholder. Fixes #20. Related changes in pgxntool-test: - Add test/standard/tag-version-bump.bats: standalone script-logic coverage for bump-default-version.sh, plus make -n dry-run and stub-based coverage of post-tag-version-bump's wiring, and a real end-to-end smoke test - Add pgxntool/bump-default-version.sh to the exact distribution-contents manifest (test/lib/dist-expected-files.txt) Co-Authored-By: Claude --- HISTORY.asc | 19 ++++++ README.asc | 15 +++++ README.html | 128 +++++++++++++++++++++++++--------------- _.gitignore | 4 ++ base.mk | 60 +++++++++++++++++++ bump-default-version.sh | 50 ++++++++++++++++ 6 files changed, 230 insertions(+), 46 deletions(-) create mode 100755 bump-default-version.sh diff --git a/HISTORY.asc b/HISTORY.asc index bdd5121..b9bed1c 100644 --- a/HISTORY.asc +++ b/HISTORY.asc @@ -1,3 +1,22 @@ +STABLE +------ +== Add `make post-tag-version-bump` to freeze a just-released version +Committing versioned SQL files (`sql/{ext}--{version}.sql`) means ongoing +development after a release can silently regenerate and overwrite the file +that was just released, since `make` always regenerates whatever file +matches the current `default_version`. New target `post-tag-version-bump` +bumps each extension's `default_version` to a placeholder alias (`stable` +by default), so a subsequent `make` freezes the released file instead of +overwriting it. Deliberately a separate, explicit step rather than wired +into `tag`/`dist` -- both of those run routinely outside of an actual +release, and `dist` is documented to leave the repository clean, so +auto-bumping on every such run would break that guarantee. Controlled via +`PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP` (default `yes`) and +`PGXNTOOL_POST_TAG_VERSION` (default `stable`); `_.gitignore` now ignores +`sql/*--stable.sql` to match. + +Issues fixed in this release: #20 + 2.3.0 ----- == Rename `PGTLE_VERSION` to `PGXNTOOL_PGTLE_VERSION` diff --git a/README.asc b/README.asc index 45c4b59..883582e 100644 --- a/README.asc +++ b/README.asc @@ -262,6 +262,13 @@ If a tag for the current version already exists and points at your current commi WARNING: You will be very unhappy if you forget to update the .control file for your extension! There is an https://github.com/Postgres-Extensions/pgxntool/issues/1[open issue] to improve this. +[[_post_tag_version_bump]] +=== post-tag-version-bump + +Committing versioned SQL files (see <<_committing_version_files>>) means ongoing development after a release can silently regenerate and overwrite the file that was just released, since `make` always regenerates whatever file matches the current `default_version`. `make post-tag-version-bump` bumps each extension's `default_version` to a placeholder alias -- `stable` by default -- so a subsequent `make` instead regenerates `sql/{ext}--stable.sql`, keeping the released file frozen. + +This is a deliberate, separate step -- *not* wired into `tag` or `dist`. Both of those run routinely outside of an actual release (this project's own test suite calls `make dist` freely, and `dist` is documented to leave your repository clean), so tying a tracked `.control` file mutation to every such run would both break that guarantee and risk bumping `default_version` on a version nobody actually meant to release yet. Run `make post-tag-version-bump` yourself as an explicit step in your own release process, right after the tag you're actually releasing has been created and pushed. See `PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP` and `PGXNTOOL_POST_TAG_VERSION` below to control or disable this. + === dist `make dist` will create a .zip file for your current version that you can upload to PGXN. It first runs `tag` (creating/pushing the version's git tag as described above if needed), then uses `git archive` at that tag to build the .zip file, so the archive always matches the exact tagged commit. The file is named after the PGXN name and version (the top-level "name" and "version" attributes in META.json, generated from `META.in.json`). The .zip file is placed in the *parent* directory so as not to clutter up your git repo. @@ -678,6 +685,14 @@ Default: `origin`. The git remote used by `tag`, `rmtag`, `forcetag`, and `dist` make dist PGXN_REMOTE=upstream ---- +=== PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP * + +Default: `yes`. Set to `no` to make `make post-tag-version-bump` a no-op instead of bumping `default_version` -- useful if a shared release script always calls it but a specific project wants to opt out without editing that script. See <<_post_tag_version_bump>>. + +=== PGXNTOOL_POST_TAG_VERSION + +Default: `stable`. The placeholder value `make post-tag-version-bump` sets `default_version` to. Not valid semver, but PostgreSQL doesn't require semver for extension versions. If you override this, also update the `sql/*--stable.sql` line in your `.gitignore` to match. + === ASCIIDOC Default: auto-detected, the first of `asciidoctor` or `asciidoc` found on `PATH`. Path to the Asciidoc processor used to build `.html` files from `$(ASCIIDOC_EXTS)` source files. Override if the processor you want isn't first on `PATH`, or isn't on `PATH` at all. See <<_document_handling>>. diff --git a/README.html b/README.html index ba71c2a..2c828af 100644 --- a/README.html +++ b/README.html @@ -455,15 +455,16 @@

PGXNtool

  • 4.5. testdeps
  • 4.6. results
  • 4.7. tag
  • -
  • 4.8. dist
  • -
  • 4.9. pgxntool-sync
  • -
  • 4.10. pgxntool-version
  • -
  • 4.11. list
  • -
  • 4.12. print-%
  • -
  • 4.13. distclean
  • -
  • 4.14. pgtle
  • -
  • 4.15. check-pgtle
  • -
  • 4.16. run-pgtle
  • +
  • 4.8. post-tag-version-bump
  • +
  • 4.9. dist
  • +
  • 4.10. pgxntool-sync
  • +
  • 4.11. pgxntool-version
  • +
  • 4.12. list
  • +
  • 4.13. print-%
  • +
  • 4.14. distclean
  • +
  • 4.15. pgtle
  • +
  • 4.16. check-pgtle
  • +
  • 4.17. run-pgtle
  • 5. Version-Specific SQL Files @@ -499,18 +500,20 @@

    PGXNtool

  • 8. Configuration Variables
  • 9. Copyright
  • @@ -635,6 +638,18 @@

    Note +test exits non-zero (after printing regression.diffs) if any test fails. Previously it always exited 0 regardless of test results, silently masking failures from CI and other automation that relies on the exit code. + + + + +
    + + + + @@ -1036,7 +1051,16 @@

    4.
    -

    4.8. dist

    +

    4.8. post-tag-version-bump

    +
    +

    Committing versioned SQL files (see Committing Version Files) means ongoing development after a release can silently regenerate and overwrite the file that was just released, since make always regenerates whatever file matches the current default_version. make post-tag-version-bump bumps each extension’s default_version to a placeholder alias — stable by default — so a subsequent make instead regenerates sql/{ext}--stable.sql, keeping the released file frozen.

    +
    +
    +

    This is a deliberate, separate step — not wired into tag or dist. Both of those run routinely outside of an actual release (this project’s own test suite calls make dist freely, and dist is documented to leave your repository clean), so tying a tracked .control file mutation to every such run would both break that guarantee and risk bumping default_version on a version nobody actually meant to release yet. Run make post-tag-version-bump yourself as an explicit step in your own release process, right after the tag you’re actually releasing has been created and pushed. See PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP and PGXNTOOL_POST_TAG_VERSION below to control or disable this.

    +
    +
    +
    +

    4.9. dist

    make dist will create a .zip file for your current version that you can upload to PGXN. It first runs tag (creating/pushing the version’s git tag as described above if needed), then uses git archive at that tag to build the .zip file, so the archive always matches the exact tagged commit. The file is named after the PGXN name and version (the top-level "name" and "version" attributes in META.json, generated from META.in.json). The .zip file is placed in the parent directory so as not to clutter up your git repo.

    @@ -1069,9 +1093,9 @@

    -

    4.9. pgxntool-sync

    +

    4.10. pgxntool-sync

    -

    This rule will pull down the latest released version of PGXNtool via git subtree pull and then reconcile the files setup.sh copied into your project (.gitignore, test/deps.sql) with a 3-way merge.

    +

    This rule will pull down the latest released version of PGXNtool via git subtree pull and then reconcile the files setup.sh copied into your project (.gitignore, test/deps.sql) with a 3-way merge (it also verifies the test/pgxntool symlink, recreating it if missing).

    +
    Note
    +
    While you can still run make installcheck or any other valid PGXS make target directly, it’s recommended to use make test when using pgxntool. The test target ensures proper test isolation and correct dependency installation.
    @@ -1135,7 +1159,7 @@

    -

    4.10. pgxntool-version

    +

    4.11. pgxntool-version

    make pgxntool-version prints the version of the embedded pgxntool copy, read from the first line of pgxntool/HISTORY.asc. That line is "STABLE" instead of a version number if this copy was synced from an unreleased commit rather than a tagged release.

    @@ -1153,19 +1177,19 @@

    -

    4.11. list

    +

    4.12. list

    make list prints every make target defined in your project — including ones provided by PGXS and pgxntool, not just ones you wrote — one per line. Useful for discovering what’s available without reading through the Makefile.

    -

    4.12. print-%

    +

    4.13. print-%

    make print-VARNAME prints the current value (and origin) of any make variable, e.g. make print-PGXNVERSION. Useful for debugging why a variable isn’t set to what you expect.

    -

    4.13. distclean

    +

    4.14. distclean

    make distclean removes generated configuration files (META.json — generated from META.in.json — plus meta.mk and control.mk) that survive a normal make clean.

    @@ -1191,7 +1215,7 @@

    -

    4.14. pgtle

    +

    4.15. pgtle

    Generates pg_tle (Trusted Language Extensions) registration SQL files for deploying extensions in managed environments like AWS RDS/Aurora. See [_pg_tle_Support] for complete documentation.

    @@ -1208,7 +1232,7 @@

    -

    4.15. check-pgtle

    +

    4.16. check-pgtle

    Checks if pg_tle is installed and reports the version. This target: - Reports the version from pg_extension if CREATE EXTENSION pg_tle has been run in the database @@ -1224,7 +1248,7 @@

    -

    4.16. run-pgtle

    +

    4.17. run-pgtle

    Registers all extensions with pg_tle by executing the generated pg_tle registration SQL files in a PostgreSQL database. This target: - Requires pg_tle to be installed in the target database. This isn’t a make-level dependency on check-pgtlepgtle.sh checks it itself when it runs, and will tell you to run make check-pgtle if pg_tle isn’t there @@ -1881,73 +1905,85 @@

    -

    8.2. ASCIIDOC

    +

    8.2. PGXNTOOL_ENABLE_POST_TAG_VERSION_BUMP *

    +
    +

    Default: yes. Set to no to make make post-tag-version-bump a no-op instead of bumping default_version — useful if a shared release script always calls it but a specific project wants to opt out without editing that script. See post-tag-version-bump.

    +
    +
    +
    +

    8.3. PGXNTOOL_POST_TAG_VERSION

    +
    +

    Default: stable. The placeholder value make post-tag-version-bump sets default_version to. Not valid semver, but PostgreSQL doesn’t require semver for extension versions. If you override this, also update the sql/*--stable.sql line in your .gitignore to match.

    +
    +
    +
    +

    8.4. ASCIIDOC

    Default: auto-detected, the first of asciidoctor or asciidoc found on PATH. Path to the Asciidoc processor used to build .html files from $(ASCIIDOC_EXTS) source files. Override if the processor you want isn’t first on PATH, or isn’t on PATH at all. See Document Handling.

    -

    8.3. PGXNTOOL_PGTLE_VERSION

    +

    8.5. PGXNTOOL_PGTLE_VERSION

    Default: unset (generates every known pg_tle version range). Set on the command line to limit make pgtle to the single version range this value falls into. Not named PGTLE_VERSION: make auto-imports same-named environment variables, and that name collided silently with CI jobs that set a PGTLE_VERSION env var for an unrelated purpose (which pg_tle to test against). See pgtle.

    -

    8.4. PG_CONFIG

    +

    8.6. PG_CONFIG

    Default: pg_config. Path to the pg_config binary used to detect the PostgreSQL version and locate PGXS. Override when the right pg_config isn’t the one on PATH, such as when testing against a specific PostgreSQL install.

    -

    8.5. TESTDIR

    +

    8.7. TESTDIR

    Default: test. Root directory for test input files: $(TESTDIR)/sql/, $(TESTDIR)/expected/, $(TESTDIR)/build/, $(TESTDIR)/install/. Overriding this on its own is unusual; it mainly exists so TESTOUT has a sensible default.

    -

    8.6. TESTOUT

    +

    8.8. TESTOUT

    Default: $(TESTDIR). Directory pg_regress writes actual test output to — $(TESTOUT)/results/, $(TESTOUT)/regression.diffs, etc. — via --outputdir in REGRESS_OPTS. Kept separate from TESTDIR so generated output can be pointed somewhere other than the directory holding your checked-in sql/expected files, if you want that separation.

    -

    8.7. PGXNTOOL_VERIFY_RESULTS_MODE

    +

    8.9. PGXNTOOL_VERIFY_RESULTS_MODE

    Default: pgtap. Controls how the verify-results safeguard decides whether tests are failing.

    -

    8.7.1. pgtap

    +

    8.9.1. pgtap

    Scans test/results/*.out for pgTap not ok lines and plan mismatches, falling back to checking for regression.diffs too. Use this mode when your test suite uses pgTap.

    -

    8.7.2. diffs

    +

    8.9.2. diffs

    Checks only for regression.diffs, matching classic pg_regress behavior. Use this mode when your tests use plain SQL expected-output comparison only.

    -

    8.8. PGXNTOOL_ENABLE_TEST_BUILD *

    +

    8.10. PGXNTOOL_ENABLE_TEST_BUILD *

    Default: auto-detected — yes if test/build/*.sql files exist, no otherwise. Enables or disables the test-build pre-flight SQL check. Set explicitly to yes if you want an error when test/build/ unexpectedly has no SQL files (catches accidental deletion of its contents), or to no to disable the check even when files are present.

    -

    8.9. PGXNTOOL_ENABLE_TEST_INSTALL *

    +

    8.11. PGXNTOOL_ENABLE_TEST_INSTALL *

    Default: auto-detected — yes if test/install/*.sql files exist, no otherwise. Enables or disables the test/install schedule-based setup feature. Same explicit-override semantics as PGXNTOOL_ENABLE_TEST_BUILD.

    -

    8.10. PGXNTOOL_ENABLE_VERIFY_RESULTS *

    +

    8.12. PGXNTOOL_ENABLE_VERIFY_RESULTS *

    Default: yes. Enables or disables the verify-results safeguard that blocks make results when tests are failing. Setting it to empty on the command line (make PGXNTOOL_ENABLE_VERIFY_RESULTS= results) also disables it.

    -

    8.11. PGXNTOOL_ENABLE_CHECK_STALE_EXPECTED *

    +

    8.13. PGXNTOOL_ENABLE_CHECK_STALE_EXPECTED *

    Default: yes. Enables or disables the check-stale-expected safeguard, which fails make test if test/expected/ (or test/build/expected/) contains a .out file with no corresponding .sql file — catching a stale file left behind after a test was renamed or removed. Set to no to make the check a complete no-op (it’s dropped from TEST_DEPS entirely).

    @@ -1956,13 +1992,13 @@

    -

    8.12. PGXNTOOL_CHECK_EXPECTED_FILE_TYPES *

    +

    8.14. PGXNTOOL_CHECK_EXPECTED_FILE_TYPES *

    Default: yes. Sub-check of check-stale-expected, independent of PGXNTOOL_ENABLE_CHECK_STALE_EXPECTED: fails (with a distinct error message and exit code from the orphaned-.out check) if test/expected/ (or test/build/expected/) contains any file that isn’t *.out. Set to no to disable just this sub-check while leaving the orphaned-.out check active.

    -

    8.13. PGXNTOOL_NO_PGXS_INCLUDE

    +

    8.15. PGXNTOOL_NO_PGXS_INCLUDE

    Default: unset (PGXS is included normally). Skips including PGXS ($(PGXS)) entirely. This is only for advanced scenarios where you need to manage the PGXS include yourself; most projects should never set this.

    @@ -1983,7 +2019,7 @@