simplify snapshot versioning guidelines #1570
Labels
No labels
announce
bootstrap
Closed As
accepted
Closed As
duplicate
Closed As
exceptionexpired
Closed As
fixed
Closed As
invalid
Closed As
nothingtodo
Closed As
permanentexception
Closed As
rejected
Closed As
temporaryexception
Closed As
wontfix
cmake
committee
draftneeded
hasdraft
meeting
meson
needinfo
Priority
In Committee
Priority
Needs Review
Priority
Waiting For Reporter
rust
writeup
No milestone
No project
No assignees
8 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
packaging/guidelines#1570
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Today during the FPC meeting, we talked about the snapshot versioning guidelines. We believe these are too complicated and have contributed to packagers doing snapshots incorrectly and breaking upgrade paths. This conversation was triggered by a recent example, but it has happened many times before as well. We currently have six different allowed snapshot formats to indicate the snapshot info in the version.
<date>.<revision><date><scm><revision><number>.<revision><number>.<scm><revision><scm><date>.<revision><scm><number>.<revision>To make it easier for packagers to do the right thing, we generally agreed that we should standardize on one format, and indicate that doing anything else is deprecated and should be replaced. Two main candidates were discussed during the meeting. Below are some of the aspects of these brought up during the meeting.
<scm><date>.<revision><scm>is of questionable usefulness. It isn't necessary for the upgrade path, and if it changes (i.e. an upstream migrating from one scm to another) the upgrade path could be incorrect (e.g. moving from svn to git, but0^svn...sorts later than0^git...).<date>is problematic because it has previously been used for author date, commit date, and date the snapshot was obtained. There is little consensus among packagers on which one is best. Our currently guidelines say it should be the "last modification of the source code", which could be interpreted as either of the first two. We could clarify but it will still be confusing due to existing packager expectations.<date>is also problematic because the format specified in the guidelines (YYYYMMDD) only allows for one snapshot per day. It was suggested that we could expand the format to include the hour (YYYYMMDDHH), but that could lead to upgrade path problems if a packagers tries to switch back to the first format, misunderstanding that it is evaluated as a date when it's actually evaluated as an integer.<number>.<revision>We ran out of time during the meeting, so I'm opening this issue to continue the conversation and hopefully reach consensus on one format.
We could also use
<date><scm>.<revision>, which makes SCM not the leading sorting candidate. I do think commit date is actually useful, the other potential sources for date are not.If we have
<number>, we would explicitly want to define what this is. I've seen it used a few different ways.I will also note that this information encoded in the Version string can be helpful and useful for security analysis tools, so having a reliable structure that gives the right hints to tools, users, packagers, and sorts predictably is valuable for that reason.
Agreed. I've treated it as a simple integer, starting at 1 for the first snapshot, and each subsequent snapshot incrementing it by one. I think this is the most common way to use it, but it's worth spelling out explicitly.
Security scanners are such an inconsistent mess I don't think it's worth trying to cater to them. Many (most?) don't even work correctly with RHEL, which provides security metadata in multiple formats for them to consume. Are there even scanners that advertise compatibility with Fedora? Or more to the point, are there any that claim to check for a snapshot date anywhere? Trying to encode the snapshot date in the version aspirationally in hopes they'll rely on it in the future doesn't make sense to me.
At the peril of introducing a third option here, personally, I think something like
<serial>.<scm><revision>would be clearest and easiest to understand:<serial>is incremented +1 every time a new snapshot is taken, starting at0<scm>, despite almost always beinggitin practice these days, makes it clear that the hexcode that follows is a "shortcommit" (or the serial number for some other SCMs), and it also prevents it from being interpreted as a number by RPM in case it's all hexdigits <a (this should not matter with the serial number incrementing at the front, but better be safe?).<revision>identifies which ... revision from that version control system is used.Personally I don't really think
<date>is very useful, but I agree that "date when the specified revision was committed" is most useful (compared to "when was this downloaded" or whatever other things people have been doing).Maybe
<serial>(.<date>)?.<scm><revision>, with<date>being optional, could make sense? I know, that could be viewed as two blessed formats, but I'd argue it's one format with an optional component for people who want (or don't want) to include a date 🤭Separate question: Do we want to keep using
.as separator here? Or use+instead, since it has the same meaning (separator without sorting implications) but isn't used in other places?@decathorpe wrote in #1570 (comment):
I am okay with this format, but I'd swap date and serial, so:
<commitdate>(.<serial>)?.<scm><revision>. I am okay with either order.I'd move the separator so that the revision hash is cleanly separated. Makes it easier to parse. But I'm not married to it.
I think we could use
+after<serial>, since it would provide an additional hint even if it has no sorting value.The benefit of moving the incrementing number to the front would be that the date is no longer needed to increment strictly monotonically for sorting.
I'm inclined to codify
<commitdate>(.<serial>)?.<scm><revision>. Only use.<serial>if there is a next update within the same<commitdate>, to sort0^20260922.gitcaffe123 < 0^20260922.1.git42897528 < 0^20260922.2.gitab123aa < 0^20260923.gitfb597ac5.I think the
<scm>part makes sense, because revisions can be numbers-only (even in git), sogit42897528clearly says this is not a number, but a hash. Also0^20260922.git42897528 < 0^20260922.1.gitcaffe123but0^20260922.42897528 > 0^20260922.1.caffe12. And we don't want special rules for digits-only hashes. We want one format, so the less optional parts the better.I think using
+as separator over.only makes this more complex for no big benefit. It might please some packaging nerds like us, but only confuse people who are already struggling with this.While AFAIK it is technically possible to have later commits with sooner commit dates, this is less likely to happen than with author dates. Codifying commit date for git makes sense.
Remember, the core problem we're trying to solve is that the current guidelines are so complicated that maintainers are having trouble doing them correctly. I think we need to make things more simple to solve this problem. Things that are not simple:
+It may convey that to a human, but rpm still treats it as sorting characters so it's not truly clear. To make matters worse, rpm does implicit separators between continuous segments (i.e. consecutive letters or consecutive numbers), so letter characters at the start of the hash will be treated as a continuous segment with the scm characters and used for sorting. That means
git1234567becomes('git', '1234567'), butgitab34567becomes('gitab', '34567'), and a comparison with everything else equal will be betweengitandgitab. Best case scenario is that is never factored in because everything before the hash is done correctly, but it's an additional wrinkle that worries me.This is relying on the fact that rpm sorts numbers as newer than letters. In the first example
gitis being compared to1, not20260922being compared to20260922.1like one might assume. Relying on maintainers understanding this nuance worries me as well.The regex-like format I posted above was purely for discussion, not intended to end up in a guidelines document - though maybe it should? Providing a regex that users can check their stuff against might be better than pages and pages of documentation ...
If we really want to make it KISS then I think
<number>.<scm>.<revision>should do it (added.between scm and revision to avoid the weird RPM segmentation fault).<number>.<scm>.<revision>is workable, or even better drop the<scm>to have just<number>.<revision>. The snapshot format must accomplish two things:The SCM used upstream is not necessary for either of these. Besides, these days it will almost always be git, and even when it isn't, it doesn't matter for either of the two goals.
I like the format with the date as the main sorting value and an optional additional value that @ngompa and @churchyard proposed. I'm fine with excluding the SCM name if that's considered redundant. I don't like having to invent an additional counter value in EVR when we can just use the commit date from upstream. Also, for packages that don't use
%autorelease, having to increment two different Fedora-specific counter values is confusing for packagers. I'm wondering if that's what led to the issue that started this discussion, since the Release value was bumped from1to2, but the snapshot counter value in Version (also1) was not.I'd like to propose a compromise: we allow exactly one format,
<number>.<revision>, but<number>is explicitly allowed to be either a simple integer or the date in YYYYMMDD format (technically also an integer, but resembling a date). This is a bit of a merge of the existing allowed formats<number>.<revision>and<date>.<revision>, but acknowledges that rpm doesn't actually understands dates and treats the this field as a number regardless. This enables packagers to do multiple snapshots in a day with the simple incrementing number, or give up that ability to have the number look like a date. Adding additional segments (numbers or<scm>) would not be allowed due to the multiple ways mentioned above how that can go wrong.For a real life example, the bluez package using the current snapshot commit would be allowed to be either of the following at the maintainers discretion:
bluez-5.87^1.b5ed56dbluez-5.87^20260918.b5ed56dOnce you use a date, how do you bump to a new commit from the same date?
You normally wouldn't. If you want that ability then you would need to stick with a simple incrementing integer instead of a date (which is the reason I prefer that). If you do choose to use a date but change your mind later (for multiple snapshots in a day or otherwise) you have epoch as a fallback option. That's why I called this a compromise. Reducing the flexibility is necessary in order to make this as simple and reliable as possible.
Well, allowing both dates and incrementing integers is also a form of additional complexity. I don't think we should have a Versioning system that is inflexible enough that it requires bumping Epoch in a case like this. It's impossible to know for sure in advance whether you'll end up needing a second commit from the same day.
No, it's not additional complexity, because it's still just an integer. And it doesn't require using an epoch if you stick with the simple incrementing integer and don't try to force it to look like a date. I'm trying to offer a compromise that explicitly allows folks to use an integer that resembles a date stamp if they want, without allowing additional segments that actually increase complexity and can go wrong in multiple ways.
I guess we could further compromise and explicitly allow the integer to be YYYYMMDD or YYYYMMDDHH, as long as it never decreases without bumping something the left (base version or epoch). That would allow multiple snapshots in a day, just not multiple snapshots in an hour. With the previous example, that would allow:
bluez-5.87^1.b5ed56dbluez-5.87^20260918.b5ed56dbluez-5.87^2026091812.b5ed56d(I made up an hour because I can't actually find this commit in bluez upstream)Would that be acceptable?
It adds complexity because it's still another a format that we have to document even if it's technically still a single integer. I'm not a huge fan of using another counter for version sorting that is completely detached from upstream development (unlike the
<version>and<revision>parts which correspond to git metadata), but if you prefer your format with the counter, I'm alright with having just these two formats instead of the seven different ones we have now.Why not separate the YYMMDD part from the HH (
bluez-5.87^20260918.12.b5ed56d) to avoid the need to bump the base version or epoch when you want to bump the date but remove the hour? I guess it doesn't follow your single integer that's either a counter or a YYMMDD model to have another part in the version, but it would prevent this pitfall, no?I'm really struggling to see how restricting the format to
<number>.<revision>is adding complexity, but at least we agree that it would be less complex than the current guidelines.Because that will lead to comparisons between the HH and the revision, because rpm compares segments left to right. The example above would not sort correctly if the revision started with a higher number.
I want to strictly stick with
<number>.<revision>(regardless of whether number resembles a date) to guarantee proper sorting from the number so we can ignore how rpm segments and orders the revision. That's how we make this robust enough to reduce human error.Sorry, I meant it adds complexity if we allow both
<date>.<revision>and<counter number>.<reversion>instead of only allowing<date>.<revision>. But yes, any simplification from the status quo is definitely valuable.To prevent the sorting issue you brought up, what about using a tilde to separate the
<revision>part instead of a dot?It's a number that is primarily used for sorting. That is not complex. The only thing adding complexity to it is the insistence on explicitly allowing that number to resemble a date (which I don't think is a big deal and why I'm happy to compromise on that aspect).
That doesn't make logical sense. Tilde is used to sort a component earlier than a non-tilde component. Your example is saying that
20260918~25ed56dmust sort before20260918, which would never be used. Tilde is already used for sorting pre-releases. Introducing a second use for it is actually adding more complexity. Additionally, it's possible to have a snapshot that is after a pre-release but before a final release, which would mean a version field with two tildes in it. Please no.Maybe we can compromise on
<number>.<revision>and just say that "number must go up on change" and recommend using an incrementing counter that starts at 1? That way people who really like the YYYYMMDD date format can theoretically use it as the<number>part but it wouldn't be the documented recommendation.We discussed this at length in today's FPC meeting. We thought we reached a conclusion of approval for
<number>.<revision>with (+2, 2, -1), but after the meeting we realized that we calculated wrong and the vote majority is based on the total members, not just members present (per FESCo voting rules, which we follow as a subcommittee of FESCo). We'll need to re-vote here in this issue, or at the next meeting if we still don't have enough votes by that time.PROPOSAL: Snapshot version guidelines allow exactly one format,
<number>.<revision>.<number>MUST be an incrementing integer.<number>MAY resemble a date formatted as YYYYMMDD or YYYYMMDDHH.@packaging/Committee Please vote on this proposal.
+1
+1
+1
-1
(I'd change it to +1 if we had either "snap"/"rev" or
<scm>somewhere to make it more obvious it's a snapshot release.)The first line of the snapshot guidelines states that snapshots "must contain a snapshot information field after a caret (^)." The caret is already the indicator that it's a snapshot, so I don't think an additional indicator is necessary.
+1
@carlwgeorge wrote in #1570 (comment):
It is not in itself an indicator, because we also use it for postreleases (like 1.0-post1 in the Java and Python world). All
^does is indicate that it is intended to sort higher.Nope, post releases are supposed to use a period, not a caret.
-1
I think the argument against not using
<number>.<scm>(.)<revision>is weak and I would prefer having the snapshot identifier begit123abcd(orgit.123abcd, if we need a separator between them for some reason) than just123abcd. Hex-encoded hash values can "randomly" look like they have meaning (all letters, all numbers - or even a sequence of numbers that accidentally looks like a date!), so prefixing them with "git", "svn", or "hg" makes it clear that what follows is a (truncated) hex hash that refers to a VCS revision.+1 for number.revision - in practice the SCM is going to be Git most of the time anyway. If we think it might be ambiguous - maybe allow a more explicit declaration that what follows the number is a revision, but I'd be more inclined to require a standard marker instead of git / hg etc. in that case e.g. ${number}.[rev.]${commitid} (the rev. being optional for those who want to disambiguate)
(This came up in Matrix - I expect that the number only being required to be monotonically increasing integer - maybe we should state that it does not have to be sequential, to be clear, and that the YYYYMMDD[HH] is an option but there are other options - but my preferred way of using number these days is counting the number of commits after the tag. I don't feel too strongly about having it listed as an example usage though)
I take back all my criticism of the suggested format, everything is better than
conmon-v3-3.0.0~dev-4.20260916094957753737.main.58.gba34e8.fc46- +1 to<number>.<revision>and yeeting everything else into the sun, please.So, that would become
conmon-v3-3.0.0~58.gba34e8-1.fc46? (That conveniently sorts greater than the thing you pasted.)Snapshot notation requires a caret. It has been suggested in previous meetings to replace the caret with a tilde for pre-release snapshots, but that can have sorting problems (e.g.
1.0~1.a1b2c3d>1.0~beta.1). What does work in every scenario I can think of is using both for pre-release snapshots (e.g.1.0~^1.a1b2c3d<1.0~beta.1).In this particular case, the upstream has a
v3.0.0-devtag, so I think it should beconmon-v3-3.0.0~dev^1.ba34e85.fc46(which also sorts higher), which the guidelines refer to as a "post-prerelease" snapshot.I see. Well, it's not perfect either. +1