mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-21 01:53:30 +00:00
fix(release): sort pre-release packages below their final release (#8016)
Pre-release RPM versions replaced the SemVer `-` with `_`, which rpm treats as an ordinary segment separator, so `1.0.0_rc.5` compared as newer than `1.0.0` and a host with an rc RPM installed could not `dnf upgrade` to the GA package. DEB previews had the mirror-image problem: only the first `-` became `~`, so `1.0.0~rc.5-preview.2` carried `preview.2` as its Debian revision and sorted above `1.0.0~rc.5`. Both formats now spell every pre-release separator as `~`, which dpkg and rpm (>= 4.10) both treat as "sorts before anything". Verified with rpm 4.16 (AlmaLinux 9) and dpkg 1.21: `1.0.0~rc.5 < 1.0.0`, `1.0.0~rc.5~preview.2 < 1.0.0~rc.5 < 1.0.0~rc.6`, alpha < beta < rc, and `rc.9 < rc.10`; fpm 1.18 passes `~` through into both package headers, and `dnf upgrade` from a `~rc.5` RPM to the GA RPM succeeds where the `_rc.5` one refused. The test now pins the full ordering contract under both package managers and fails against the previous spelling. The release-checksum step already normalizes `~` to `.` for every uploaded asset, so RPM assets need no further handling. Hosts that already installed an `_rc`/`_beta` RPM need a one-time `dnf install rustfs-1.0.0` or `rpm -Uvh --oldpackage` to reach GA. Fixes #8012
This commit is contained in:
@@ -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" ;;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user