Skip to content

Commit efa59d7

Browse files
authored
Merge pull request #701 from thaJeztah/simplify_package_versions
Fix package version generation
2 parents ab19b1c + f8299f2 commit efa59d7

File tree

4 files changed

+146
-83
lines changed

4 files changed

+146
-83
lines changed

deb/build-deb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,40 @@ debSource="$(awk -F ': ' '$1 == "Source" { print $2; exit }' debian/control)"
4343
debMaintainer="$(awk -F ': ' '$1 == "Maintainer" { print $2; exit }' debian/control)"
4444
debDate="$(date --rfc-2822)"
4545

46+
versionID="$(. /etc/os-release && echo "$VERSION_ID")"
47+
48+
# Include an extra `.0` in the version, in case we ever would have to re-build an
49+
# already published release with a packaging-only change.
50+
pkgRevision=0
51+
52+
# Generate changelog. The version/name of the generated packages are based on this.
53+
#
54+
# Resulting packages are formatted as;
55+
#
56+
# - name of the package (e.g., "docker-ce")
57+
# - version (e.g., "22.10.6~beta.0")
58+
# - "-0" (mostly "best practice", and allows updating for specific situations)
59+
# - distro (e.g., "ubuntu")
60+
# - VERSION_ID (e.g. "22.04" or "11") this must be "sortable" to make sure that
61+
# packages are upgraded when upgrading to a newer distro version ("codename"
62+
# cannot be used for this, as they're not sorted)
63+
# - pkgRevision (usually "0", see above)
64+
# - SUITE ("codename"), e.g. "jammy" or "bullseye". This is mostly for convenience,
65+
# because some places refer to distro versions by codename, others by version.
66+
# we prefix the codename with a tilde (~), which effectively excludes it from
67+
# version comparison.
68+
#
69+
# Note that while the `${EPOCH}${EPOCH_SEP}` is part of the version, it is not
70+
# included in the package's *filename*. (And if you're wondering: we needed the
71+
# EPOCH because of our use of CalVer, which made version comparing not work in
72+
# some cases).
73+
#
74+
# Examples:
75+
#
76+
# docker-ce_22.10.6~beta.0-0~debian.11.0~bullseye_amd64.deb
77+
# docker-ce_22.10.6~beta.0-0~ubuntu.22.04.0~jammy_amd64.deb
4678
cat > "debian/changelog" <<-EOF
47-
$debSource (${EPOCH}${EPOCH_SEP}${DEB_VERSION}-0~${DISTRO}-${SUITE}) $SUITE; urgency=low
79+
$debSource (${EPOCH}${EPOCH_SEP}${DEB_VERSION}-0~${DISTRO}.${versionID}.${pkgRevision}~${SUITE}) $SUITE; urgency=low
4880
* Version: $VERSION
4981
-- $debMaintainer $debDate
5082
EOF

deb/gen-deb-ver

Lines changed: 29 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -13,48 +13,26 @@ GIT_COMMAND="git -C $REPO_DIR"
1313
origVersion="$VERSION"
1414
debVersion="${VERSION#v}"
1515

16-
gen_deb_version() {
17-
# Adds an increment to the deb version to get proper order
18-
# 18.01.0-tp1 -> 18.01.0-0.1-tp1
19-
# 18.01.0-beta1 -> 18.01.0-1.1-beta1
20-
# 18.01.0-rc1 -> 18.01.0-2.1-rc1
21-
# 18.01.0 -> 18.01.0-3
22-
fullVersion="$1"
23-
pattern="$2"
24-
increment="$3"
25-
testVersion="${fullVersion#*-$pattern}"
26-
baseVersion="${fullVersion%-"$pattern"*}"
27-
echo "$baseVersion-$increment.${testVersion##.}.$pattern$testVersion"
28-
}
16+
# deb packages require a tilde (~) instead of a hyphen (-) as separator between
17+
# the version # and pre-release suffixes, otherwise pre-releases are sorted AFTER
18+
# non-pre-release versions, which would prevent users from updating from a pre-
19+
# release version to the "ga" version.
20+
#
21+
# For details, see this thread on the Debian mailing list:
22+
# https://lists.debian.org/debian-policy/1998/06/msg00099.html
23+
#
24+
# The code below replaces hyphens with tildes. Note that an intermediate $tilde
25+
# variable is needed to make this work on all versions of Bash. In some versions
26+
# of Bash, the tilde would be substituted with $HOME (even when escaped (\~) or
27+
# quoted ('~').
28+
tilde='~'
29+
debVersion="${debVersion//-/$tilde}"
2930

