-
Notifications
You must be signed in to change notification settings - Fork 694
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
Nightly builds not supported #200
Comments
Build metadata is part of the specification. If you look at version 2.0.0 of the spec [ http://semver.org/spec/v2.0.0.html ], build metadata is added to a version number with a plus sign. So your version number for "dev" would be |
FYI, that's from item 10 in the spec. Important to note, from the spec: " |
Thanks, but I would not consider this meta data. Specifically, the semver spec says that metadata cannot be considered when deciding precedence, thus the nightly version (e.g. Really, I think development build tags deserve their own field, distinct from both meta-data and pre-release identifiers. In the above example, a package manager which relies on semver would be unable to update from a released version to a nightly version. While this may be desirable in many cases (since most users will not want to update to development versions), forcing it to be the case defeats the purpose of having development versions, if no one can install them. On the other hand, if the package manager could identify that the nightly version is more recent than the released version, but that it is in fact a development version, it could provide the user with an option of whether or not they want to install development versions (like being on the firefox beta or aurora channels). My vote/recommendation for a future version of semver would be to use a different separator for these "post release" identifiers. For instance, instead of just a hyphen, a hyphen followed by a star. Since a star is not part of a valid identifier in the semver spec, there should not be any ambiguity. The question is how existing semver parsers would (and should) handle such a construct. |
It seems like you're looking for the solution to a very specific problem. What I would consider is using the actual version number to signify newer "nightly build" versions. So, in the case that you've released version |
A lot of the issues I see regarding specialized parsing--as with the meta data--seem to revolve around some want/need to avoid updating the version, and I personally think it's just fine to have frequent changes to the PATCH component. Releasing |
I just wanna hop in quickly to discourage from using |
@FichteFoll - agreed, I realized my mistake but got distracted before I could fix. Thanks for the clarification. :) |
Anyway, to get back to the actual discussion.
Actually, it "SHOULD" not be considered. In my implementation of semver I do consider build metadata when deciding precedence - mainly because this clause didn't exist in 2.0.0-rc.2 - and I'm thinking about keeping it that way for internal reasons and this one here. So, a good example for allowing this kind of "higher than x" versioning is the usage of gitflow. You don't know the release version until you create the release branch and thus depend on the current develop branch or an arbitrarily increased patch version. The most logical step would be to increase on the current version instead of decreasing on a potential future version. So, I can think of two options here:
Edit: Phrasing. |
I disagree that this is a "very specific problem". Nightly and other development builds are extremely common practice. I'm thinking hard about your suggestion to simply bump the patch number for development builds. On the face of it it seems reasonable, but there's some nagging me about it that I can't quite put my finger on. |
Ah, I figured out what is nagging me about using the patch version for development builds: development builds do not necessarily keep the interface intact. For instance, say I'm starting with version Before my next release, I decide that I don't want that function after all, and remove it. I now have to release as It may sound contrived, but in my experience, a fast paced development environment frequently leads to temporary changes to the API as part of the development cycle and as far as I can tell, semver is incompatible with this increasingly common type of development. |
At my company we take "SHOULD NOT" to mean that we may, if we so choose, consider build meta data for version precedence. To this end, we use it in a similar manner to that which @mearns suggests - that is, 1.0.0+foo will always have higher precedence than 1.0.0. Likewise, 1.0.0+build.24 will have a higher precedence that 1.0.0+build.3. |
@damianpowell |
@FichteFoll raises an interesting point, but those points should be tempered by the light @damianpowell and @mearns brings: encouraging use of nightly builds makes the the build information non-trivial to the process of determining which part of the version string to increment, especially in the instance where a nightly build can introduce temporary breaking changes that are later discarded. These are all interesting points. I've been pretty "religious" about updating minor versions (in a 0.x version environment) in the situation that a break in the API has been introduced, even though it is later disregarded (which leads to another version bump). In a post-1.0 versioned environment, I can see how such a scheme would easily lead to lots of major version bumps--in my pre-1.0 world, 0.1.0 and 0.2.0 are roughly equivalent in nature to 1.0.0 and 2.0.0. I'll be watching this one closely, as much of my public libraries are close to or already breached the 1.0 mark. |
The failure here it seems, is you are trying to force a automated build versioning scheme independent of the semantics of SemVer, and then force it onto SemVer. (as with a lot of other issues recorded here). IMO, your automated build should either automatically verify the public API changeset, then appropriately increment the version, or accept an input that tells you of major/minor/patch increment. You cannot safely determine the next version of a public API before making the changes, and false attempts to do so will only lead to heartache. |
@EddieGarmon You're absolutely right, though: the problem is that we want some additional semantics which SemVer does not provide. Hence opening an issue to request it. My point is that the semantics encapsulated in semver are too limited to support a very common development style, which will restrict adoption of semver. The idea of "extra" versioning information is already present in semver via the pre-release identifiers. All I'm looking for is a similar allowance for "post-release" identifiers to work with development builds, so that semver can be more widely used. |
There are only ever two kinds of "releases", official - should never change, and "pre" meaning this might be the next step forward. In development, you are always exploring the next possible step forward, aka you are always working on the next 'pre' release. SemVer support these two scenarios perfectly, and if you would shift your thinking from 'I'm building after X', to 'I'm working on the next Y' (using prerelease) then there is no need for what you are asking. What is missing, in general, are the tools to help all developers properly (and automatically) determine the appropriate and correct version at build time. |
@EddieGarmon Until you are ready to set in stone exactly what changes are going to be included in the next release, the only sane option is to mark your versions as "post-X", not "pre-Y". |
@mearns Assume I am working on a project that strictly adheres to the current SemVer spec. Today we publish a release the official 1.2.3 build. (Yay!!) Then tomorrow I get a request to make a feature change. Great, time to get to work. So, do I start by setting the version, absolutely not. I get to work and solve the problem. Once I am done, then I inspect the public API delta and let that tell me the next version number to use. It could be any of the following: 1.2.4-dev.1, 1.3.0-dev.1, or 2.0.0-dev.1. (where 'dev' is my current prerelease designation, and the 1 is the next sequential number of currently published builds with the same version and prerelease designation). When I am ready to publish this prerelease package, its version is set for me, all I have to do is tag the generated version in git. If I have a consumer that wants the latest bits, they get the newest bits by specifying the version range of interest and that they want prereleases included. How does it work in my local development? I always use version 0.0.0 in code as a placeholder. DevEnv builds and UnitTests work fine this way. Only when I execute a 'Publish' task in my build scripts do I swap out the 0.0.0 for the contents of a file like semver.txt Again, the spec as written supports your scenario, but it appears that your tools do not. Don't change the spec, build the right tools. |
It has nothing to do with tools. Development builds could just as well be built manually. Continuing with your scenario, lets your change was to add a function to the public interface, you did created version 1.3.0-dev.1. What do you do when management decides they don't want this feature after all. You remove it, and what do you set the version to? To adhere to semver, you need to mark the version number as 2.0.0 (or 2.0.0-dev.1, for instance), because you removed something from the public API. If you mark it as 1.4.0, for instance, then any one who was getting a jump start and coding against the 1.3.0 dev release will justifiably assume that their code is compatible with 1.4.0, but it's not, because you removed that new API function that they were so excited about. So as far as I can tell, you have no choice within semver but to bump the major version number. My argument is that this is garbage. Version 2.0.0 and version 1.2.3 have the exact same public interface, but you had to bump the major version number because semver doesn't account for this properly. Bumping the major version sucks because now everyone has to assume that none of their existing code is compatible with your new version: their existing plugins, clients, add-ons, or whatever, are all going to stop working, even though they actually are compatible, and the only reason they've been marked incompatible is because semver doesn't support this increasingly common development style. |
@mearns, I think your problem is not the problem SemVer is trying to solve. If you carefully read the introduction part of the specification you'll see that the main problem addressed by SemVer is the "dependency hell", and it's more about backward compatibility of APIs than anything else. What could help you, though, is a different approach to the development process and/or release management. Try a workflow similar to A successful Git branching model. A few points to note:
Hope this helps. |
Dependency hell can only ever be addressed suitably if a sufficient number of people follow a standard which properly addresses it. Bottom line, it's no skin off my nose if semver doesn't work for me, I just won't use it. What I'm trying to point out is that I am not the only one who will run into these kinds of problems: there are lots of other individuals and teams who work in a similar way, or perhaps in a different manner which semver doesn't support because it is too restrictive. At the end of the day if the maintainer(s) of semver want it to address a problem, it needs to be widely adopted, and it will not be widely adopted if people cannot make it work for them. Yes, I could try a particular work flow, but I'm not going to unless I have a compelling reason to, and compliance with semver is not compelling enough. And is this really what we want as a programming community? Everybody using the same workflow? We all benefit when people and teams work in the way that is most comfortable for them, and when people do things in different ways. Diversity pushes the field to new places. To your point about development builds not being public releases: this is another assumption based on the way you may be used to developing. In many open projects (firefox, for instance), nightly builds are publicly available. Even if it were the case that development builds are not public, bringing this up misses the broader picture. Logical, semantic version identifiers can be just as beneficial inside an organization as outside. As far as I as a developer am concerned, any time the code leaves my computer it's "released", even if it isn't to the general public. Why shouldn't my QA team get the same benefits from semantic versioning as the general public? Why shouldn't my entire organization be able to use a consistent versioning scheme throughout the entire lifecycle of the product? The way we currently work (in my team, that is), we do this, and it's great. The QA team can automatically decide which tests to run based on the version because they can tell how it effected the API. They can unambiguously tell me what version a bug was discovered in, and I can always find the version in my revision control system. As goes for public releases, so goes for internal releases. The only issue (and it's not an issue for us) is that our versions aren't compliant with semver. |
@zafarkhaja, your 4. is actually what we are trying to solve here. The problem with these "different" develop builds is that versions with only a different
Thus, you may be able to create multiple builds whose string values but you wouldn't know which one is newer because they have the same precedence. I already made two proposals above and I still think that these are the best options so far (slightly rephrased):
I definitely favor the first one because it would be official and something you can rely on - assuming the corresponding version of the semver spec is supported. |
@FichteFoll Your suggestion also has a nice symmetry: the '-' ("minus") is used to indicate "pre-release" identifiers, and the '+' ("plus") is used for "post-release". It's like it was meant to be, except apparently it wasn't because it isn't how the standard is written. |
You can not compare this to FireFox's release schema because they are using a fixed versioning system that is not really compatible with semver (increase major every 6 weeks). However, since they already know what version their next release is going to have they can freely declare their nightly releases as pre-releases and signal that with a semver-compliant pre-release specifier (e.g. |
Ah, but isn't that my whole point? Semver is incompatible with the development process of a major open source project. They're using a different version system in part because semver is incompatible with the way they work. When you say their version specifier is semver compliant, you're kind of blurring the concept of compliant. It will parse as a valid semver, but it is not semantically correct for a semver because it does not correlate with the public interface. |
Yes, you are right about that. I just wanted to point out that their release schema allowed them to use these many kinds of pre-release builds that semver would likely not. |
Does the public API for Firefox introduce backwards-incompatible changes every six weeks, or are they simply using the major version number as a way of bringing more focus to the fact that there's been an update? I would imagine it is the latter, not the former, therefore making Firefox a poor example (or a good example of poor versioning), though I'll admit I haven't looked at the actual change logs to verify this assumption. |
I've never reviewed firefox releases in enough detail to know whether or not their public API changes with every release. As far as I know, the only semantics behind their version number is "this is our new major release". My point was not that firefox is using version numbers in a better way, or even in a good way. My point was simply that this is a very popular and very large open source project whose development and release process is incompatible with semver due to the publicly released nightly builds. So if they ever decided that they wanted to use semver, they would not be able to (at least not without drastically changing the way they work, which in my opinion is not the point of a standard like semver). |
In the case of a large open source project, or most large projects, there are planned changes. Those changes are known ahead of time, and the general impact to the product's API are fairly well known, so the nightly builds can quite easily be geared toward that. We've been going round and round on it, but it seems like the major misunderstanding is in the document around the word "SHOULD," which is just a recommendation. Allowing build meta data to establish precedence on an otherwise identical version string seems perfectly acceptable to me. I would suggest that we basically go with the change suggested by @FichteFoll. Basically just clarify the statement in item 11 of the spec, indicating that build meta data MAY be used for precedence in a development environment or in the case of nightly builds. Does this solve the problem? |
@alexandrtovmach I don't get the "consensus" idea here. About what?
|
@alexandrtovmach I think there is some consensus forming towards "if you really need nightly builds to use SemVer, then if there are no actual guarantees about what the public API is, use a But you will never have overwhelming consensus while SemVer remains dominantly popular, because there are always going to be people who want to shove more features into something, and other people who will assert that those features are unnecessary and symptoms of doing or wanting something else wrongly. One of the biggest challenges and responsibilities of a maintainer is knowing when to say no to features despite diligently and compassionately considering the desires and reasons for them, and even as users are actively asking for them. Because with a popular project, you'll be getting a lot of people wanting things just because it solves the problem they have as they have conceptualized it. But I do encourage anyone still looking for a solution to SemVer with nightly builds and not satisfied with anything else said here to ask themselves if anything I said in this comment I just made on another issue would address that. |
I also have the impression that "pre-release of the next patch version" seems to be the way that's most suggested and accepted here. I'm using that practice for a while now and so far it looks successful. From my previous comment, I'd have one suggestion to that to make it less dangerous:
As an addition to my earlier statement, I found the metadata to be useful to keep the Git commit hash directly in the version identifier. That makes it easier to find the code that's running if it's not directly tagged as a release. My versioning tool can add the number of commits since the last version tag, but having the commit hash is easier than counting commits along a branch line. |
Regardless of what is the best currently available workaround, I believe it should be discussed whether this ability should be added to SemVer and if yes, how. I don't think we are at the point in the discussion where we have reached consensus on how to proceed with the proposal. However, reality speaks that there are many systems out there that provide or utilize automated CI builds and that have no common ground for specifying versions for their artifacts and SemVer could step in to fill that void, especially given how popular it is. I would also like to see a usage study of build metadata for considering whether to allow using that for determining precedence again. |
I personally think this is all handled just fine by the spec as is, and doesn't need to be changed. |
I'd like to clarify one more thing
Assume that your latest release is 1.2.0 and it's deployed to production. Then you begin working on 1.2.1-dev or whatever postfix you prefer. You add new features and perhaps even breaking changes. Then a bug is found in production and needs to be patched asap. The sensible version for that bug fix would be 1.2.1. If you deliver that version (obviously from your release branch, including nothing but the bug fix), what happens to your development version number after that? |
@vcorr the next one would be v1.2.2-dev or whatever postfix you prefer. |
@vcorr Version numbers are assigned automatically based on previous version tags up the history. The release branch and the main branch are unrelated and will never be merged, so they don't interact with each other regarding their version numbers. It is the task of the maintainer to assign proper version tags. So if I set the 1.2.1 tag on the release/1.2 branch, that doesn't affect the main branch in any way. It will still see 1.2.0 as its latest version tag and continue to generate 1.2.1-dev numbers. But as is the meaning of a pre-release, none of them can be assumed compatible (or ordered across certain boundaries) with any other pre-release. For example, our versions are built like this: 1.2.1-44-feature-name.5+1a2b3c
Obviously, when you finish work on issue 44 and then continue with issue 38, the version number will appear smaller. But there's no way to change that. This is simply the fate of generated pre-release version numbers in a multi-branch environment. Hence, they must all be assumed incompatible with each other. Only comparisons to release versions or within the same branch are allowed. |
@ygoe "branches" have nothing to do with semver, nor does your individual repository's workflow. You're making a lot of assumptions about tooling that may not even exist for others, and about what this tooling would do for others. Many workflows don't even have a different "release" and "main" branch - there's just the one main branch, from which all releases are done. |
@ljharb Then SemVer does not apply to those workflows or leads to undefined behaviour. It's just not specified. So I could only describe my workflow. |
Totally fine to describe your own workflow! Semver however applies perfectly fine to those workflows, since in many ecosystems, git doesn't contain released artifacts, and an artifact is "published" by pushing to another, separate registry. |
Since you mentioned release artifacts... Assuming you only have one artifact repository for both prod and dev, how do you deal with the situation, where you have 1.2.0 in production, you are working with 1.2.1-dev towards next release and now you need to make a bug fix to prod with 1.2.1? Artefacts repository:
1.2.1-dev.3 would be considered earlier than 1.2.1. For instance Helm charts need to be Semver versioned and if you want to keep your development version open with something like ~1.2 it would now pick up the latest of that, 1.2.1 and not 1.2.1-dev.3 |
@vcorr that's why i'd release it as All prereleases are just throwaways. Once v1.2.2 is out, all prereleases for v1.2.2 are obsolete. In npm, |
What is an artefact repository? Is that a store for released (binary/compiled) bits? Why should this store contain prereleases? After all, if it's released, it's not a prerelease anymore – it's a release. And that must be assigned a public and comparable version. But if you add a hotfix to 1.2.0 and call it 1.2.1, who says that the main development does contain that fix after all? It could be a fix that's only relevant to the state 1.2.0 was in and may be obsolete by other changes for 1.3.0. So the presence of the fix in the 1.2 branch does not necessarily imply that it's "more" than the current main development. And other prereleases may not even contain that fix because they're built from other unfinished work branches that will never see that fix. It's complicated and unless you want to assign versions to each commit/prerelease manually and carefully, you have to use an automatic scheme that cannot consider all parallel developments but only the definitive history of the part to look at. YMMV. |
For node packages, it’s an npm registry. For ruby gems, it’s rubygems.com or similar. Most languages have some sort of location for published artifacts that’s different from the repository, whether it’s a prerelease or not. Git is for development, not distribution. |
As I understand it, everything that's published to these locations has a proper assigned version number. This would be tagged as such in Git so that you know what code belongs to that released thing, because somebody external might refer to such a version. Whether it's called 1.0.0 or 1.2.4 or 1.3.6-rc.2. If it contains a dash you must make sure that those versions have a defined order. You probably wouldn't feed daily unreviewed builds automatically into these places, with branch names and commit counts. |
Not to public repositories, no, but depending on your setup it may be required to push them somewhere in order to automate updating development environments. In the production bug fix scenario above, there are two possibilities, either as @ljharb pointed out, bump the patch version in development, or host a completely separate artifact repository for development. I find the first option quite sufficient. |
This is worth putting in the FAQ if none of the fancier "ordered, unstable post-release" ideas are likely to be accepted. |
@vcorr If you're doing that, the important question is: do you want automatic updates or admins or users to install those nightly builds or not? Regardless of whether or not you have automatic updates, even if you intend to never have them, even if you teach everyone with download or install permissions to never grab those packages - if you upload unvetted builds to the same repository as your vetted builds with a higher version number, you are saying something. If you are using a package system which honors SemVer notions of pre-release versions, then that's fine, because in the semantics of that package system, you can say "this is a version you should ignore, because there are no compatibility guarantees" with either pre-release versions or But in package systems that don't do that, you might be saying "this is the newest version, prefer this one unless you know you want an older one". If you are using a package system you have to speak its language. And that means if you are using it to shove builds into the same update channel as your vetter builds, you have to figure out a way to say "this is not an upgrade" in that package system's language. Otherwise you are lying (in the language of your packaging system). Which might be fine, lying isn't always wrong. You or your team are allowed to decide that a given lie is fine in your case. Just understand it has the same risks and tradeoffs as any other deliberate miscommunication. Drropping the unvetted builds down to But no amount of explicit "nightly" support in SemVer will work around the fact that you'll still have to express "don't update to this!" in the language of your package system, and SemVer can't cover all package systems. For those other package systems, making all your nightlies |
I think the FAQ should also explicitly mention:
Because nightly versioning is often a problem of saying the right thing in the language of your specific package system, not a problem of saying the right thing in the language of SemVer. There is some overlap in saying what nightlies want to say in both languages (SemVer pre-releases if the package system knows not to treat them as upgrades) but for the most part they are just separate. |
closing in favor of #703 (comment) |
Clear ambiguity in French translation
I really like semver except for specification that all strings following the Major.minor.patch version number indicate a pre-release. I feel that this is inconvenient for, if not incompatible with, rapid development environments with development builds (e.g., nightly snapshot builds).
In my team, we do not always know what the version number of the next release will be, because we don't know what kind of changes will be ready for inclusion when it is time to release. We therefore do not bump the version number until the release. Instead, we add a "post-release" suffix to the version string immediately after the release. For instance, we release version 1.0.0, and then add the string "-dev" to the version string, so that until the next release, we are all working with version 1.0.0-dev. Nightly builds will include this suffix on the version string, indicating that it is a development build.
Conceptually, it is very similar to the idea of a pre-release identifier as you've described it, but the important difference is that its precedence is higher than the version number it attaches to. Again, this is because we don't know if the next release is going to 1.0.1 with a critical bug fix the next day, or 1.1.0 with new features sometime next month.
I would love to see semver updated to support such a feature, though I'm not sure how exactly it could be incorporated without breaking backward compatibility. Perhaps this could be worked into semver ver 3.0, unless you have a suggestion for how semver can handle nightly builds.
The text was updated successfully, but these errors were encountered: