From eac34b9e31184b080795be11e0763f4d2f911c10 Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Tue, 23 Jun 2026 00:45:17 +0400 Subject: [PATCH 1/5] fix: expose dev builds as project dev version --- CMakeLists.txt | 5 +++++ cmake/AddPostgreSQLExtension.cmake | 15 +++++++++------ docs/development.md | 16 ++++++++++++---- h3/CMakeLists.txt | 2 +- h3/src/config.h.in | 2 +- h3/test/CMakeLists.txt | 2 +- h3/test/expected/extension.out | 4 ++-- h3/test/sql/extension.sql | 4 ++-- h3_postgis/CMakeLists.txt | 2 +- h3_postgis/src/config.h.in | 2 +- h3_postgis/test/CMakeLists.txt | 2 +- scripts/postrelease | 6 ++---- scripts/release | 5 +---- 13 files changed, 39 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 88eb67a5..f28811dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,11 @@ project( # set this to "${PROJECT_VERSION}" on release #set(INSTALL_VERSION "${PROJECT_VERSION}") set(INSTALL_VERSION "unreleased") +if(INSTALL_VERSION STREQUAL "unreleased") + set(INSTALL_OUTPUT_VERSION "${PROJECT_VERSION}dev") +else() + set(INSTALL_OUTPUT_VERSION "${INSTALL_VERSION}") +endif() set(H3_CORE_VERSION 4.5.0) set(H3_CORE_SHA256 0da8a392a6ff77e76b60e6a331a49497d0935b6b7b6899da7a3e2786139b0441) diff --git a/cmake/AddPostgreSQLExtension.cmake b/cmake/AddPostgreSQLExtension.cmake index e195a630..582ae6bf 100644 --- a/cmake/AddPostgreSQLExtension.cmake +++ b/cmake/AddPostgreSQLExtension.cmake @@ -273,20 +273,23 @@ function(PostgreSQL_add_extension LIBRARY_NAME) set(EXTENSION_UPDATES_PROCESSED "") foreach(file ${EXTENSION_UPDATES}) get_filename_component(UPDATE_NAME "${file}" NAME) - set(UPDATE_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_NAME}") + set(UPDATE_OUTPUT_NAME "${UPDATE_NAME}") + file(READ "${file}" UPDATE_CONTENTS) + if(UPDATE_OUTPUT_NAME MATCHES "--unreleased\\.sql$" AND NOT EXTENSION_VERSION STREQUAL "unreleased") + string(REGEX REPLACE "--unreleased\\.sql$" "--${EXTENSION_VERSION}.sql" UPDATE_OUTPUT_NAME "${UPDATE_OUTPUT_NAME}") + string(REPLACE "unreleased" "${EXTENSION_VERSION}" UPDATE_CONTENTS "${UPDATE_CONTENTS}") + endif() + set(UPDATE_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_OUTPUT_NAME}") if(PostgreSQL_VERSION_MAJOR VERSION_LESS "16") - file(READ "${file}" UPDATE_CONTENTS) string(REPLACE "@extschema:${EXTENSION_NAME}@." "" UPDATE_CONTENTS "${UPDATE_CONTENTS}") string(REPLACE "@extschema:h3@." "" UPDATE_CONTENTS "${UPDATE_CONTENTS}") string(REPLACE "@extschema:postgis@." "" UPDATE_CONTENTS "${UPDATE_CONTENTS}") string(REPLACE "@extschema:postgis_raster@." "" UPDATE_CONTENTS "${UPDATE_CONTENTS}") - file(WRITE "${UPDATE_OUTPUT}" "${UPDATE_CONTENTS}") - else() - configure_file("${file}" "${UPDATE_OUTPUT}" COPYONLY) endif() + file(WRITE "${UPDATE_OUTPUT}" "${UPDATE_CONTENTS}") configure_file( "${UPDATE_OUTPUT}" - "${EXTENSION_BUILD_EXTENSION_DIR}/${UPDATE_NAME}" + "${EXTENSION_BUILD_EXTENSION_DIR}/${UPDATE_OUTPUT_NAME}" COPYONLY ) list(APPEND EXTENSION_UPDATES_PROCESSED "${UPDATE_OUTPUT}") diff --git a/docs/development.md b/docs/development.md index 52ffbf36..12494eb9 100644 --- a/docs/development.md +++ b/docs/development.md @@ -2,6 +2,13 @@ In order to build and test your changes, simply run `./scripts/develop`. +During development, repository source files keep `INSTALL_VERSION` and the +latest update SQL filenames at `unreleased`. CMake derives the installed +PostgreSQL extension version from that placeholder as `${PROJECT_VERSION}dev`, +so a development build of project version `4.5.0` installs control, SQL, and +module metadata for `4.5.0dev`. Release scripts still replace the source +placeholder with the exact release version. + For local upgrade-validation coverage, install `pg_validate_extupgrade` so `ctest` can run the same extension-upgrade checks as CI. Without it, CTest registers explicit `*_validate_extupgrade_unavailable` placeholder tests and @@ -30,8 +37,9 @@ This command also validates that all extension GUCs are documented in `h3/src/gu - The script creates `release-X.Y.Z` and leaves the release changes uncommitted for review. 2. Review the release diff - - Root `CMakeLists.txt` has `VERSION X.Y.Z` and installs - `${PROJECT_VERSION}` instead of `unreleased`. + - Root `CMakeLists.txt` has `VERSION X.Y.Z`, sets `INSTALL_VERSION` to + `${PROJECT_VERSION}`, and therefore installs exactly `X.Y.Z` instead of + the generated development version. - The `h3` and `h3_postgis` update files that ended in `--unreleased.sql` have been renamed to end in `--X.Y.Z.sql`, and their CMake references were renamed with them. @@ -60,6 +68,6 @@ This command also validates that all extension GUCs are documented in `h3/src/gu - Run `scripts/postrelease`. The script restores `INSTALL_VERSION` to `unreleased`, creates the next empty `h3--X.Y.Z--unreleased.sql` and `h3_postgis--X.Y.Z--unreleased.sql` files, adds them to the extension CMake - files, restores the upgrade regression target to `unreleased`, and runs the - release metadata checks. + files, keeps the upgrade regression target pointed at the default + extension version, and runs the release metadata checks. - Review, commit, push, and merge the post-release development branch. diff --git a/h3/CMakeLists.txt b/h3/CMakeLists.txt index 4a325cdd..e0088bb9 100644 --- a/h3/CMakeLists.txt +++ b/h3/CMakeLists.txt @@ -2,7 +2,7 @@ PostgreSQL_add_extension(postgresql_h3 RELOCATABLE NAME h3 COMMENT "H3 bindings for PostgreSQL" - VERSION ${INSTALL_VERSION} + VERSION ${INSTALL_OUTPUT_VERSION} COMPONENT ${PROJECT_NAME} SOURCES src/binding/edge.c diff --git a/h3/src/config.h.in b/h3/src/config.h.in index 8a880437..9669e60f 100644 --- a/h3/src/config.h.in +++ b/h3/src/config.h.in @@ -17,6 +17,6 @@ #ifndef H3_CONFIG_H #define H3_CONFIG_H -#define POSTGRESQL_H3_VERSION "@INSTALL_VERSION@" +#define POSTGRESQL_H3_VERSION "@INSTALL_OUTPUT_VERSION@" #endif /* H3_CONFIG_H */ diff --git a/h3/test/CMakeLists.txt b/h3/test/CMakeLists.txt index 276bc665..c5949314 100644 --- a/h3/test/CMakeLists.txt +++ b/h3/test/CMakeLists.txt @@ -73,7 +73,7 @@ PostgreSQL_add_extupgrade_test( NAME h3_validate_extupgrade EXTNAME h3 FROM_VERSION 0.1.0 - TO_VERSION ${INSTALL_VERSION} + TO_VERSION ${INSTALL_OUTPUT_VERSION} TEMP_ROOT ${CMAKE_CURRENT_BINARY_DIR}/extupgrade-h3 TEMP_PORT 65441 DYNAMIC_LIBRARY_PATH ${H3_REGRESS_TEMP_CONFIG_DYNAMIC_LIBRARY_PATH} diff --git a/h3/test/expected/extension.out b/h3/test/expected/extension.out index d7fb76a3..20aea75c 100644 --- a/h3/test/expected/extension.out +++ b/h3/test/expected/extension.out @@ -2,7 +2,7 @@ -- -- TEST h3_get_extension_version -- -SELECT h3_get_extension_version() ~ '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' +SELECT h3_get_extension_version() ~ '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:dev|-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' OR h3_get_extension_version() = 'unreleased'; t @@ -97,7 +97,7 @@ SELECT hex, h3_distance_user_wrapper(hex) AS dist FROM h3_distance_expr_fail_userfn; -ALTER EXTENSION h3 UPDATE TO 'unreleased'; +ALTER EXTENSION h3 UPDATE; SELECT (current_setting('server_version_num')::int >= 140000) = EXISTS ( SELECT 1 FROM pg_amproc ap diff --git a/h3/test/sql/extension.sql b/h3/test/sql/extension.sql index e8266ea4..e1767f4b 100644 --- a/h3/test/sql/extension.sql +++ b/h3/test/sql/extension.sql @@ -4,7 +4,7 @@ -- TEST h3_get_extension_version -- -SELECT h3_get_extension_version() ~ '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' +SELECT h3_get_extension_version() ~ '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:dev|-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$' OR h3_get_extension_version() = 'unreleased'; -- @@ -114,7 +114,7 @@ SELECT h3_distance_user_wrapper(hex) AS dist FROM h3_distance_expr_fail_userfn; -ALTER EXTENSION h3 UPDATE TO 'unreleased'; +ALTER EXTENSION h3 UPDATE; SELECT (current_setting('server_version_num')::int >= 140000) = EXISTS ( SELECT 1 diff --git a/h3_postgis/CMakeLists.txt b/h3_postgis/CMakeLists.txt index 855ec635..695f6afb 100644 --- a/h3_postgis/CMakeLists.txt +++ b/h3_postgis/CMakeLists.txt @@ -2,7 +2,7 @@ PostgreSQL_add_extension(postgresql_h3_postgis RELOCATABLE NAME h3_postgis COMMENT "H3 PostGIS integration" - VERSION ${INSTALL_VERSION} + VERSION ${INSTALL_OUTPUT_VERSION} COMPONENT ${PROJECT_NAME} REQUIRES h3 diff --git a/h3_postgis/src/config.h.in b/h3_postgis/src/config.h.in index fb4bb002..9ab16de0 100644 --- a/h3_postgis/src/config.h.in +++ b/h3_postgis/src/config.h.in @@ -17,6 +17,6 @@ #ifndef PGH3_CONFIG_H #define PGH3_CONFIG_H -#define POSTGRESQL_PGH3_VERSION "@INSTALL_VERSION@" +#define POSTGRESQL_PGH3_VERSION "@INSTALL_OUTPUT_VERSION@" #endif /* PGH3_CONFIG_H */ diff --git a/h3_postgis/test/CMakeLists.txt b/h3_postgis/test/CMakeLists.txt index 1c7c473d..d87b8f38 100644 --- a/h3_postgis/test/CMakeLists.txt +++ b/h3_postgis/test/CMakeLists.txt @@ -90,7 +90,7 @@ PostgreSQL_add_extupgrade_test( NAME h3_postgis_validate_extupgrade EXTNAME h3_postgis FROM_VERSION 4.0.0 - TO_VERSION ${INSTALL_VERSION} + TO_VERSION ${INSTALL_OUTPUT_VERSION} TEMP_ROOT ${CMAKE_CURRENT_BINARY_DIR}/extupgrade-h3_postgis TEMP_PORT 65442 DYNAMIC_LIBRARY_PATH ${H3_POSTGIS_REGRESS_TEMP_CONFIG_DYNAMIC_LIBRARY_PATH} diff --git a/scripts/postrelease b/scripts/postrelease index 1cd4a8ff..f6d0014d 100755 --- a/scripts/postrelease +++ b/scripts/postrelease @@ -87,11 +87,9 @@ main() { make_next_update h3 h3/sql/updates h3/CMakeLists.txt "$version" make_next_update h3_postgis h3_postgis/sql/updates h3_postgis/CMakeLists.txt "$version" - sed -i "s/ALTER EXTENSION h3 UPDATE TO '${version}'/ALTER EXTENSION h3 UPDATE TO 'unreleased'/g" \ - h3/test/sql/extension.sql h3/test/expected/extension.out for test_file in h3/test/sql/extension.sql h3/test/expected/extension.out; do - grep -q "ALTER EXTENSION h3 UPDATE TO 'unreleased'" "$test_file" || - die "${test_file} extension regression target was not restored to unreleased" + grep -q "ALTER EXTENSION h3 UPDATE;" "$test_file" || + die "${test_file} extension regression target does not update to the default version" done verify_update_references diff --git a/scripts/release b/scripts/release index 62271b05..9316d798 100755 --- a/scripts/release +++ b/scripts/release @@ -165,7 +165,7 @@ verify_release_state() { die "unreleased update files remain after release" fi - if grep -R -n -E 'availability: unreleased|Since vunreleased|UPDATE TO '\''unreleased'\''|--unreleased\.sql' \ + if grep -R -n -E 'availability: unreleased|Since vunreleased|--unreleased\.sql' \ h3 h3_postgis docs/api.md CMakeLists.txt; then die "unreleased release markers remain" fi @@ -211,9 +211,6 @@ main() { release_update_file h3 h3/sql/updates h3/CMakeLists.txt "$version" release_update_file h3_postgis h3_postgis/sql/updates h3_postgis/CMakeLists.txt "$version" - sed -i "s/ALTER EXTENSION h3 UPDATE TO 'unreleased'/ALTER EXTENSION h3 UPDATE TO '${version}'/g" \ - h3/test/sql/extension.sql h3/test/expected/extension.out - sed -i -E "s/^version: v[0-9]+\.[0-9]+\.[0-9]+/version: v${version}/" CITATION.cff sed -i -E "s/^date-released: [0-9]{4}-[0-9]{2}-[0-9]{2}/date-released: ${release_date}/" CITATION.cff From 99a9a3c0ae64e17755dfec96d4eb41d7690b3b9b Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Tue, 23 Jun 2026 01:39:08 +0400 Subject: [PATCH 2/5] fix: narrow dev update version substitution --- cmake/AddPostgreSQLExtension.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/AddPostgreSQLExtension.cmake b/cmake/AddPostgreSQLExtension.cmake index 582ae6bf..96b7f2a4 100644 --- a/cmake/AddPostgreSQLExtension.cmake +++ b/cmake/AddPostgreSQLExtension.cmake @@ -277,7 +277,7 @@ function(PostgreSQL_add_extension LIBRARY_NAME) file(READ "${file}" UPDATE_CONTENTS) if(UPDATE_OUTPUT_NAME MATCHES "--unreleased\\.sql$" AND NOT EXTENSION_VERSION STREQUAL "unreleased") string(REGEX REPLACE "--unreleased\\.sql$" "--${EXTENSION_VERSION}.sql" UPDATE_OUTPUT_NAME "${UPDATE_OUTPUT_NAME}") - string(REPLACE "unreleased" "${EXTENSION_VERSION}" UPDATE_CONTENTS "${UPDATE_CONTENTS}") + string(REGEX REPLACE "'unreleased'" "'${EXTENSION_VERSION}'" UPDATE_CONTENTS "${UPDATE_CONTENTS}") endif() set(UPDATE_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_OUTPUT_NAME}") if(PostgreSQL_VERSION_MAJOR VERSION_LESS "16") From 08e1b14d149fe1645f748e140f8b7f6a42128e89 Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Tue, 23 Jun 2026 02:38:35 +0400 Subject: [PATCH 3/5] fix: preserve dev upgrade aliases --- cmake/AddPostgreSQLExtension.cmake | 97 ++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/cmake/AddPostgreSQLExtension.cmake b/cmake/AddPostgreSQLExtension.cmake index 96b7f2a4..62697e3e 100644 --- a/cmake/AddPostgreSQLExtension.cmake +++ b/cmake/AddPostgreSQLExtension.cmake @@ -271,14 +271,103 @@ function(PostgreSQL_add_extension LIBRARY_NAME) # Apply the same compatibility preprocessing to update scripts. set(EXTENSION_UPDATES_PROCESSED "") + set(EXTENSION_UNRELEASED_TRANSITION_EMITTED FALSE) + set(EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED FALSE) + set(EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED FALSE) foreach(file ${EXTENSION_UPDATES}) get_filename_component(UPDATE_NAME "${file}" NAME) set(UPDATE_OUTPUT_NAME "${UPDATE_NAME}") + set(UPDATE_TRANSITION_NAMES "") + set(UPDATE_TRANSITION_OUTPUTS "") + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${file}") file(READ "${file}" UPDATE_CONTENTS) if(UPDATE_OUTPUT_NAME MATCHES "--unreleased\\.sql$" AND NOT EXTENSION_VERSION STREQUAL "unreleased") string(REGEX REPLACE "--unreleased\\.sql$" "--${EXTENSION_VERSION}.sql" UPDATE_OUTPUT_NAME "${UPDATE_OUTPUT_NAME}") string(REGEX REPLACE "'unreleased'" "'${EXTENSION_VERSION}'" UPDATE_CONTENTS "${UPDATE_CONTENTS}") endif() + + if(NOT EXTENSION_VERSION STREQUAL "unreleased" AND NOT EXTENSION_UNRELEASED_TRANSITION_EMITTED) + set(UPDATE_TARGET_SUFFIX "--${EXTENSION_VERSION}.sql") + string(LENGTH "${UPDATE_OUTPUT_NAME}" UPDATE_OUTPUT_NAME_LENGTH) + string(LENGTH "${UPDATE_TARGET_SUFFIX}" UPDATE_TARGET_SUFFIX_LENGTH) + if(UPDATE_OUTPUT_NAME_LENGTH GREATER_EQUAL UPDATE_TARGET_SUFFIX_LENGTH) + math(EXPR UPDATE_TARGET_SUFFIX_START "${UPDATE_OUTPUT_NAME_LENGTH} - ${UPDATE_TARGET_SUFFIX_LENGTH}") + string(SUBSTRING "${UPDATE_OUTPUT_NAME}" ${UPDATE_TARGET_SUFFIX_START} ${UPDATE_TARGET_SUFFIX_LENGTH} UPDATE_OUTPUT_SUFFIX) + if(UPDATE_OUTPUT_SUFFIX STREQUAL "${UPDATE_TARGET_SUFFIX}") + # Let old local development installs marked as "unreleased" move to + # the generated development version, and later to the real release. + set(EXTENSION_UNRELEASED_TRANSITION_EMITTED TRUE) + set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--unreleased--${EXTENSION_VERSION}.sql") + set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") + set(UPDATE_TRANSITION_CONTENT [=[ +-- Generated transition from @SOURCE_VERSION@ development installs. +\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit +]=]) + string(REPLACE "@SOURCE_VERSION@" "unreleased" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") + list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") + list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") + endif() + endif() + endif() + + if(DEFINED PROJECT_VERSION AND EXTENSION_VERSION STREQUAL PROJECT_VERSION + AND (NOT EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED OR NOT EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED)) + set(UPDATE_TARGET_SUFFIX "--${EXTENSION_VERSION}.sql") + string(LENGTH "${UPDATE_OUTPUT_NAME}" UPDATE_OUTPUT_NAME_LENGTH) + string(LENGTH "${UPDATE_TARGET_SUFFIX}" UPDATE_TARGET_SUFFIX_LENGTH) + if(UPDATE_OUTPUT_NAME_LENGTH GREATER_EQUAL UPDATE_TARGET_SUFFIX_LENGTH) + math(EXPR UPDATE_TARGET_SUFFIX_START "${UPDATE_OUTPUT_NAME_LENGTH} - ${UPDATE_TARGET_SUFFIX_LENGTH}") + string(SUBSTRING "${UPDATE_OUTPUT_NAME}" ${UPDATE_TARGET_SUFFIX_START} ${UPDATE_TARGET_SUFFIX_LENGTH} UPDATE_OUTPUT_SUFFIX) + if(UPDATE_OUTPUT_SUFFIX STREQUAL "${UPDATE_TARGET_SUFFIX}") + if(NOT EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED) + set(EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED TRUE) + set(UPDATE_DEV_VERSION "${PROJECT_VERSION}dev") + set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--${UPDATE_DEV_VERSION}--${EXTENSION_VERSION}.sql") + set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") + set(UPDATE_TRANSITION_CONTENT [=[ +-- Generated transition from @SOURCE_VERSION@ development installs. +\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit +]=]) + string(REPLACE "@SOURCE_VERSION@" "${UPDATE_DEV_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") + list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") + list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") + endif() + + string(SUBSTRING "${UPDATE_OUTPUT_NAME}" 0 ${UPDATE_TARGET_SUFFIX_START} UPDATE_SOURCE_PREFIX) + set(UPDATE_NAME_PREFIX "${EXTENSION_NAME}--") + string(LENGTH "${UPDATE_NAME_PREFIX}" UPDATE_NAME_PREFIX_LENGTH) + string(LENGTH "${UPDATE_SOURCE_PREFIX}" UPDATE_SOURCE_PREFIX_LENGTH) + if(UPDATE_SOURCE_PREFIX_LENGTH GREATER UPDATE_NAME_PREFIX_LENGTH) + string(SUBSTRING "${UPDATE_SOURCE_PREFIX}" 0 ${UPDATE_NAME_PREFIX_LENGTH} UPDATE_SOURCE_NAME_PREFIX) + string(SUBSTRING "${UPDATE_SOURCE_PREFIX}" ${UPDATE_NAME_PREFIX_LENGTH} -1 UPDATE_SOURCE_VERSION) + if(UPDATE_SOURCE_NAME_PREFIX STREQUAL "${UPDATE_NAME_PREFIX}" AND NOT UPDATE_SOURCE_VERSION STREQUAL "unreleased") + set(UPDATE_SOURCE_DEV_VERSION "${UPDATE_SOURCE_VERSION}dev") + if(NOT UPDATE_SOURCE_DEV_VERSION STREQUAL "${PROJECT_VERSION}dev" AND NOT EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED) + set(EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED TRUE) + set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--${UPDATE_SOURCE_DEV_VERSION}--${EXTENSION_VERSION}.sql") + set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") + set(UPDATE_TRANSITION_CONTENT [=[ +-- Generated transition from @SOURCE_VERSION@ development installs. +\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit +]=]) + string(REPLACE "@SOURCE_VERSION@" "${UPDATE_SOURCE_DEV_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") + list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") + list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") + endif() + endif() + endif() + endif() + endif() + endif() set(UPDATE_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_OUTPUT_NAME}") if(PostgreSQL_VERSION_MAJOR VERSION_LESS "16") string(REPLACE "@extschema:${EXTENSION_NAME}@." "" UPDATE_CONTENTS "${UPDATE_CONTENTS}") @@ -293,6 +382,14 @@ function(PostgreSQL_add_extension LIBRARY_NAME) COPYONLY ) list(APPEND EXTENSION_UPDATES_PROCESSED "${UPDATE_OUTPUT}") + foreach(UPDATE_TRANSITION_NAME UPDATE_TRANSITION_OUTPUT IN ZIP_LISTS UPDATE_TRANSITION_NAMES UPDATE_TRANSITION_OUTPUTS) + configure_file( + "${UPDATE_TRANSITION_OUTPUT}" + "${EXTENSION_BUILD_EXTENSION_DIR}/${UPDATE_TRANSITION_NAME}" + COPYONLY + ) + list(APPEND EXTENSION_UPDATES_PROCESSED "${UPDATE_TRANSITION_OUTPUT}") + endforeach() endforeach() # Install everything else into share-dir From f385531aaf347a34e0301892b4e9151a8d02c2cd Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Tue, 23 Jun 2026 02:51:24 +0400 Subject: [PATCH 4/5] fix: narrow release update version replacement --- scripts/release | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/release b/scripts/release index 9316d798..ca963316 100755 --- a/scripts/release +++ b/scripts/release @@ -72,7 +72,8 @@ release_update_file() { [[ ! -e "$new_file" ]] || die "${new_file} already exists" git mv "$old_file" "$new_file" - sed -i "s/unreleased/${version}/g" "$new_file" + sed -i "s/UPDATE TO 'unreleased'/UPDATE TO '${version}'/g" "$new_file" + sed -i "s/availability: unreleased/availability: ${version}/g" "$new_file" sed -i -E 's/[[:space:]]+$//' "$new_file" grep -qF "$old_name" "$cmake_file" || die "${cmake_file} does not reference ${old_name}" OLD_NAME="$old_name" NEW_NAME="$new_name" \ From b901788dc26f939ede96d519cb37ba90b9017a2d Mon Sep 17 00:00:00 2001 From: Darafei Praliaskouski Date: Tue, 23 Jun 2026 03:28:18 +0400 Subject: [PATCH 5/5] fix: narrow generated update marker rewrites --- cmake/AddPostgreSQLExtension.cmake | 106 +++++++++-------------------- scripts/release | 2 +- 2 files changed, 34 insertions(+), 74 deletions(-) diff --git a/cmake/AddPostgreSQLExtension.cmake b/cmake/AddPostgreSQLExtension.cmake index 62697e3e..eedc852e 100644 --- a/cmake/AddPostgreSQLExtension.cmake +++ b/cmake/AddPostgreSQLExtension.cmake @@ -167,6 +167,21 @@ function(PostgreSQL_add_extension_bitcode LIBRARY_NAME EXTENSION_NAME EXTENSION_ ) endfunction() +macro(PostgreSQL_append_update_transition SOURCE_VERSION) + set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--${SOURCE_VERSION}--${EXTENSION_VERSION}.sql") + set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") + set(UPDATE_TRANSITION_CONTENT [=[ +-- Generated transition from @SOURCE_VERSION@ development installs. +\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit +]=]) + string(REPLACE "@SOURCE_VERSION@" "${SOURCE_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") + file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") + list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") + list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") +endmacro() + # Helper command to add extensions function(PostgreSQL_add_extension LIBRARY_NAME) set(options RELOCATABLE) @@ -283,87 +298,32 @@ function(PostgreSQL_add_extension LIBRARY_NAME) file(READ "${file}" UPDATE_CONTENTS) if(UPDATE_OUTPUT_NAME MATCHES "--unreleased\\.sql$" AND NOT EXTENSION_VERSION STREQUAL "unreleased") string(REGEX REPLACE "--unreleased\\.sql$" "--${EXTENSION_VERSION}.sql" UPDATE_OUTPUT_NAME "${UPDATE_OUTPUT_NAME}") - string(REGEX REPLACE "'unreleased'" "'${EXTENSION_VERSION}'" UPDATE_CONTENTS "${UPDATE_CONTENTS}") + string(REPLACE "UPDATE TO 'unreleased'" "UPDATE TO '${EXTENSION_VERSION}'" UPDATE_CONTENTS "${UPDATE_CONTENTS}") + string(REPLACE "availability: unreleased" "availability: ${EXTENSION_VERSION}" UPDATE_CONTENTS "${UPDATE_CONTENTS}") endif() if(NOT EXTENSION_VERSION STREQUAL "unreleased" AND NOT EXTENSION_UNRELEASED_TRANSITION_EMITTED) - set(UPDATE_TARGET_SUFFIX "--${EXTENSION_VERSION}.sql") - string(LENGTH "${UPDATE_OUTPUT_NAME}" UPDATE_OUTPUT_NAME_LENGTH) - string(LENGTH "${UPDATE_TARGET_SUFFIX}" UPDATE_TARGET_SUFFIX_LENGTH) - if(UPDATE_OUTPUT_NAME_LENGTH GREATER_EQUAL UPDATE_TARGET_SUFFIX_LENGTH) - math(EXPR UPDATE_TARGET_SUFFIX_START "${UPDATE_OUTPUT_NAME_LENGTH} - ${UPDATE_TARGET_SUFFIX_LENGTH}") - string(SUBSTRING "${UPDATE_OUTPUT_NAME}" ${UPDATE_TARGET_SUFFIX_START} ${UPDATE_TARGET_SUFFIX_LENGTH} UPDATE_OUTPUT_SUFFIX) - if(UPDATE_OUTPUT_SUFFIX STREQUAL "${UPDATE_TARGET_SUFFIX}") - # Let old local development installs marked as "unreleased" move to - # the generated development version, and later to the real release. - set(EXTENSION_UNRELEASED_TRANSITION_EMITTED TRUE) - set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--unreleased--${EXTENSION_VERSION}.sql") - set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") - set(UPDATE_TRANSITION_CONTENT [=[ --- Generated transition from @SOURCE_VERSION@ development installs. -\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit -]=]) - string(REPLACE "@SOURCE_VERSION@" "unreleased" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") - list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") - list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") - endif() + if(UPDATE_OUTPUT_NAME MATCHES "--${EXTENSION_VERSION}\\.sql$") + # Let old local development installs marked as "unreleased" move to + # the generated development version, and later to the real release. + set(EXTENSION_UNRELEASED_TRANSITION_EMITTED TRUE) + PostgreSQL_append_update_transition("unreleased") endif() endif() if(DEFINED PROJECT_VERSION AND EXTENSION_VERSION STREQUAL PROJECT_VERSION AND (NOT EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED OR NOT EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED)) - set(UPDATE_TARGET_SUFFIX "--${EXTENSION_VERSION}.sql") - string(LENGTH "${UPDATE_OUTPUT_NAME}" UPDATE_OUTPUT_NAME_LENGTH) - string(LENGTH "${UPDATE_TARGET_SUFFIX}" UPDATE_TARGET_SUFFIX_LENGTH) - if(UPDATE_OUTPUT_NAME_LENGTH GREATER_EQUAL UPDATE_TARGET_SUFFIX_LENGTH) - math(EXPR UPDATE_TARGET_SUFFIX_START "${UPDATE_OUTPUT_NAME_LENGTH} - ${UPDATE_TARGET_SUFFIX_LENGTH}") - string(SUBSTRING "${UPDATE_OUTPUT_NAME}" ${UPDATE_TARGET_SUFFIX_START} ${UPDATE_TARGET_SUFFIX_LENGTH} UPDATE_OUTPUT_SUFFIX) - if(UPDATE_OUTPUT_SUFFIX STREQUAL "${UPDATE_TARGET_SUFFIX}") - if(NOT EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED) - set(EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED TRUE) - set(UPDATE_DEV_VERSION "${PROJECT_VERSION}dev") - set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--${UPDATE_DEV_VERSION}--${EXTENSION_VERSION}.sql") - set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") - set(UPDATE_TRANSITION_CONTENT [=[ --- Generated transition from @SOURCE_VERSION@ development installs. -\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit -]=]) - string(REPLACE "@SOURCE_VERSION@" "${UPDATE_DEV_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") - list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") - list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") - endif() - - string(SUBSTRING "${UPDATE_OUTPUT_NAME}" 0 ${UPDATE_TARGET_SUFFIX_START} UPDATE_SOURCE_PREFIX) - set(UPDATE_NAME_PREFIX "${EXTENSION_NAME}--") - string(LENGTH "${UPDATE_NAME_PREFIX}" UPDATE_NAME_PREFIX_LENGTH) - string(LENGTH "${UPDATE_SOURCE_PREFIX}" UPDATE_SOURCE_PREFIX_LENGTH) - if(UPDATE_SOURCE_PREFIX_LENGTH GREATER UPDATE_NAME_PREFIX_LENGTH) - string(SUBSTRING "${UPDATE_SOURCE_PREFIX}" 0 ${UPDATE_NAME_PREFIX_LENGTH} UPDATE_SOURCE_NAME_PREFIX) - string(SUBSTRING "${UPDATE_SOURCE_PREFIX}" ${UPDATE_NAME_PREFIX_LENGTH} -1 UPDATE_SOURCE_VERSION) - if(UPDATE_SOURCE_NAME_PREFIX STREQUAL "${UPDATE_NAME_PREFIX}" AND NOT UPDATE_SOURCE_VERSION STREQUAL "unreleased") - set(UPDATE_SOURCE_DEV_VERSION "${UPDATE_SOURCE_VERSION}dev") - if(NOT UPDATE_SOURCE_DEV_VERSION STREQUAL "${PROJECT_VERSION}dev" AND NOT EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED) - set(EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED TRUE) - set(UPDATE_TRANSITION_NAME "${EXTENSION_NAME}--${UPDATE_SOURCE_DEV_VERSION}--${EXTENSION_VERSION}.sql") - set(UPDATE_TRANSITION_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_TRANSITION_NAME}") - set(UPDATE_TRANSITION_CONTENT [=[ --- Generated transition from @SOURCE_VERSION@ development installs. -\echo Use "ALTER EXTENSION @EXTENSION_NAME@ UPDATE TO '@EXTENSION_VERSION@'" to load this file. \quit -]=]) - string(REPLACE "@SOURCE_VERSION@" "${UPDATE_SOURCE_DEV_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_NAME@" "${EXTENSION_NAME}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - string(REPLACE "@EXTENSION_VERSION@" "${EXTENSION_VERSION}" UPDATE_TRANSITION_CONTENT "${UPDATE_TRANSITION_CONTENT}") - file(WRITE "${UPDATE_TRANSITION_OUTPUT}" "${UPDATE_TRANSITION_CONTENT}") - list(APPEND UPDATE_TRANSITION_NAMES "${UPDATE_TRANSITION_NAME}") - list(APPEND UPDATE_TRANSITION_OUTPUTS "${UPDATE_TRANSITION_OUTPUT}") - endif() - endif() + if(UPDATE_OUTPUT_NAME MATCHES "^${EXTENSION_NAME}--(.+)--${EXTENSION_VERSION}\\.sql$") + set(UPDATE_SOURCE_VERSION "${CMAKE_MATCH_1}") + if(NOT EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED) + set(EXTENSION_PROJECT_DEV_RELEASE_TRANSITION_EMITTED TRUE) + PostgreSQL_append_update_transition("${PROJECT_VERSION}dev") + endif() + if(NOT UPDATE_SOURCE_VERSION STREQUAL "unreleased") + set(UPDATE_SOURCE_DEV_VERSION "${UPDATE_SOURCE_VERSION}dev") + if(NOT UPDATE_SOURCE_DEV_VERSION STREQUAL "${PROJECT_VERSION}dev" AND NOT EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED) + set(EXTENSION_SOURCE_DEV_RELEASE_TRANSITION_EMITTED TRUE) + PostgreSQL_append_update_transition("${UPDATE_SOURCE_DEV_VERSION}") endif() endif() endif() diff --git a/scripts/release b/scripts/release index ca963316..e1dcb77f 100755 --- a/scripts/release +++ b/scripts/release @@ -166,7 +166,7 @@ verify_release_state() { die "unreleased update files remain after release" fi - if grep -R -n -E 'availability: unreleased|Since vunreleased|--unreleased\.sql' \ + if grep -R -n -E 'availability: unreleased|Since vunreleased|UPDATE TO '\''unreleased'\''|--unreleased\.sql' \ h3 h3_postgis docs/api.md CMakeLists.txt; then die "unreleased release markers remain" fi