30-
case "$debVersion" in
31-
*-dev)
32-
;;
33-
*-tp[.0-9]*)
34-
debVersion="$(gen_deb_version "$debVersion" tp 0)"
35-
;;
36-
*-beta[.0-9]*)
37-
debVersion="$(gen_deb_version "$debVersion" beta 1)"
38-
;;
39-
*-rc[.0-9]*)
40-
debVersion="$(gen_deb_version "$debVersion" rc 2)"
41-
;;
42-
*)
43-
debVersion="$debVersion-3"
44-
;;
45-
esac
46-
47-
tilde='~' # ouch Bash 4.2 vs 4.3, you keel me
48-
debVersion="${debVersion//-/$tilde}" # using \~ or '~' here works in 4.3, but not 4.2; just ~ causes $HOME to be inserted, hence the $tilde
49-
# if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better
50-
if [[ "$VERSION" == *-dev ]]; then
31+
# if we have a "-dev" suffix or have change in Git, this is a nightly build, and
32+
# we'll create a pseudo version based on commit-date and -sha.
33+
if [[ "$VERSION" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ]; then
5134
export TZ=UTC
5235

53-
DATE_COMMAND="date"
54-
if [[ $(uname) == "Darwin" ]]; then
55-
DATE_COMMAND="docker run --rm alpine date"
56-
fi
57-
5836
# based on golang's pseudo-version: https://groups.google.com/forum/#!topic/golang-dev/a5PqQuBljF4
5937
#
6038
# using a "pseudo-version" of the form v0.0.0-yyyymmddhhmmss-abcdefabcdef,
@@ -65,11 +43,20 @@ if [[ "$VERSION" == *-dev ]]; then
6543
# as a pre-release before version v0.0.0, so that the go command prefers any
6644
# tagged release over any pseudo-version.
6745
gitUnix="$($GIT_COMMAND log -1 --pretty='%ct')"
68-
gitDate="$($DATE_COMMAND --utc --date "@$gitUnix" +'%Y%m%d%H%M%S')"
46+
47+
if [ "$(uname)" = "Darwin" ]; then
48+
# Using BSD date (macOS), which doesn't support the --date option
49+
# date -jf "<input format>" "<input value>" +"<output format>" (https://unix.stackexchange.com/a/86510)
50+
gitDate="$(TZ=UTC date -u -jf "%s" "$gitUnix" +'%Y%m%d%H%M%S')"
51+
else
52+
# Using GNU date (Linux)
53+
gitDate="$(TZ=UTC date -u --date "@$gitUnix" +'%Y%m%d%H%M%S')"
54+
fi
55+
6956
gitCommit="$($GIT_COMMAND log -1 --pretty='%h')"
7057
# generated version is now something like '0.0.0-20180719213702-cd5e2db'
71-
debVersion="0.0.0-${gitDate}-${gitCommit}"
72-
origVersion=$debVersion
58+
origVersion="0.0.0-${gitDate}-${gitCommit}" # (using hyphens)
59+
debVersion="0.0.0~${gitDate}.${gitCommit}" # (using tilde and periods)
7360

7461
# verify that nightly builds are always < actual releases
7562
#

rpm/gen-rpm-ver

Lines changed: 75 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -12,45 +12,77 @@ fi
1212
GIT_COMMAND="git -C $REPO_DIR"
1313
origVersion="$VERSION"
1414
rpmVersion="${VERSION#v}"
15-
rpmRelease=3
1615

17-
# rpmRelease versioning is as follows
18-
# Docker 18.01.0-ce: version=18.01.0.ce, release=3
19-
# Docker 18.01.0-ce-tp1: version=18.01.0.ce, release=0.1.tp1
20-
# Docker 18.01.0-ce-beta1: version=18.01.0.ce, release=1.1.beta1
21-
# Docker 18.01.0-ce-rc1: version=18.01.0.ce, release=2.1.rc1
22-
# Docker 18.01.0-ce-cs1: version=18.01.0.ce.cs1, release=1
23-
# Docker 18.01.0-ce-cs1-rc1: version=18.01.0.ce.cs1, release=0.1.rc1
24-
# Docker 18.01.0-ce-dev nightly: version=18.01.0.ce, release=0.0.YYYYMMDD.HHMMSS.gitHASH
16+
# rpm "Release:" field ($rpmRelease) is used to set the "_release" macro, which
17+
# is an incremental number for builds of the same release (Version: / #rpmVersion).
18+
#
19+
# This field can be:
20+
#
21+
# - Version: 0 : Package was built, but no matching upstream release (e.g., can be used for "nightly" builds)
22+
# - Version: 1 : Package was built for an upstream (pre)release version
23+
# - Version: > 1 : Only to be used for packaging-only changes (new package built for a version for which a package was already built/released)
24+
#
25+
# For details, see the Fedora packaging guide:
26+
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/#_complex_versioning_with_a_reasonable_upstream
27+
#
28+
# Note that older versions of the rpm spec allowed more traditional information
29+
# in this field, which is still allowed, but considered deprecated; see
30+
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/#_complex_versioning_with_a_reasonable_upstream
31+
#
32+
# In our case, this means that all releases, except for "nightly" builds should
33+
# use "Version: 1". Only in an exceptional case, where we need to publish a new
34+
# package (build) for an existing release, "Version: 2" should be used; this script
35+
# does not currently account for that situation.
36+
#
37+
# Assuming all tagged version of rpmRelease correspond with an upstream release,
38+
# this means that versioning is as follows:
39+
#
40+
# Docker 22.06.0: version=22.06.0, release=1
41+
# Docker 22.06.0-alpha.1: version=22.06.0, release=1
42+
# Docker 22.06.0-beta.1: version=22.06.0, release=1
43+
# Docker 22.06.0-rc.1: version=22.06.0, release=1
44+
# Docker 22.06.0-dev: version=0.0.0~YYYYMMDDHHMMSS.gitHASH, release=0
45+
rpmRelease=1
2546

26-
if [[ "$rpmVersion" =~ .*-tp[.0-9]+$ ]]; then
27-
testVersion=${rpmVersion#*-tp}
28-
rpmVersion=${rpmVersion%-tp*}
29-
rpmRelease="0.${testVersion##.}.tp${testVersion}"
30-
elif [[ "$rpmVersion" =~ .*-beta[.0-9]+$ ]]; then
31-
testVersion=${rpmVersion#*-beta}
32-
rpmVersion=${rpmVersion%-beta*}
33-
rpmRelease="1.${testVersion##.}.beta${testVersion}"
34-
elif [[ "$rpmVersion" =~ .*-rc[.0-9]+$ ]]; then
35-
testVersion=${rpmVersion#*-rc}
36-
rpmVersion=${rpmVersion%-rc*}
37-
rpmRelease="2.${testVersion##.}.rc${testVersion}"
38-
fi
47+
# rpm packages require a tilde (~) instead of a hyphen (-) as separator between
48+
# the version # and pre-release suffixes, otherwise pre-releases are sorted AFTER
49+
# non-pre-release versions, which would prevent users from updating from a pre-
50+
# release version to the "ga" version.
51+
#
52+
# For details, see the Fedora packaging guide:
53+
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Versioning/#_handling_non_sorting_versions_with_tilde_dot_and_caret
54+
#
55+
# > The tilde symbol (‘~’) is used before a version component which must sort
56+
# > earlier than any non-tilde component. It is used for any pre-release versions
57+
# > which wouldn’t otherwise sort appropriately.
58+
# >
59+
# > For example, with upstream releases 0.4.0, 0.4.1, 0.5.0-rc1, 0.5.0-rc2, 0.5.0,
60+
# > the two "release candidates" should use 0.5.0~rc1 and 0.5.0~rc2 in the Version:
61+
# > field. Bugfix or "patchlevel" releases that some upstream make should be handled
62+
# > using simple versioning. The separator used by upstream may need to be replaced
63+
# > by a dot or dropped.
64+
# >
65+
# > For example, if the same upstream released 0.5.0-post1 as a bugfix version,
66+
# > this "post-release" should use 0.5.0.post1 in the Version: field. Note that
67+
# > 0.5.0.post1 sorts lower than both 0.5.1 and 0.5.0.1.
68+
#
69+
# The code below replaces hyphens with tildes. Note that an intermediate $tilde
70+
# variable is needed to make this work on all versions of Bash. In some versions
71+
# of Bash, the tilde would be substituted with $HOME (even when escaped (\~) or
72+
# quoted ('~').
73+
tilde='~'
74+
rpmVersion="${rpmVersion//-/$tilde}"
3975

4076
DOCKER_GITCOMMIT=$($GIT_COMMAND rev-parse --short HEAD)
4177
if [ -n "$($GIT_COMMAND status --porcelain --untracked-files=no)" ]; then
4278
DOCKER_GITCOMMIT="$DOCKER_GITCOMMIT-unsupported"
4379
fi
4480

45-
# if we have a "-dev" suffix or have change in Git, let's make this package version more complex so it works better
46-
if [[ "$rpmVersion" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ]; then
81+
# if we have a "-dev" suffix or have change in Git, this is a nightly build, and
82+
# we'll create a pseudo version based on commit-date and -sha.
83+
if [[ "$VERSION" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ]; then
4784
export TZ=UTC
4885

49-
DATE_COMMAND="date"
50-
if [[ $(uname) == "Darwin" ]]; then
51-
DATE_COMMAND="docker run --rm alpine date"
52-
fi
53-
5486
# based on golang's pseudo-version: https://groups.google.com/forum/#!topic/golang-dev/a5PqQuBljF4
5587
#
5688
# using a "pseudo-version" of the form v0.0.0-yyyymmddhhmmss-abcdefabcdef,
@@ -61,14 +93,23 @@ if [[ "$rpmVersion" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ];
6193
# as a pre-release before version v0.0.0, so that the go command prefers any
6294
# tagged release over any pseudo-version.
6395
gitUnix="$($GIT_COMMAND log -1 --pretty='%ct')"
64-
gitDate="$($DATE_COMMAND --utc --date "@$gitUnix" +'%Y%m%d%H%M%S')"
96+
97+
if [ "$(uname)" = "Darwin" ]; then
98+
# Using BSD date (macOS), which doesn't support the --date option
99+
# date -jf "<input format>" "<input value>" +"<output format>" (https://unix.stackexchange.com/a/86510)
100+
gitDate="$(TZ=UTC date -u -jf "%s" "$gitUnix" +'%Y%m%d%H%M%S')"
101+
else
102+
# Using GNU date (Linux)
103+
gitDate="$(TZ=UTC date -u --date "@$gitUnix" +'%Y%m%d%H%M%S')"
104+
fi
105+
65106
gitCommit="$($GIT_COMMAND log -1 --pretty='%h')"
66107
# generated version is now something like '0.0.0-20180719213702-cd5e2db'
67-
rpmVersion="0.0.0-${gitDate}-${gitCommit}"
68-
rpmRelease="0"
69-
origVersion=$rpmVersion
108+
origVersion="0.0.0-${gitDate}-${gitCommit}" # (using hyphens)
109+
rpmVersion="0.0.0~${gitDate}.${gitCommit}" # (using tilde and periods)
110+
rpmRelease=0
70111
fi
71112

72-
# Replace any other dashes with periods
113+
# Replace any remaining dashes with periods
73114
rpmVersion="${rpmVersion//-/.}"
74115
echo "$rpmVersion $rpmRelease $DOCKER_GITCOMMIT $origVersion"

static/gen-static-ver

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@ fi
1111

1212
GIT_COMMAND="git -C $REPO_DIR"
1313

14-
staticVersion="$VERSION"
15-
if [[ "$VERSION" == *-dev ]]; then
14+
staticVersion="${VERSION#v}"
15+
16+
# if we have a "-dev" suffix or have change in Git, this is a nightly build, and
17+
# we'll create a pseudo version based on commit-date and -sha.
18+
if [[ "$VERSION" == *-dev ]] || [ -n "$($GIT_COMMAND status --porcelain)" ]; then
1619
export TZ=UTC
1720

1821
# based on golang's pseudo-version: https://groups.google.com/forum/#!topic/golang-dev/a5PqQuBljF4
@@ -27,17 +30,17 @@ if [[ "$VERSION" == *-dev ]]; then
2730
gitUnix="$($GIT_COMMAND log -1 --pretty='%ct')"
2831

2932
if [ "$(uname)" = "Darwin" ]; then
30-
# Using BSD date (macOS), which doesn't suppoort the --date option
33+
# Using BSD date (macOS), which doesn't support the --date option
3134
# date -jf "<input format>" "<input value>" +"<output format>" (https://unix.stackexchange.com/a/86510)
32-
gitDate="$(TZ=UTC date -jf "%s" "$gitUnix" +'%Y%m%d%H%M%S')"
35+
gitDate="$(TZ=UTC date -u -jf "%s" "$gitUnix" +'%Y%m%d%H%M%S')"
3336
else
3437
# Using GNU date (Linux)
35-
gitDate="$(TZ=UTC date --utc --date "@$gitUnix" +'%Y%m%d%H%M%S')"
38+
gitDate="$(TZ=UTC date -u --date "@$gitUnix" +'%Y%m%d%H%M%S')"
3639
fi
3740

3841
gitCommit="$($GIT_COMMAND log -1 --pretty='%h')"
3942
# generated version is now something like '0.0.0-20180719213702-cd5e2db'
40-
staticVersion="0.0.0-${gitDate}-${gitCommit}"
43+
staticVersion="0.0.0-${gitDate}-${gitCommit}" # (using hyphens)
4144
fi
4245

4346
echo "$staticVersion"

0 commit comments

Comments
 (0)