diff --git a/scripts/release/package_versions.sh b/scripts/release/package_versions.sh index 2852a04bb..e265cfbef 100755 --- a/scripts/release/package_versions.sh +++ b/scripts/release/package_versions.sh @@ -37,6 +37,14 @@ esac semver_core='(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)' prerelease_id='(alpha|beta|rc)\.(0|[1-9][0-9]*)' +# Every SemVer pre-release separator becomes '~' in both package formats. +# dpkg and rpm (>= 4.10) both treat '~' as "sorts before anything, even the +# empty string", so 1.0.0~rc.5 < 1.0.0 and 1.0.0~rc.5~preview.2 < 1.0.0~rc.5. +# Neither '_' (an ordinary rpm segment separator, which makes 1.0.0_rc.5 sort +# above 1.0.0) nor a second '-' (which dpkg reads as the start of the Debian +# revision, so 1.0.0~rc.5-preview.2 sorts above 1.0.0~rc.5) preserves the +# SemVer ordering. GitHub stores '~' in asset names as '.'; package.yml +# accounts for that when it writes the release checksums. tilde='~' case "$build_type" in @@ -65,8 +73,8 @@ case "$build_type" in [[ "$source_version" =~ ^${semver_core}-${prerelease_id}$ ]] || fail "prerelease version must be strict alpha, beta, or rc SemVer" - deb_version=${source_version/-/$tilde} - rpm_version=${source_version//-/_} + deb_version=${source_version//-/$tilde} + rpm_version=${source_version//-/$tilde} rpm_release=1 ;; preview) @@ -74,8 +82,8 @@ case "$build_type" in [[ "$source_version" =~ ^${semver_core}-${prerelease_id}-preview\.(0|[1-9][0-9]*)$ ]] || fail "preview version must be strict prerelease-preview SemVer" - deb_version=${source_version/-/$tilde} - rpm_version=${source_version//-/_} + deb_version=${source_version//-/$tilde} + rpm_version=${source_version//-/$tilde} rpm_release=1 ;; *) fail "unsupported build type" ;; diff --git a/scripts/test_package_versions.sh b/scripts/test_package_versions.sh index ec44dd2fe..a847de815 100755 --- a/scripts/test_package_versions.sh +++ b/scripts/test_package_versions.sh @@ -74,16 +74,16 @@ run_success stable-amd64 \ $'deb_version=1.2.3\nrpm_version=1.2.3\nrpm_release=1\ndeb_file=rustfs_1.2.3_amd64.deb\nrpm_file=rustfs-1.2.3-1.x86_64.rpm' \ release 1.2.3 '' amd64 x86_64 run_success alpha-arm64 \ - $'deb_version=1.2.3~alpha.1\nrpm_version=1.2.3_alpha.1\nrpm_release=1\ndeb_file=rustfs_1.2.3~alpha.1_arm64.deb\nrpm_file=rustfs-1.2.3_alpha.1-1.aarch64.rpm' \ + $'deb_version=1.2.3~alpha.1\nrpm_version=1.2.3~alpha.1\nrpm_release=1\ndeb_file=rustfs_1.2.3~alpha.1_arm64.deb\nrpm_file=rustfs-1.2.3~alpha.1-1.aarch64.rpm' \ prerelease 1.2.3-alpha.1 '' arm64 aarch64 run_success beta-amd64 \ - $'deb_version=1.2.3~beta.2\nrpm_version=1.2.3_beta.2\nrpm_release=1\ndeb_file=rustfs_1.2.3~beta.2_amd64.deb\nrpm_file=rustfs-1.2.3_beta.2-1.x86_64.rpm' \ + $'deb_version=1.2.3~beta.2\nrpm_version=1.2.3~beta.2\nrpm_release=1\ndeb_file=rustfs_1.2.3~beta.2_amd64.deb\nrpm_file=rustfs-1.2.3~beta.2-1.x86_64.rpm' \ prerelease 1.2.3-beta.2 '' amd64 x86_64 run_success rc-amd64 \ - $'deb_version=1.2.3~rc.4\nrpm_version=1.2.3_rc.4\nrpm_release=1\ndeb_file=rustfs_1.2.3~rc.4_amd64.deb\nrpm_file=rustfs-1.2.3_rc.4-1.x86_64.rpm' \ + $'deb_version=1.2.3~rc.4\nrpm_version=1.2.3~rc.4\nrpm_release=1\ndeb_file=rustfs_1.2.3~rc.4_amd64.deb\nrpm_file=rustfs-1.2.3~rc.4-1.x86_64.rpm' \ prerelease 1.2.3-rc.4 '' amd64 x86_64 run_success preview-amd64 \ - $'deb_version=1.0.0~rc.5-preview.2\nrpm_version=1.0.0_rc.5_preview.2\nrpm_release=1\ndeb_file=rustfs_1.0.0~rc.5-preview.2_amd64.deb\nrpm_file=rustfs-1.0.0_rc.5_preview.2-1.x86_64.rpm' \ + $'deb_version=1.0.0~rc.5~preview.2\nrpm_version=1.0.0~rc.5~preview.2\nrpm_release=1\ndeb_file=rustfs_1.0.0~rc.5~preview.2_amd64.deb\nrpm_file=rustfs-1.0.0~rc.5~preview.2-1.x86_64.rpm' \ preview 1.0.0-rc.5-preview.2 '' amd64 x86_64 run_success development-amd64 \ "deb_version=0~dev.7463.${sha} @@ -126,23 +126,43 @@ run_failure newline release $'1.2.3\nforged=1' '' amd64 x86_64 run_failure unsupported-deb-arch release 1.2.3 '' x86_64 x86_64 run_failure mismatched-arch release 1.2.3 '' amd64 aarch64 +# Ordering contract shared by both package managers: every pre-release sorts +# below its final release, every preview sorts below the pre-release it +# previews, and pre-release kinds/numbers keep their SemVer order. if command -v dpkg >/dev/null 2>&1; then dpkg --compare-versions "0~dev.7462.${sha}" lt "0~dev.7463.${sha}" dpkg --compare-versions "0~dev.7463.${sha}" lt 0.1.0 dpkg --compare-versions 1.2.3~rc.4 lt 1.2.3 - passed=$((passed + 3)) + dpkg --compare-versions 1.2.3~alpha.1 lt 1.2.3~beta.2 + dpkg --compare-versions 1.2.3~beta.2 lt 1.2.3~rc.4 + dpkg --compare-versions 1.2.3~rc.9 lt 1.2.3~rc.10 + dpkg --compare-versions 1.0.0~rc.5~preview.2 lt 1.0.0~rc.5 + dpkg --compare-versions 1.0.0~rc.5~preview.1 lt 1.0.0~rc.5~preview.2 + dpkg --compare-versions 1.0.0~rc.5~preview.2 lt 1.0.0~rc.6 + dpkg --compare-versions 1.0.0~rc.5 lt 1.0.1 + passed=$((passed + 10)) elif [[ $require_package_managers == true ]]; then printf 'FAIL package ordering: dpkg is required\n' >&2 exit 1 fi if command -v rpm >/dev/null 2>&1; then - rpm_old="0-0.dev.7462.${sha}" - rpm_new="0-0.dev.7463.${sha}" - rpm_release=0.1.0-1 - [[ $(rpm --eval "%{lua: print(rpm.vercmp('${rpm_old}', '${rpm_new}'))}") == -1 ]] - [[ $(rpm --eval "%{lua: print(rpm.vercmp('${rpm_new}', '${rpm_release}'))}") == -1 ]] - passed=$((passed + 2)) + rpm_lt() { + [[ $(rpm --eval "%{lua: print(rpm.vercmp('$1', '$2'))}") == -1 ]] || + { printf 'FAIL rpm ordering: expected %s < %s\n' "$1" "$2" >&2; exit 1; } + passed=$((passed + 1)) + } + rpm_lt "0-0.dev.7462.${sha}" "0-0.dev.7463.${sha}" + rpm_lt "0-0.dev.7463.${sha}" 0.1.0-1 + # The former 1.2.3_rc.4 spelling compared as newer than 1.2.3 (issue #8012). + rpm_lt 1.2.3~rc.4-1 1.2.3-1 + rpm_lt 1.2.3~alpha.1-1 1.2.3~beta.2-1 + rpm_lt 1.2.3~beta.2-1 1.2.3~rc.4-1 + rpm_lt 1.2.3~rc.9-1 1.2.3~rc.10-1 + rpm_lt 1.0.0~rc.5~preview.2-1 1.0.0~rc.5-1 + rpm_lt 1.0.0~rc.5~preview.1-1 1.0.0~rc.5~preview.2-1 + rpm_lt 1.0.0~rc.5~preview.2-1 1.0.0~rc.6-1 + rpm_lt 1.0.0~rc.5-1 1.0.1-1 elif [[ $require_package_managers == true ]]; then printf 'FAIL package ordering: rpm is required\n' >&2 exit 1