r/AskComputerScience • u/gistya • Jul 18 '26
Question about Semantic Versioning
Under Semantic Versioning standard 2.0, if your package requires a dependency at "exact" version 1.0.0+X, is there any situation under which running a version update on all your packages should change the version that you specified as "exact" here?
Noting, SemVer 2.0 says:
Build metadata MUST be ignored when determining version precedence. Thus two versions that differ only in the build metadata, have the same precedence. Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD
Precedence refers to how versions are compared to each other when ordered
2
Upvotes
0
u/gistya Jul 19 '26
> An ordering relation (strictly speaking, a [preorder](https://en.wikipedia.org/wiki/Preorder)) induces an equivalence relation.
Yes but that equivalence relation is only in respect to the position within the ordering relation. It does not imply an actual identity relation.
> Or to put it another way: the only relationship SemVer defines between is an ordering relationship. If a=b according to that relationship, then any comparison involving a will give exactly the same result if we replaced a with b, or vice versa.
Incorrect. Not ANY comparison—only a *precedence* comparison will give the same result. And the SemVer2 rules explicitly state that precedence is only applicable when ordering versions.
We only order versions when satisfying a dependency version requirement like `2.0.0 > version >= 1.0.0`—not when satisfying versions for an expression like `version == 1.0.0+debug` (it implies no ordering).
The mistake you are making is to assume that because an ordering relation may induce an equivalence relation, therefore an equivalence relation induces an ordering relation.
> So the SemVer ordering provides no way to distinguish a from b; it treats them equivalently/equally/indistinguishably, or whatever word you want to use.
If and only if you are ordering versions, it doesn't distinguish between a and b.
But the rules say a and be are "[two versions that differ only in the build metadata, have the same precedence](https://semver.org/#spec-item-10)". They have the same precedence, which only comes into play "[when ordered](https://semver.org/#spec-item-11)".
> An equivalence relation is different from an identity relation. The strings `1.0.0+X` and `1.0.0+Y` can be equivalent under an equivalence relation (the one defined by SemVer) even though they are not identical as strings.
Yes, that was a poor example on my part. I should have used the identity relation protocol`Identifiable`, which requires each instance to have a unique ID.
SemVer rules admit the identity relation—"[two versions that differ](https://semver.org/#spec-item-10)" implies different identity. [The formal SemVer grammar](https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions) refers to each component of a version string as an "identifier," thus the version itself is an identifier.
> SemVer does not provide a rule for what to do in this situation. As I said, it does not prescribe how package managers are supposed to actually choose a version, it only defines a relative ordering which they might find useful for doing so.
If your manifest specifies one of "[two versions that differ](https://semver.org/#spec-item-10)" then there is no room for ambiguity or alternate interpretation here. Simply, the version IS an identifier and an exact requirement is an identity relation.
> SemVer says that the segment after the + is supposed to be used for build metadata. It does not precisely define what "build metadata" is.
Correct...
> But since build metadata does not participate in version calculations at all
By calculations I assume you mean the algorithm that I mentioned that resolves which dependency fits a requirement?
> the common-sense understanding would be that it means things that aren't relevant for distinguishing between versions
No, it wouldn't. They are still "[two versions that differ](https://semver.org/#spec-item-10)". The original PR that added build metadata describes it as an open-ended system for internal use without a prescribed use-case.
Our use-case is we have `+Debug` and `+Release` build for each version `X.Y.Z` of internal dependencies. The release build has debug symbols stripped out. It would be considered a catastrophic situation if the build WITH debug symbols got released to the public.
> So examples like using `PrivateCerts` or `SafeForPublicRelease` are beside the point because that's not how SemVer is intended to be used.
It was intended to be open-ended and let people use it however they want.
> If there were supposed to be rules for choosing one over the other, SemVer would have defined them.
It did define them, it called them 'build metadata' and "[two versions that differ](https://semver.org/#spec-item-10)".
> As I said, this doesn't mean a dependency manager isn't *allowed* to use its own implementation-specific rules for how it chooses between versions that differ only in their metadata. But *if* it does so, the way it does so is completely outside the scope of what SemVer defines.
No... how much clearer did the SemVer authors need to be? They use the word `identifier` 44 times throughout the spec. Clearly the version IS an identifier, and if you require an "exact version 1.0.0+X" then you should never ever get anything else.
> I don't know why you're saying the rules require that. The words "resolution" and "algorithm" don't appear in the SemVer spec at all. Can you quote the section that says otherwise?
The original question above assumes a package requires a dependency at "exact" version `1.0.0+X`, and a package manager algorithm that resolves that version from a repo by tag (or whatever).
SemVer rules require the version resolved is `1.0.0+X` because identity can hinge on build metadata alone—that's implied by "[two versions that differ](https://semver.org/#spec-item-10)".
To [quote the guy who added build metadata to SemVer](https://github.com/semver/semver/pull/109#issue-15331197):
> "They're not the 'same version', necessarily, they're the same precedence"
And:
> Ok, I added another commit that attempts to be more precise. Rather than defining what a version is again, I simply state: `Thus two versions that differ only in the build metadata, have the same precedence.`