From 907f13f99f8150ccf82de1f0d4b59fb24682a501 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 1/6] Versioning: MAY → **may**, etc Bold is enough to say that this is a special word, and the text is easier to read without the capital letters. --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index 94c5ec2..253198f 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -15,7 +15,7 @@ while accommodating varied and often inconsistent upstream versioning schemes. Note that upstreams may each have their own terminology and it is in general impossible to define these terms with complete generality. For some upstreams, every commit is itself considered a version. -Many upstreams never make releases, +Some upstreams never make releases, instead just letting users take whatever is in the code repository at any given time. release version:: @@ -60,31 +60,25 @@ are available from https://fedoraproject.org/wiki/Package_Versioning_Examples[Pa == Epoch: tag The `+Epoch:+` tag provides the most significant input to RPM's version comparison function. -If present, it MUST consist of a positive integer. -It SHOULD ONLY be introduced or incremented +If present, it **must** consist of a positive integer. +It **should only** be introduced or incremented when necessary to avoid ordering issues. The `+Epoch:+` tag, once introduced to a package, -MUST NOT ever be removed or decreased in any way. +**must never** be removed or decreased. == Simple versioning Most upstream versioning schemes are "simple"; -they generate versions like "1.2.03.007p1". -They consist of one or more version components, -separated by periods. -Each component is a whole number, -potentially with leading zeroes. -The rightmost component can also include -one or more ASCII letters, -upper or lower case. -The value of a component must *never* be reduced -(to a value which sorts lower) +they generate versions like `+1.2.03.007p1+`. +They consist of one or more version components, separated by periods. +Each component is a whole number, potentially with leading zeroes. +The components can also include one or more ASCII letters, upper or lower case. +The value of a component must *never* be reduced (to a value which sorts lower) without a component somewhere to the left increasing. -Note that the version sequence -("1.4a", "1.4b", "1.4") +Note that the version sequence (`+1.4a+`, `+1.4b+`, `+1.4+`) does not meet this criterion, -as "4" sorts lower than "4b". -The sequence ("1.4", "1.4a", "1.4b") is, however, simple. +as `+4+` sorts lower than `+4b+`. +The sequence (`+1.4+`, `+1.4a+`, `+1.4b+`) is, however, simple. This is a very common versioning scheme, and the vast majority of software projects use something which works like this. @@ -128,7 +122,7 @@ the structured `+Release:+` tag: * snapshot information (`++`) * minor release bump (`++`) -The package release number MUST always be present +The package release number **must** always be present while the others may or may not be depending on the situation. Those items which are present are combined @@ -151,7 +145,7 @@ and may in some circumstances contain additional structure, including tildes. As this is not under the control of the packager, that structure is not covered here. -The packager MUST simply include `+%{?dist}+` verbatim +The packager **must** simply include `+%{?dist}+` verbatim as indicated above. === Upstream has never chosen a version @@ -197,11 +191,11 @@ use Version: 0 and move the _entire_ version string into `++`. === Snapshots -All snapshots MUST contain a snapshot information field +All snapshots **must** contain a snapshot information field (`+:+`) in the `+Release:+` tag. That field must at minimum consist of the date in eight-digit "YYYYMMDD" format. -The packager MAY include +The packager **may** include up to 17 characters of additional information after the date. The following formats are suggested: @@ -221,7 +215,7 @@ in upstream's source code control system. Obviously if CVS is used, no such revision information exists, so it would be omitted, -but otherwise it SHOULD be included. +but otherwise it **should** be included. === Prerelease versions @@ -231,7 +225,7 @@ For the field of the `+Release:+` tag, use a number of the form "0.N" where N is an integer beginning with 1 and increasing for each revision of the package. -Prerelease versions MUST use +Prerelease versions **must** use a `+Release:+` tag strictly less than 1, as this is the sole indicator that a prerelease has been packaged. @@ -240,7 +234,7 @@ as this is the sole indicator that a prerelease has been packaged. For the `++` field of the `+Release:+` tag, use an integer beginning with 1 and increasing for each revision of the package. -Release and post-release versions MUST use +Release and post-release versions **must** use a `+Release:+` tag greater than or equal to 1. === Upstream makes unsortable changes @@ -269,7 +263,7 @@ to ensure that F{CURRENTVER} < F{NEXTVER}, but that is a waste of time and energy for the newer branches which do not need to be touched. -In this case, you MAY set `++` +In this case, you **may** set `++` to an in integer beginning with '1' and increasing by one for each minor bump you need to do. Remove `++` once you are able @@ -303,7 +297,7 @@ and thus will not serve as an upgrade to the existing package. == Rawhide is allowed to lag temporarily -A package MAY temporarily have a lower EVR in Rawhide +A package **may** temporarily have a lower EVR in Rawhide when compared to a release branch of Fedora ONLY in the case where the package fails to build in Rawhide. This permits important updates to be pushed to existing Fedora releases From 81d03d6fba9a808a973924e7d6c655c3b672359d Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 2/6] Versioning: switch to ~ and ^ for pre- and post-release versions This makes versioning vastly simpler from the packager POV: - the upstream release can *always* be manipulated into Version that sorts properly. - downstream information is contained solely in the Release field, and it can be bumped without any drama. This is based on other drafts, in particular - https://pagure.io/packaging-committee/pull-request/908. Also see: - https://fedoraproject.org/wiki/PackagingDrafts/TildeVersioning - https://github.com/rpm-software-management/rpm/pull/597 The guidelines go into quite a lot of complexity to cover complicated cases. But nowadays 99% of upstreams use fairly mundane release numbering schemes, so almost all packaging scenarios will be covered by simple uses of plain numbers, with an overwhelming majority of the remaining sliver covered by an occasional insertion of ~pre or ^post. --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index 253198f..7641f39 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -52,11 +52,6 @@ non-sorting version sequence:: from RPM's implementation then simply using upstream's versions directly will result in updates which don't actually update any packages. -== Examples - -Examples of many possible versioning scenarios -are available from https://fedoraproject.org/wiki/Package_Versioning_Examples[Package Versioning Examples]. - == Epoch: tag The `+Epoch:+` tag provides the most significant input to RPM's version comparison function. @@ -92,7 +87,7 @@ To package *release versions* of software using this versioning scheme: Increment the release (by 1) for each update you make. Reset to 1 whenever you change `+Version:+`. -== More complex versioning +== Complex versioning There are several ways in which the simple scheme might not work in a particular situation: @@ -105,14 +100,252 @@ in a particular situation: (snapshot or otherwise). * You wish to package a postrelease snapshot. * Upstream was thought to be following one scheme - but then changed in a way that can't be sorted. + but then changed in a way that does not sort properly. * You need to apply a small fix to a release branch of Fedora without updating the newer branches. * More than one of the above may apply (lucky you). Follow all of the relevant recommendations below together. -The methods for dealing with most of these issues involves -potentially removing some information from the `+Version:+` tag +=== Handling non-sorting versions with tilde and caret + +The tilde symbol ('`+~+`') is used before a version component which must sort *earlier* than any non-tilde component. +It is used for any pre-release versions which wouldn't otherwise sort appropriately. + +For example, with upstream releases `+0.4.0+`, `+0.4.1+`, `+0.5.0-rc1+`, `+0.5.0-rc2+`, `+0.5.0+`, +the two "release candidates" should use `+0.5.0~rc1+` and `+0.5.0~rc2+` in the `+Version:+` field. + +The caret symbol ('`+^+`') is used before a version component which must sort *later* than any non-caret component. +It is used for any post-release versions which wouldn't otherwise sort appropriately. + +For example, if the same upstream released `+0.5.0-post20200508+` as a bugfix version, +this "post-release" should use `+0.5.0^post20200508+` in the `+Version:+` field. +Note that `+0.5.0^post20200508+` sorts lower than `+0.5.1+` **and** `+0.5.0.1+`. + +=== Snapshots + +Snapshots (a version taken from the upstream source control system not associated with a release), +**must** contain a snapshot information field. +That field must at minimum consist of the date in eight-digit "YYYYMMDD" format, +which specifies the last modification of the source code. +The packager **may** include up to 17 characters of additional information after the date, +specifying the version control system and commit identifier. +The snapshot information field **should** be appended to version field described above, +possibly including the pre-release and post-release information. +When the snapshot follows a normal release version, it should be separated by two carets (`+^^+`). +When the snapshot follows a pre- or post-release version, it should be separated by a single caret (`+^+`). + +The following formats should be used for the snapshot information field: + +* `+YYYYMMDD.+` +* `+YYYYMMDD+` + +Where `++` is a short string +identifying the source code control system upstream uses +(e.g. "git", "svn", "hg") or the string "snap". +The `++` string may be abbreviated to a single letter. +`++` is either a short git commit hash, a subversion revision number, +or something else useful in identifying the precise revision in upstream's source code control system. +If the version control system does not provide an identifier (e.g. CVS), this part should be omitted. +A full hash **should not** be used for `++`, to avoid overly long version numbers; +only the first 7 to 10 characters. + +For example, if the last upstream release was `+0.4.1+`, +a snapshot could use `+0.4.1^^20200601g01234ae+` in the `+Version:+` field. +If the last upstream post-release was `+0.5.0-post20200508+`, +a snapshot could use `+0.5.0^post20200508^20200601g01234ae+` in the `+Version:+` field. +Similarly, if the upstream then makes a pre-release with version `+0.5.0-rc1+`, +but it is buggy, and we need to actually package a post-pre-release snapshot, +this shapshot could use `+0.5.0~rc1^20200701gdeadf00f+` in the `+Version:+` field. + +If upstream is known to never use post-release versions, +or use post-release versions that already sort appropriately, +a single caret **may** be used instead of the double for post-release snapshots. + +For example, if upstream releases `+5.13.0+` as the stable version, +and then `+5.13.1+`, `+5.13.2+`, …, `+5.13.1.17+`, `+5.13.2.8+` as bugfix versions, +a snapshot could be versioned as `+5.13.0^20200601g01234ae+` +or `+5.13.1.17^20200701gdeadf00f+`. + +=== Upstream has never chosen a version + +When upstream has never chosen a version, +you **must** use `+Version: 0+`. +"`+0+`" sorts lower than any other possible value that upstream might choose. +And if upstream does choose to release "version 0" +then you can immediately move to using `+Release: 1%{?dist}+` +with no ordering issues. + +=== Upstream uses invalid characters in the version + +It's possible that upstream uses characters besides ASCII letters +(upper and lower case), digits and periods in its version. +They must be removed and potentially replaced with valid characters. +Any such alterations **must** be documented in the specfile. +It is not possible to cover all potential situations here, +so it is left to the packager +to alter the upstream versioning scheme consistently. + +After altering the version to be free of invalid characters, +see <> below +if the modifications, +when applied to successive releases from upstream, +will not order properly. + +=== Unsortable versions + +When upstream uses a versioning scheme that does not sort properly, +first see if simply inserting a tilde or caret is enough to make the string sortable. + +For example, if upstream uses a sequence like `+1.2pre1+`, `+1.2pre2+`, `+1.2final+`, +then `+1.2~pre1+`, `+1.2~pre2+`, `+1.2final+` could be used as `+Version+`. + +If this is not possible, use something similar to the snapshot versioning described above, +with the upstream version moved to the second part of the snapshot information field: +`+.+`. + +For example, if upstream releases versions `+I+`, `+II+`, …, `+VIII+`, `+IX+` +use `+20200101.I+`, `+20200201.II+`, …, `+20200801.III+`, `+20200901.IX+` +in the `+Version+` field. + +=== Upstream breaks version scheme + +It is possible that upstream simply adopts a different versioning scheme, +fails to follow an expected pattern, +or even simply resets their version to some lower value. +If none of the above operations can help +with giving a version which sorts properly, +or give you a version which sorts lower +than the packages already in Fedora, +then you have little recourse but to increment the `+Epoch:+` tag, +or to begin using it by adding `+Epoch: 1+`. +At the same time, try to work with upstream +to hopefully minimize the need to involve `+Epoch:+` in the future. + +=== Examples + +==== Comparing versions with `rpmdev-vercmp` + +When in doubt, verify the sorting with `rpmdev-vercmp` from the `rpmdevtools` package: + +```console +$ rpmdev-vercmp 2~almost^post 2.0.1 +2~almost^post < 2.0.1 +``` + +==== Simple versioning + +[%header] +|=== +|Upstream| Version field | Release field | Explanation + +|1.0 |1.0 | 1%{?dist} | The first release. + +|1.1 |1.1 | 1%{?dist} | An upstream update. + +|1.1 |1.1 | 2%{?dist} | You made a change to the package but the upstream version didn't change. + +|1.2 |1.2 | 1%{?dist} | The upstream version changed, so Release: goes back to 1. + +|1.2.1 |1.2.1 |1%{?dist} | Extra levels of versioning are OK… + +|1.3 |1.3 |1%{?dist} | …they can come and go without problems. +|=== + +[%header] +|=== +|Upstream| Version field | Release field | Explanation + +| 5.2 | 5.2 | 1%{?dist} | + +| 5.2a | 5.2a | 1%{?dist} | Upstream introduced a letter to indicate a patch release. You trust upstream to use letters in alphabetical order, so it's OK to use the version as is. + +| 5.2b | 5.2b | 1%{?dist} | + +| 5.2b.1 | 5.2b.1 | 1%{?dist} | Even this is OK as long as the sequence increases. + +| 5.3 | 5.3 | 1%{?dist} | +|=== + +==== Complex versioning with a reasonable upstream + +[%header] +|=== +|Upstream version | Full package NEVRA | Notes + +| 1.0.0-rc1 | `+pkg-1.0.0~rc1-1%{?dist}+` | first prerelease + +| 1.0.0-rc2 | `+pkg-1.0.0~rc2-1%{?dist}+` | second prerelease + +| 1.0.0 | `+pkg-1.0.0-1%{?dist}+` | release + +| 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | bugfix release + +| 1.0.1-security1 | `+pkg-1.0.1^security1-1%{?dist}+` | security bufix release +|=== + +==== Complex versioning with non-sorting upstream post-release versions + +[%header] +|=== +|Upstream version | Full package NEVRA | Notes + +| 1.1.0~BETA | `+pkg-1.1.0~BETA-1%{?dist}+` | this is a prerelease, first beta + +| 1.1.0~BETA1 | `+pkg-1.1.0~BETA1-1%{?dist}+` | this is a prerelease, second beta + +| 1.1.0~BETA2 | `+pkg-1.1.0~BETA2-1%{?dist}+` | this is a prerelease, third beta + +| 1.1.0~CR1 | `+pkg-1.1.0~CR1-1%{?dist}+` | this is a prerelease, candidate release 1 + +| 1.1.0~CR2 | `+pkg-1.1.0~CR2-1%{?dist}+` | this is a prerelease, candidate release 2 + +| | `+pkg-1.1.0~CR2-2%{?dist}+` | this is a prerelease, candidate release 2, second build + +| 1.1.0-1% | `+pkg-1.1.0-1%{?dist}+` | final release + +| 1.1.0-GA1 | `+pkg-1.1.0^GA1-1%{?dist}+` | post release, GA1 + +| 1.1.0-CP1 | `+pkg-1.1.0^20201011.CP1-1%{?dist}+` | post release, CP1, after GA1, does not sort properly + +| 1.1.0-CP2 | `+pkg-1.1.0^20201101.CP2-1%{?dist}+` | post release, CP2, after CP1 + +| 1.1.0-SP1 | `+pkg-1.1.0^20210101.SP1-1%{?dist}+` | post release, SP1, after CP2 + +| 1.1.0-SP1-CP1 | `+pkg-1.1.0^20210105.SP1_CP1-1%{?dist}+` | post release, SP1_CP1, after SP1 +|=== + +==== Complex versioning with a pre- and post-release snapshots + +[%header] +|=== +|Upstream version | Full package NEVRA | Notes + +| 1.0.0-rc1 | `+pkg-1.0.0~rc1-1%{?dist}+` | first prerelease + +| 1.0.0-rc2 | `+pkg-1.0.0~rc2-1%{?dist}+` | second prerelease + +| git commit `f00fabd` | `+pkg-1.0.0~rc2-1%{?dist}^20210101gf00fabd+` | post-prerelease snapshot + +| 1.0.0 | `+pkg-1.0.0-1%{?dist}+` | release + +| | `+pkg-1.0.0-2%{?dist}+` | a rebuild from the same sources + +| 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | bugfix release + +| git commit `bbbccc0` | `+pkg-1.0.1^^20210203gbbbccc0-1%{?dist}+` | a snapshot + +| 1.0.1-security1 | `+pkg-1.0.1^security1-1%{?dist}+` | security bufix release + +| git commit `abc0202` | `+pkg-1.0.1^security1^20210301gabc0202-1%{?dist}+` | another snapshot +|=== + + +== Traditional versioning with part of the upstream version information in the release field + +The method described in this section is deprecated, but **may** be used. + +This method for dealing with most pre- and post-release versions and unsortable versions +involves potentially removing some information from the `+Version:+` tag while imposing additional structure onto the `+Release:+` tag. There are potentially four fields which comprise the structured `+Release:+` tag: @@ -148,31 +381,6 @@ that structure is not covered here. The packager **must** simply include `+%{?dist}+` verbatim as indicated above. -=== Upstream has never chosen a version - -When upstream has never chosen a version, -you MUST use `+Version: 0+`. -"`+0+`" sorts lower than any other possible value that upstream might choose. -And if upstream does choose to release "version 0" -then you can immediately move to using `+Release: 1%{?dist}+` -with no ordering issues. - -=== Upstream uses invalid characters in the version - -It's possible that upstream uses characters besides ASCII letters -(upper and lower case), digits and periods in its version. -They must be removed and potentially replaced with valid characters. -Any such alterations MUST be documented in the specfile. -It is not possible to cover all potential situations here, -so it is left to the packager -to alter the upstream versioning scheme consistently. - -After altering the version to be free of invalid characters, -see <> below -if the modifications, -when applied to successive releases from upstream, -will not order properly. - === Unsortable versions When upstream uses a versioning scheme that does not sort properly, @@ -237,21 +445,17 @@ and increasing for each revision of the package. Release and post-release versions **must** use a `+Release:+` tag greater than or equal to 1. -=== Upstream makes unsortable changes +=== Examples + +Examples of many possible versioning scenarios of traditional versioning +are available from +https://fedoraproject.org/wiki/Package_Versioning_Examples[Package Versioning Examples]. -It is possible that upstream simply adopts a different versioning scheme, -fails to follow an expected pattern, -or even simply resets their version to some lower value. -If none of the above operations can help -with giving a version which sorts properly, -or give you a version which simply sorts lower -than the packages already in Fedora, -then you have little recourse but to increment the `+Epoch:+` tag, -or to begin using it by adding `+Epoch: 1+`. -At the same time, try to work with upstream -to hopefully minimize the need to involve `+Epoch:+` in the future. -=== You need to change an old branch without rebuilding the others + + + +== You need to change an old branch without rebuilding the others Sometimes, you may find yourself in a situation where an older branch needs a fix, but the newer branches are fine. @@ -270,30 +474,6 @@ Remove `++` once you are able to increase the package release normally without introducing ordering issues. -== Versioning prereleases with tilde - -If you wish to package a prerelease version -and are confident that you will need to package -only tagged releases and not any snapshots -until the next release, -you MAY make use of RPM's tilde ('`+~+`') notation. -To do this, split upstream's prerelease version into two components: - -* the version that the next actual release will take (`++`). -* the "prerelease" portion (`++`). - -Then you construct `+Version:+` and `+Release:+` as follows: - - Version: ~ - Release: %{?dist}[.] - -with `++` and `++` as detailed above. - -Note that you MUST NOT mix the use of tilde with -the previously detailed scheme for versioning prerelease snapshots. -Once a snapshot has been packaged according to these guidelines, -any `+Version:+` which uses tilde will be seen by RPM as older -and thus will not serve as an upgrade to the existing package. == Rawhide is allowed to lag temporarily From 7ca1c1facbe42b6b207d3ccba4e58735939516ac Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 3/6] Stop using ^ for snapshots In previous scheme, carets were used for both snapshots and any "post-releases", i.e. non-numerical upstream bugfix versions. But to make sure that snapshots based from the initial release sort earlier than a subsequent post-release, the snapshot needed to start with a double caret. This was rather complex and people didn't like it. It turns out to be unnecessary for two reasons: - a normal dot is actually appropriate for post-release versions. It already sorts later than the release, so we don't need to do anything special. - I looked over list of all packages returned by 'dnf list --releasever=rawhide --disablerepo=\* --enablerepo=fedora-source', and there's just a handful of packages with non-sorting versions. I think that fancy version schemes were more popular in the past, and nowadays semver and ubuntu-style date-based versions are much more popular. So any fancy scheme that we come up would be used for maybe a few packages out of 20k+ source packages currently in Fedora. We can handle those few special cases using snaphot-like date-based versions, and keep the general case simpler. In the new sheme is that ^ is only used for non-release snapshots. --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index 7641f39..f529de7 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -106,7 +106,7 @@ in a particular situation: * More than one of the above may apply (lucky you). Follow all of the relevant recommendations below together. -=== Handling non-sorting versions with tilde and caret +=== Handling non-sorting versions with tilde, dot, and caret The tilde symbol ('`+~+`') is used before a version component which must sort *earlier* than any non-tilde component. It is used for any pre-release versions which wouldn't otherwise sort appropriately. @@ -114,25 +114,26 @@ It is used for any pre-release versions which wouldn't otherwise sort appropriat For example, with upstream releases `+0.4.0+`, `+0.4.1+`, `+0.5.0-rc1+`, `+0.5.0-rc2+`, `+0.5.0+`, the two "release candidates" should use `+0.5.0~rc1+` and `+0.5.0~rc2+` in the `+Version:+` field. -The caret symbol ('`+^+`') is used before a version component which must sort *later* than any non-caret component. -It is used for any post-release versions which wouldn't otherwise sort appropriately. +Bugfix or "patchlevel" releases that some upstream make should be handled using simple versioning. +The separator used by upstream may need to be replaced by a dot or dropped. + +For example, if the same upstream released `+0.5.0-post1+` as a bugfix version, +this "post-release" should use `+0.5.0.post1+` in the `+Version:+` field. +Note that `+0.5.0.post1+` sorts lower than both `+0.5.1+` and `+0.5.0.1+`. -For example, if the same upstream released `+0.5.0-post20200508+` as a bugfix version, -this "post-release" should use `+0.5.0^post20200508+` in the `+Version:+` field. -Note that `+0.5.0^post20200508+` sorts lower than `+0.5.1+` **and** `+0.5.0.1+`. +The caret symbol ('`+^+`') is used before a version component which must sort *later* than any non-caret component. +It is used for post-release snapshots, see next section. === Snapshots Snapshots (a version taken from the upstream source control system not associated with a release), -**must** contain a snapshot information field. +**must** contain a snapshot information field after a caret (`+^+`). That field must at minimum consist of the date in eight-digit "YYYYMMDD" format, which specifies the last modification of the source code. The packager **may** include up to 17 characters of additional information after the date, specifying the version control system and commit identifier. -The snapshot information field **should** be appended to version field described above, -possibly including the pre-release and post-release information. -When the snapshot follows a normal release version, it should be separated by two carets (`+^^+`). -When the snapshot follows a pre- or post-release version, it should be separated by a single caret (`+^+`). +The snapshot information field is appended to version field described above, +possibly including the pre-release and patchlevel information. The following formats should be used for the snapshot information field: @@ -150,21 +151,12 @@ A full hash **should not** be used for `++`, to avoid overly long vers only the first 7 to 10 characters. For example, if the last upstream release was `+0.4.1+`, -a snapshot could use `+0.4.1^^20200601g01234ae+` in the `+Version:+` field. -If the last upstream post-release was `+0.5.0-post20200508+`, -a snapshot could use `+0.5.0^post20200508^20200601g01234ae+` in the `+Version:+` field. +a snapshot could use `+0.4.1^20200601g01234ae+` in the `+Version:+` field. Similarly, if the upstream then makes a pre-release with version `+0.5.0-rc1+`, but it is buggy, and we need to actually package a post-pre-release snapshot, this shapshot could use `+0.5.0~rc1^20200701gdeadf00f+` in the `+Version:+` field. -If upstream is known to never use post-release versions, -or use post-release versions that already sort appropriately, -a single caret **may** be used instead of the double for post-release snapshots. - -For example, if upstream releases `+5.13.0+` as the stable version, -and then `+5.13.1+`, `+5.13.2+`, …, `+5.13.1.17+`, `+5.13.2.8+` as bugfix versions, -a snapshot could be versioned as `+5.13.0^20200601g01234ae+` -or `+5.13.1.17^20200701gdeadf00f+`. +Note that `+0.4.1^+` sorts higher than `+0.4.1+`, but lower than both `+0.4.2+` and `+0.4.1.+`. === Upstream has never chosen a version @@ -197,9 +189,11 @@ When upstream uses a versioning scheme that does not sort properly, first see if simply inserting a tilde or caret is enough to make the string sortable. For example, if upstream uses a sequence like `+1.2pre1+`, `+1.2pre2+`, `+1.2final+`, -then `+1.2~pre1+`, `+1.2~pre2+`, `+1.2final+` could be used as `+Version+`. +then `+1.2~pre1+`, `+1.2~pre2+`, `+1.2_final+` could be used as `+Version+`. +The underscore ('`+_+`') is a visual separator that does not influence sort order, +and is used here because "final" does not form a separate version component. -If this is not possible, use something similar to the snapshot versioning described above, +If this is not possible, use something similar to the snapshot version information field described above, with the upstream version moved to the second part of the snapshot information field: `+.+`. @@ -280,7 +274,7 @@ $ rpmdev-vercmp 2~almost^post 2.0.1 | 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | bugfix release -| 1.0.1-security1 | `+pkg-1.0.1^security1-1%{?dist}+` | security bufix release +| 1.0.1-security1 | `+pkg-1.0.1.security1-1%{?dist}+` | security bufix release |=== ==== Complex versioning with non-sorting upstream post-release versions @@ -303,40 +297,41 @@ $ rpmdev-vercmp 2~almost^post 2.0.1 | 1.1.0-1% | `+pkg-1.1.0-1%{?dist}+` | final release -| 1.1.0-GA1 | `+pkg-1.1.0^GA1-1%{?dist}+` | post release, GA1 +| 1.1.0-GA1 | `+pkg-1.1.0.20201001.GA1-1%{?dist}+` | post release, GA1 -| 1.1.0-CP1 | `+pkg-1.1.0^20201011.CP1-1%{?dist}+` | post release, CP1, after GA1, does not sort properly +| 1.1.0-CP1 | `+pkg-1.1.0.20201011.CP1-1%{?dist}+` | post release, CP1, after GA1, does not sort properly -| 1.1.0-CP2 | `+pkg-1.1.0^20201101.CP2-1%{?dist}+` | post release, CP2, after CP1 +| 1.1.0-CP2 | `+pkg-1.1.0.20201101.CP2-1%{?dist}+` | post release, CP2, after CP1 -| 1.1.0-SP1 | `+pkg-1.1.0^20210101.SP1-1%{?dist}+` | post release, SP1, after CP2 +| 1.1.0-SP1 | `+pkg-1.1.0.20210101.SP1-1%{?dist}+` | post release, SP1, after CP2 -| 1.1.0-SP1-CP1 | `+pkg-1.1.0^20210105.SP1_CP1-1%{?dist}+` | post release, SP1_CP1, after SP1 +| 1.1.0-SP1-CP1 | `+pkg-1.1.0.20210105.SP1_CP1-1%{?dist}+` | post release, SP1_CP1, after SP1 |=== + ==== Complex versioning with a pre- and post-release snapshots [%header] |=== |Upstream version | Full package NEVRA | Notes -| 1.0.0-rc1 | `+pkg-1.0.0~rc1-1%{?dist}+` | first prerelease +| 1.0.0-rc1 | `+pkg-1.0.0~rc1-1%{?dist}+` | First prerelease -| 1.0.0-rc2 | `+pkg-1.0.0~rc2-1%{?dist}+` | second prerelease +| 1.0.0-rc2 | `+pkg-1.0.0~rc2-1%{?dist}+` | Second prerelease -| git commit `f00fabd` | `+pkg-1.0.0~rc2-1%{?dist}^20210101gf00fabd+` | post-prerelease snapshot +| git commit `f00fabd` | `+pkg-1.0.0~rc2^20210101gf00fabd-1%{?dist}+` | Post-prerelease snapshot -| 1.0.0 | `+pkg-1.0.0-1%{?dist}+` | release +| 1.0.0 | `+pkg-1.0.0-1%{?dist}+` | A release -| | `+pkg-1.0.0-2%{?dist}+` | a rebuild from the same sources +| | `+pkg-1.0.0-2%{?dist}+` | A rebuild from the same sources -| 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | bugfix release +| 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | A bugfix release -| git commit `bbbccc0` | `+pkg-1.0.1^^20210203gbbbccc0-1%{?dist}+` | a snapshot +| git commit `bbbccc0` | `+pkg-1.0.1^20210203gbbbccc0-1%{?dist}+` | A snapshot -| 1.0.1-security1 | `+pkg-1.0.1^security1-1%{?dist}+` | security bufix release +| 1.0.1-security1 | `+pkg-1.0.1.security1-1%{?dist}+` | A security bufix release. From past history we know that the bugfix releases will have sortable versions. If not, we could use '`+.security1+`' instead. -| git commit `abc0202` | `+pkg-1.0.1^security1^20210301gabc0202-1%{?dist}+` | another snapshot +| git commit `abc0202` | `+pkg-1.0.1.security1^20210301gabc0202-1%{?dist}+` | Another snapshot |=== From 7bf6caef32016aada62d947cc03c7d37431e36dd Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 4/6] Versioning: allow a number as replacement for date in shapshot information This provides a shorter and simpler method for constructing the shapshot information field. Sort order is obviously preserved, but a simple number has the following minor advantages: - it is shorter, which matters with the already fairly long git snapshot fields - the maintainer does not have to look up the commit date The main motivation is that for some projects, the date of the commit is not interesting. For example, systemd project makes systemd-stable branches with commits which are cherry-picked from the main development branch, or from newer stable branches. But the order in which commits are cherry-picked is not stable: when a commit is an obvious and important bugfix, it may be cherry-picked onto multiple stable branches at once. But sometimes we only belatedly realize that something is a fix, or poeple request something to be backported, and then one or more patches are applied. Git associates two dates with a commit: the author timestamp and the application timestamp. For backported commits, the author timestamp can jump backwards and forwards and is not interesting. The commit timestamp should mostly be monotonic, but it's just not interesting for backported commits, because it shows when the stable branch maintainer had time to do backports. The commit date is not harmful, but it doesn't bring enough value to make it required in the snapshot information field. A final minor technical motivation is that both the author and commit timestamps in git are controlled by the committer and may not be monotonic. If upstream has unreliable commit timestamps, using a number is better and simpler than making up some different dates downstream. This implements my suggestion from https://pagure.io/packaging-committee/pull-request/908#comment-90159. --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index f529de7..f9e1fd8 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -128,17 +128,21 @@ It is used for post-release snapshots, see next section. Snapshots (a version taken from the upstream source control system not associated with a release), **must** contain a snapshot information field after a caret (`+^+`). -That field must at minimum consist of the date in eight-digit "YYYYMMDD" format, -which specifies the last modification of the source code. +The first part of the field ensures proper sorting. +That field may either the date in eight-digit "YYYYMMDD" format, +which specifies the last modification of the source code, +or a number. The packager **may** include up to 17 characters of additional information after the date, specifying the version control system and commit identifier. The snapshot information field is appended to version field described above, possibly including the pre-release and patchlevel information. -The following formats should be used for the snapshot information field: +One of the following formats should be used for the snapshot information field: -* `+YYYYMMDD.+` -* `+YYYYMMDD+` +* `+.+` +* `++` +* `+.+` +* `+.+` Where `++` is a short string identifying the source code control system upstream uses @@ -153,8 +157,12 @@ only the first 7 to 10 characters. For example, if the last upstream release was `+0.4.1+`, a snapshot could use `+0.4.1^20200601g01234ae+` in the `+Version:+` field. Similarly, if the upstream then makes a pre-release with version `+0.5.0-rc1+`, -but it is buggy, and we need to actually package a post-pre-release snapshot, -this shapshot could use `+0.5.0~rc1^20200701gdeadf00f+` in the `+Version:+` field. +but it is buggy, and we need to actually package two post-pre-release snapshots, +those shapshots could use `+0.5.0~rc1^20200701gdeadf00f+` and `+0.5.0~rc1^20200702gdeadaeae+` +in the `+Version:+` field. + +Alternatively, those three snapshots could be versioned as +`+0.4.1^1.git01234ae+`, `+0.5.0~rc1^1.gitdeadf00f+` and `+0.5.0~rc1^2.gitdeadaeae+`. Note that `+0.4.1^+` sorts higher than `+0.4.1+`, but lower than both `+0.4.2+` and `+0.4.1.+`. @@ -327,11 +335,11 @@ $ rpmdev-vercmp 2~almost^post 2.0.1 | 1.0.1 | `+pkg-1.0.1-1%{?dist}+` | A bugfix release -| git commit `bbbccc0` | `+pkg-1.0.1^20210203gbbbccc0-1%{?dist}+` | A snapshot +| git commit `bbbccc0` | `+pkg-1.0.1^20210203gbbbccc0-1%{?dist}+` or `+pkg-1.0.1^1.gbbbccc0-1%{?dist}+` | A snapshot | 1.0.1-security1 | `+pkg-1.0.1.security1-1%{?dist}+` | A security bufix release. From past history we know that the bugfix releases will have sortable versions. If not, we could use '`+.security1+`' instead. -| git commit `abc0202` | `+pkg-1.0.1.security1^20210301gabc0202-1%{?dist}+` | Another snapshot +| git commit `abc0202` | `+pkg-1.0.1.security1^20210301gabc0202-1%{?dist}+` or `+pkg-1.0.1.security1^1.gabc0202-1%{?dist}+` | Another snapshot |=== From b015a238e38e8fb990b639fef43ce5e0e7c3407f Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 5/6] Adjust note about "version 0" The old text made sense when there was a convention to use something smaller than 1 in Release. In particular, people sometimes put there 0 during review. This is not very imporant, let's make the text more general. --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index f9e1fd8..38b5d4a 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -171,9 +171,8 @@ Note that `+0.4.1^+` sorts higher than `+0.4.1+`, but lower than both When upstream has never chosen a version, you **must** use `+Version: 0+`. "`+0+`" sorts lower than any other possible value that upstream might choose. -And if upstream does choose to release "version 0" -then you can immediately move to using `+Release: 1%{?dist}+` -with no ordering issues. +If upstream does choose to release "version 0", +then just set `+Release:+` higher than the previous value. === Upstream uses invalid characters in the version From b93aecc7c6b4785812f04c2c8c46df3eecf35926 Mon Sep 17 00:00:00 2001 From: Zbigniew Jędrzejewski-Szmek Date: Jul 01 2021 16:23:34 +0000 Subject: [PATCH 6/6] Say that RHEL<=7 should use the traditional approach --- diff --git a/guidelines/modules/ROOT/pages/Versioning.adoc b/guidelines/modules/ROOT/pages/Versioning.adoc index 38b5d4a..fcddde8 100644 --- a/guidelines/modules/ROOT/pages/Versioning.adoc +++ b/guidelines/modules/ROOT/pages/Versioning.adoc @@ -124,6 +124,11 @@ Note that `+0.5.0.post1+` sorts lower than both `+0.5.1+` and `+0.5.0.1+`. The caret symbol ('`+^+`') is used before a version component which must sort *later* than any non-caret component. It is used for post-release snapshots, see next section. +IMPORTANT: The caret operator is not supported in RHEL7 which has rpm 4.11. +If you need to support RHEL7/EPEL7 from the same specfile, use +<> +instead. + === Snapshots Snapshots (a version taken from the upstream source control system not associated with a release), @@ -345,6 +350,9 @@ $ rpmdev-vercmp 2~almost^post 2.0.1 == Traditional versioning with part of the upstream version information in the release field The method described in this section is deprecated, but **may** be used. +As mentioned in the <> section above, +this method is recommended for packages with complex versioning when supporting RHEL7 +and other systems with old rpm versions. This method for dealing with most pre- and post-release versions and unsortable versions involves potentially removing some information from the `+Version:+` tag