Versiointiohjeet
Fedoran pakettiversiointijärjestelmä kattaa sekä Version:
- että Release:
-tunnisteet, myös tunnisteen Epoch:
. Päätavoitteena on tarjota pakettien sarjoja, joita RPM:n versiovertailualgoritmi käsittelee päivityksinä, samalla kun ne mukautuvat vaihteleviin ja usein epäjohdonmukaisiin ylävirran versioihin.
The Version:
field contains the upstream project version, and the Release:
field specifies the downstream release number.
Joitain määritelmiä
Huomaa, että ylävirroissa voi kullakin olla oma terminologiansa ja on yleensä mahdotonta määritellä näitä termejä täysin yleisesti. Joillekin ylävirroille jokainen kommitointi itsessään katsotaan versioksi. Jotkut ylävirrat eivät koskaan julkaise julkaisu-versioita, vaan antavat käyttäjien ottaa mitä tahansa koodivarastosta milloin tahansa.
- julkaisuversio
-
Ohjelmiston versio, jonka ylävirta on päättänyt julkaista. Ohjelmiston julkaisu voi olla yhtä yksinkertaista kuin git-tunnisteen lisääminen. Tämä sisältää niin sanotut "pistejulkaisut" tai "korjaustasot", joita jotkut ylävirrat tekevät, koska niille on itse asiassa määritetty versiot ja julkaistu.
- tilannevedos
-
An archive taken from upstream’s source code control system which is not associated with any release version.
- esijulkaisuversio
-
Before a release happens, many upstreams will decide which version that will release will have, and then produce "alphas", "betas", "release candidates", or the like which carry that new version but indicate that the release of that version has not yet been made. These we call prerelease versions. Any snapshots made while upstream is preparing for their release are also considered prerelease versions.
- julkaisun jälkeinen versio
-
Any version which happens after a particular release is technically "post-release", but before upstream begins making prereleases for the next version, any snapshot is considered a postrelease version.
- non-sorting version sequence
-
A sequence of version strings which is not ordered in the same way that RPM’s version comparison function would order it. RPM has a somewhat complicated version comparison function which it will use to determine if a package is "newer". If upstream’s idea of what constitutes a "newer" version differs from RPM’s implementation then simply using upstream’s versions directly will result in updates which don’t actually update any packages.
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 when necessary to avoid ordering issues. The Epoch:
tag, once introduced to a package, must never be removed or decreased.
Release
tag
The Release:
should be managed automatically using the %autorelease
macro:
Release: %autorelease
As described in %autorelease documentation, the build machinery will replace the macro with the number of builds since the last commit that changed the Version
field, suffixed with the %{?dist}
tag. This means that a commit that changes Version
automatically gets Release: 1%{?dist}
, and commits after that get Release: 2%{?dist}
, Release: 3%{?dist}
, and so on.
Alternatively, the Release:
field may be updated manually. See Traditional versioning with part of the upstream version information in the release field.
Yksinkertainen versiointi
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 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
) does not meet this criterion, 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.
To package release versions of software using this versioning scheme:
-
Use the upstream project version verbatim in the
Version:
tag. Don’t trim leading zeroes.
Monimutkainen versiointi
There are several ways in which the simple scheme might not work in a particular situation:
-
Upstream has never chosen a version; only snapshots are available for packaging.
-
Upstream simply doesn’t use a version scheme which orders properly under RPM’s version comparison operation.
-
You wish to package a prerelease version (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 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.
This subsection describes how to modify the upstream project version to be suitable for the Version
field. Use of Release: +%autorelease+
remains unchanged.
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.
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.
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
.
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.
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 [Traditional versioning with part of the upstream version information in the release field] instead. |
Tilannevedokset
Snapshots (a version taken from the upstream source control system not associated with a release), must contain a snapshot information field after a caret (^
). 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.
One of the following formats should be used for the snapshot information field:
-
<date>.<revision>
-
<date><scm><revision>
-
<number>.<revision>
-
<number>.<scm><revision>
-
+<scm><date>.<revision>
-
+<scm><number>.<revision>
Where <scm>
is a short string identifying the source code control system upstream uses (e.g. "git", "svn", "hg") or the string "snap". The <scm>
string may be abbreviated to a single letter. <revision>
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 <revision>
, 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. 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 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^<something>
sorts higher than 0.4.1
, but lower than both 0.4.2
and 0.4.1.<anything>
.
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. If upstream does choose to release "version 0", then just set Release:
higher than the previous value. (When %autorelease
is used, this happens automatically.)
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 [Unsortable versions] below if the modifications, when applied to successive releases from upstream, will not order properly.
Ei lajiteltavissa olevat versiot
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.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 version information field described above, with the upstream version moved to the second part of the snapshot information field: <date>.<version>
.
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.
Esimerkit
Comparing versions with rpmdev-vercmp
When in doubt, verify the sorting with rpmdev-vercmp
from the rpmdevtools
package:
==== Yksinkertainen versiointi
[%header]
|===
|Upstream version | Version tag | Explanation
|1.0 |1.0 | The first release.
|1.1 |1.1 | An upstream update.
|1.2.1 |1.2.1 | Another upstream update. Extra levels of versioning are OK…
|1.3 |1.3 | …they can come and go without problems.
|===
In this case the full N-V-R could be e.g. `pkg-1.2.1-1.fc{CURRENTVER}` (immediately after an update) or `pkg-1.2.1-5.fc{CURRENTVER}` (after downstream rebuilds with the same upstream version).
[%header]
|===
|Upstream version | Version tag | Explanation
| 5.2 | 5.2 | Upstream release.
| 5.2a | 5.2a | 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 | Another patch release after 5.2 — this is not a beta.
| 5.2b.1 | 5.2b.1 | Even this is OK as long as the sequence increases.
| 5.3 | 5.3 | Another upstream release.
|===
In this case the full N-V-R could be e.g. `pkg-5.2b.1-1.fc{CURRENTVER}`.
==== Complex versioning with a reasonable upstream
[%header]
|===
|Upstream version | Version tag | Notes
| 1.0.0-rc1 | `+1.0.0~rc1+` | first prerelease
| 1.0.0-rc2 | `+1.0.0~rc2+` | second prerelease
| 1.0.0 | `+1.0.0+` | release
| 1.0.1 | `+1.0.1+` | bugfix release
| 1.0.1-security1 | `+pkg-1.0.1.security1+` | security bufix release
|===
In this case the full N-V-R could be e.g. `pkg-1.0.0~rc2-42.fc{CURRENTVER}` (if many rebuilds were done).
==== Complex versioning with non-sorting upstream post-release versions
[%header]
|===
|Upstream version | Version tag | Notes
| 1.1.0~BETA | `+1.1.0~BETA+` | this is a prerelease, first beta
| 1.1.0~BETA1 | `+1.1.0~BETA1+` | this is a prerelease, second beta
| 1.1.0~BETA2 | `+1.1.0~BETA2+` | this is a prerelease, third beta
| 1.1.0~CR1 | `+1.1.0~CR1+` | this is a prerelease, candidate release 1
| 1.1.0~CR2 | `+1.1.0~CR2+` | this is a prerelease, candidate release 2
| 1.1.0-1% | `+1.1.0+` | final release
| 1.1.0-GA1 | `+1.1.0.20201001.GA1+` | post release, GA1
| 1.1.0-CP1 | `+1.1.0.20201011.CP1+` | post release, CP1, after GA1, does not sort properly
| 1.1.0-CP2 | `+1.1.0.20201101.CP2+` | post release, CP2, after CP1
| 1.1.0-SP1 | `+1.1.0.20210101.SP1+` | post release, SP1, after CP2
| 1.1.0-SP1-CP1 | `+1.1.0.20210105.SP1_CP1+` | post release, SP1_CP1, after SP1
|===
In this case the full N-V-R could be e.g. `pkg-1.1.0.20210105.SP1_CP1-1.fc{CURRENTVER}`.
==== Complex versioning with a pre- and post-release snapshots
[%header]
|===
|Upstream version | Version | Notes
| 1.0.0-rc1 | `+1.0.0~rc1+` | First prerelease
| 1.0.0-rc2 | `+1.0.0~rc2+` | Second prerelease
| git commit `f00fabd` | `+1.0.0~rc2^20210101gf00fabd+` | Post-prerelease snapshot
| 1.0.0 | `+1.0.0+` | A release
| 1.0.1 | `+1.0.1+` | A bugfix release
| git commit `bbbccc0` | `+1.0.1^20210203gbbbccc0+` or `+pkg-1.0.1^1.gbbbccc0+` | A snapshot
| 1.0.1-security1 | `+1.0.1.security1+` | A security bufix release. From past history we know that the bugfix releases will have sortable versions. If not, we could use '`+<date>.security1+`' instead.
| git commit `abc0202` | `+1.0.1.security1^20210301gabc0202+` or `+pkg-1.0.1.security1^1.gabc0202+` | Another snapshot
|===
In this case the full N-V-R could be e.g. `pkg-1.0.1.security1^20210301gabc0202-1.fc{CURRENTVER}`.
[#traditional-versioning]
== 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 xref:_handling_non_sorting_versions_with_tilde_dot_and_caret[Handling non-sorting versions with tilde, dot, and caret] section above, this method is recommended for packages with complex versioning when supporting RHEL7 and other systems with old rpm versions.
In this method, `+%autorelease+` is not used, and the `Release` field must be managed manually.
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:
* package release number (`+<pkgrel>+`)
* extra version information (`+<extraver>+`)
* snapshot information (`+<snapinfo>+`)
* minor release bump (`+<minorbump>+`)
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 (with periods to separate them) to construct the final `+Release:+` tag. In the usual notation where square brackets indicate that an item is optional:
<pkgrel>[.<extraver>][.<snapinfo>]%{?dist}[.<minorbump>]
The actual values to be used for those three fields are situational and are referenced in the sections below. Note that your particular situation might not result in the use of `+<extraver>+` or `+<snapinfo>+`, and in most situations `+<minorbump>+` won't be used at all. Simply do not include those which you don't have.
Note that the dist tag is supplied by other portions of the system 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 as indicated above.
=== Ei lajiteltavissa olevat versiot
When upstream uses a versioning scheme that does not sort properly, first see if there is any portion which can be removed from the right side of the version string such that the remainder is sortable. This is often possible if upstream uses a sequence like ("1.2pre1", "1.2pre1", "1.2final"). If so, use the removed portion as `+<extraver>+` above, and the remainder as the package version. If this splitting leaves a leading or trailing period in either value, remove it.
If this is not possible, use Version: 0 and move the _entire_ version string into `+<extraver>+`.
=== Tilannevedokset
All snapshots **must** contain a snapshot information field (`+<snapinfo>:+`) in the `+Release:+` tag. That field must at minimum consist of the date in eight-digit "YYYYMMDD" format. The packager **may** include up to 17 characters of additional information after the date. The following formats are suggested:
* `+YYYYMMDD.<revision>+`
* `+YYYYMMDD<scm><revision>+`
Where `+<scm>+` is a short string identifying the source code control system upstream uses (e.g. "git", "svn", "hg") or the string "snap". `+<revision>+` 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. Obviously if CVS is used, no such revision information exists, so it would be omitted, but otherwise it **should** be included.
=== Esijulkaisuversio
In the `+Version:+` tag, use the version that upstream has determined the next release will be. 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 a `+Release:+` tag strictly less than 1, as this is the sole indicator that a prerelease has been packaged.
=== Release and post-release versions
For the `+<pkgrel>+` 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 a `+Release:+` tag greater than or equal to 1.
=== Rebuilds in older branches using `<minorbump>`
In the situation described in <<Only an old branch needs a change>>, you **may** adjust the `+Release+` by appending a number *after* the dist tag, creating a E-V-R for F{CURRENTVER} that still compares lower than the one in F{NEXTVER}. Set `+<minorbump>+` to an in integer beginning with '1' and increase it by one for each minor bump you need to do. Remove `+<minorbump>+` once you are able to increase the package release normally without introducing ordering issues.
=== Esimerkit
Examples of many possible versioning scenarios of traditional versioning are available from https://fedoraproject.org/wiki/Package_Versioning_Examples[Package Versioning Examples].
== Rawhide is allowed to lag temporarily
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 regardless of the current state of Rawhide.
Want to help? Learn how to contribute to Fedora Docs ›