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..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) @@ -271,25 +286,70 @@ 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 "${CMAKE_CURRENT_BINARY_DIR}/${UPDATE_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(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) + 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)) + 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() + 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}") + 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 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..e1dcb77f 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" \ @@ -211,9 +212,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