-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[QUESTION] semver: Why is "+build" information ignored when "-pre" information is allowed #1479
Comments
(Not sure what you mean by "allowed". Do you mean displayed in the "versions" listed on npmjs.org, or what gets added to In Semantic versioning, pre-release versions are included in version precedence and have a lower precedence than the associated normal version. So In Semantic versioning, the build metadata is ignored when determining version precedence, so the expression https://semver.org/#spec-item-10
|
What @shadowspawn said is 100% accurate. The reason that npm drops build info from SemVer versions and ranges is that it's not relevant for the purpose of dependency resolution. (Ie, |
Thanks for the thorough explanation and it makes sense. I guess the issue is not related to NPM but rather related to the use-cases for semver to begin with. As identified, it's actually quite common for large, mass-consumed projects to rely on build information as important information. As a result, projects which -- properly -- ignore this information inadvertently and indirectly encourage abuse of the pre-release area for distinction. That's not an argument against, nor the fault of, nor can be fixed by NPM, but I don't see this problem going away. Perhaps as a compromise, projects that knowingly expect non-patch-level changes (e.g. |
Sequencing in this ecosystem is defined by the |
I tend to think just because it isn't used for determining precedence does not mean it should be removed altogether. It is still valid semver and removes valid information about the package's origins, which can be helpful. |
Yes, I find it extremely frustrating and un-intuitive that |
@drs9222 @solarmosaic-kflorence Can you elaborate on specifically what you'd like to use this build metadata for?
What need was frustrated? What intuition was violated? What do you attempt to do, and then find yourself blocked by npm stripping off build metadata? Where did you expect to see build metadata, and find it lacking? Just to be super clear:
For this reason, the simplest approach is to just strip it from published versions, lockfiles, and the like. We have a name, semver, and sha512 integrity value, which uniquely addresses and identifies any npm artifact. If there's some utility we're missing in that approach, and we can provide it somehow (in a way that doesn't break older versions of npm, of course), then that's worth exploring. But the important thing is to identify the goal first, and then work towards a feasible implementation. |
The goal is to permanently attach meta data to the version string for whatever purpose your customers deem necessary. They should not have to justify those reasons to you. The build meta tag is part of the SemVer 2 specification. The fact that it's not needed for sorting is not relevant to the discussion of whether the tag should persist. You don't need to strip it from the version string to ignore it for sorting. |
I agree with @jwdonahue -- the point is, it is part of semver for a reason, and people use it for a reason. NPM forcefully modifying my valid semver is frustrating and unintuitive because I would not expect NPM to be modifying a valid semver at all. In fact, in my opinion this means that NPM does not support the entire semver spec, only a subset. I can appreciate that NPM wants to internally ignore the build metadata on the semver for reasons, but honestly I should not have to even know about that. |
Doesn't npm follow https://semver.org/spec/v1.0.0.html, since that's all that existed when npm started? |
Even if that's the case, 2.0.0 has been out since 2013, which is quite a long time ago. Also, FWIW, https://github.com/npm/node-semver supports |
See also npm/node-semver#264 |
Node-semver implements the semver 2.0 specification, and has since semver 2.0's formalization. (In fact, as I was involved with the process of finalizing semver 2.0 and ironing out a lot of the ambiguities in semver 1.0, node-semver was one of the first implementations to do so, shipping support for semver 2.0 slightly before semver 2.0 was formally published.)
Look, I'm not saying it's somehow "bad" or that you have to "answer" for your use of build metadata or whatever. But you're asking for the npm cli and registry to change something that is extremely load bearing, which will be time consuming and risky to implement, and may cause disruption in other parts of the ecosystem, inconveniencing or even harming other members of our community. When asked "what for?", if your best answer is "I have my reasons!", well... sorry, that's a In fact, I'm not even sure which example of semver build metadata stripping is actually bothering you. We So I know it might seem like I'm being obstinate here, but since (a) the semver specifically explicitly states that two versions that differ only in build metadata have the same precedence, and (b) the npm registry guarantees that there can only ever be a single published artifact of a given name/version combination, and (c) the npm cli's primary use of semver strings is comparing them against dependency ranges, the simplest and most effective way to calculate dependency graphs that correctly satisfy the dependency contract is to ignore build metadata entirely. And the best way to ensure that we're always ignoring it, is to strip it off any time we canonicalize a version string for comparison, or any time we store it someplace where it will be used for comparison. Just to grab one arbitrary example, right now, let's say you publish a package with Currently, we do this by normalizing the version number, and putting the manifest in an object at Because, if you do I'm not playing dumb or being difficult when I say that I literally don't know where you're asking us to "stop stripping the build metadata". We strip it everywhere, and we always assume that it will have been stripped. So, I'm sorry, yes, you really will have to spell out exactly what you're trying to do, where you expect build metadata to be included that it isn't, and provide some justification for including it, some use case that would warrant doing this work. If you want to put build metadata in your package.json, that's fine. You can also include it in your git tags, and anywhere else. npm just won't do anything with it, and the easiest way to ensure we don't accidentally start doing something with it is to not include it in npm's data model at all. Show me something you want to do today but can't because build metadata is stripped somewhere, and we'll do what we can to empower you if it's at all feasible. |
I am working on CI/CD pipelines at our company. Our standard practice is to generate pre-release builds off pull request branches that look like: This pattern worked great everywhere until I tried to apply it to NPM (and, to be fair, later Docker which also does not support I get that NPM implemented an internal solution to resolving versions that doesn't take build metadata into account at all and hence it would be a big lift to support it. I'm just telling you as an end user that the current behavior is confusing and frustrating from an end user perspective and I would like to be able to retain the metadata in my build versions. I'm also a little frustrated that the response has been to seemingly shut down the conversation rather than just acknowledging it would be a nice feature to have that may not be prioritized quickly due to the complexity in implementing it. EDIT: after typing all of this up and re-reading this entire thread, I don't really see how pointing out specifically how we use the metadata information really adds a lot to this conversation, as everyone has pretty much already answered the basic points about why the metadata is useful to exist in the build version in the first place. There are of course workarounds, but we now have to do those just for NPM and not for other parts of our infrastructure. |
Another use is to embed the build machine name or version of the build environment in the meta tag so that test labs can pull prerelease versions that match specific meta tags for testing. In environments where cloud processes are not allowed to write back to the repo, it provides a way to append information that may be needed for correlation with reported bugs. I have used them to do A/B testing of products produced by different tool chains or versions thereof. |
Actually this helps a lot. Because we strip build metadata from hundreds of different places, but in order to consider retaining it, or even to know what you're actually asking for, I'd have to know which instances of stripping the metadata is getting in your way. In this case, it's the difference between "oh, that's easy" and "that is beyond impossible". We could pretty easily make Would it satisfy your needs to have |
Just to clarify: there are layers here. The version number is found in 4 main places in the package document that might interest you:
(1) and (3) are high risk to change. I could see us (or another registry implementation) quite easily mixing that up, and ending up with multiple (2) is somewhat flexible, but I would be on the lookout for a client relying implicitly on the fact that (4) is completely arbitrary (and in fact, those dist.tarball urls are not and have never been guaranteed, and some registry implementations serve them from completely different sorts of urls). I'd be somewhat on the lookout for issues stemming from There's also the possibility (lowest risk, not sure if it meets your needs, though) of adding that data to a different field in the |
As the OP, I can state that my use-case violates semver specification and falls into My use-case is pretty simple:
I use other SemVer libraries and they behave the same way as NPM; comparing build information is non-standard and for that reason, ignored by default. In my case, my issue is that I'm not using SemVer properly. I'm using the |
There’s also the “versions” key in the packument? Unless that’s derived from the time key. |
@ljharb If you're referring to |
Oh, 😂 sorry, I completely missed that you said you don't care about the published impact. So, yeah, this is a thing that can be done. Maybe my npm registry braindump above will serve future discussions ;) |
@isaacs that is correct, for this particular use-case just preserving the build metadata in the |
@solarmosaic-kflorence If the build metadata is just the git commit, you can also refer to the |
What / Why
NPM ignores
+<build>
information to represent detailed build release information. Why?An archived bug report asking a similar question: npm-version disregards build metadata npm#12825
A near-identical question is asked on stackoverflow: https://stackoverflow.com/q/29972999/3196753
The accepted answer states the following:
However, if that's the case, why is prerelease allowed? Looking at larger projects, it's common to use
+<build>
to represent build information.Popular software with
+<build>
information:13.0.2+8
11.0.7+10
11.0.6+8
Quoting why minus shouldn't be used (semver.org):
Oddly, it appears that improper use of this hyphen has become contagious... for example, Visual Studio Code shows the following in the About dialog:
7.8.279.23-electron.0
... (is
-electron.0
a pre-release version of Electron, or should this be+electron.0
)I believe there's a valid use-case for
+<build>
information and that ignoring it forces odd workarounds, such as using pre-release prefixes when they're invalid.Where
The text was updated successfully, but these errors were encountered: