-
Notifications
You must be signed in to change notification settings - Fork 690
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
How to deal with minor and patch releases in pre-1.0 releases? #333
Comments
My understanding is that 0.x.y in initial development doesn't really follow those rules. As in item 4 on semver.org, anything may change at any time. So 0.1.1 can have massive differences as compared to 0.1.0; the change in the "patch" version means something changed, but since the project is in the initial development stage, that change may or may not be a breaking change. |
@breerly, believe @crazedsanity has answered your question. If you do not require further clarification, please close this issue at your earliest possible convenience. |
I had the exact same question and stumbled upon this. Looking at the current wording:
There is nothing explicit about what the rules for initial development should be. I think it would be worthwhile to explicitly indicate guidance for what to do when making backwards incompatible changes in early development. For example, is the minor version used for both backwards compatible and backwards incompatible feature changes? Does it not matter whether you update minor or micro in initial development? Is that what is meant by "Anything may change at any time" ? If so, perhaps that could be clarified a bit. |
The fact that the spec sticks with a three-number format for early development has to do with overall coherence. But as the rule you cite says, "anything goes" as far as SemVer is concerned. The If you want to have a more specific rule in place, that does not contradict the spirit of SemVer (i.e. "we use SemVer in our project, with additional rules for the bumping of Personally, I do not mind that part of the specification. However in my practice, I would tend to start exposing my public APIs using prereleases of the |
Thanks for the response @klehelley . That definitely clarifies things. You mentioned the following:
Why is this not appropriate when the major version is 0? If the major version is 0, we can bump either minor or micro at will for any changes regardless of whether they maintain compatibility, correct? In addition, I like your wording of "The |
Sorry I was unclear. The example rule you cite does not say anything about the major version being zero or not. I should have added "for any major version" in that example of what not to do. |
@klehelley Thanks for the clarification. I now understand the intent of the existing documentation, but it wasn't initially clear to me what "Anything may change at any time" meant within the rule. |
I think it would be helpful to shift roles based on 0 versions. That is, the left-most non-zero version is a breaking change, and the next version (if any) adds functionality. A lot of projects already follow that rule, often explicitly, but having it enshrined in Semantic Versioning 2.1.0 would be useful. For instance, 0.0.2 MAY be a breaking change, but 0.2.3 MUST NOT be. |
I think it would be very useful to specify explicitly that it’s either x.y.z, 0.x.y, or 0.0.x, and x is semver-major, y semver-minor, z semver-patch (this is how the npm ecosystem tends to treat it) |
That’s what I had in mind. |
There are probably a dozen tool owners out there that would find it very convenient if they could get the SemVer spec modified to match whatever it is they are already doing. As the spec is currently worded, any So, NPM and a few other's convention of attempting to try and advertise breaking/non-breaking changes in the development phase, is compliant from a SemVer spec perspective, possibly mildly useful, particularly to other devs working features on the same product, but it should not change consumer behavior one iota. That said, if you really want to have full semantic meaning, just use an
If your API is so unstable that you're worried you'll have dozens or more breaking changes before it's done, don't burn your product's marketing name until you have a stable first release. Name your product -prototype. The SemVer spec does not attempt to solve every problem we encounter in our workflows. That's a good thing. Let's not even try to go there. The spec gives us enough wiggle-room, that as engineers we can surely find good solutions, even if it means dropping the spec completely for some phases. Some companies use little more than a build number until they are ready for a product release. |
That’s not quite accurate: clause 4 states that anything in 0.y.z versions MAY change at any time, and that the public API SHOULD NOT be considered stable. |
@Saklad5, I thought I said something like that. Well, except that I would never advice anyone to assume that a 0.y.z version of anything will ever be stable, even if the publisher made such a claim. There's the contract you get from the spec, and there's the contract you get from the publisher. We should never get them confused. If you want to risk taking a dependency on a 0.0.z version because the publisher says they'll indicate breaking changes in the minor field, you and the publisher are operating outside the SemVer spec. At least it doesn't breaking existing tooling, as the promises are stronger than the spec. Anyone relying on the SemVer contract (ie, most of our automation), should not use a 0.y.z version in any critical production environment. The spec says that a change in 0.y... is intended to be a non-breaking change, with the caveat that because it's a prototype, there is a higher than normal probability that it will be a breaking change. In other words, "we don't intend to break your code, but we don't have a clue yet, whether that is true, so hedge your bets". The spec has explicitly overloaded both the Y and Z fields. The publisher that says "we use SemVer, but we only bump Y for known breaking changes" is still compliant in that respect, but they are also telling you "this is a prototype and we use SemVer, so there is a higher than usual probability that we will get it wrong". You basically have to ask yourself, why don't they just use the full X.Y.Z-prerelease form of version string? Let's consider how the sequence transitions to a stable version shall we? First you propose 0.0.z be the "anything can happen" level of changes. Then maybe you think, I can fix a bug so now I have 0.y.z, so does the previous value of z shift to y or does it reset to 1? Either way, no problems... so eventually we have some non-zero value of y and z and we decide it's time for an official "stable release". Is that 1.0.0 or X=Y.0.0? If the later, then why not just do X.Y.Z-prerelease the whole way through? In either case, we were officially unstable until we set X, no one with any risk aversion is going to take a dependency on any of our prerelease versions anyway. I used to think we should just get rid of the 0.y.z form altogether, but I think it was originally intended for a fast phase of development, where the developer really wasn't sure what form the API should take (revolutionary) and the X.Y.Z-prerelease form is intended more for incremental (evolutionary) changes. In both cases, the product is in a potentially untested, unsafe and probably unstable state, until we get a pure X.Y.Z mode. So now I think we keep 0.y.z and maybe make it a little more clear that it's not intended for a mode where the publisher isn't promising any design stability at all. We have X.Y.Z=prerelease for when publishers are saying "we're pretty sure we got the correct form of the API at this point, if we can fix all the bugs and add the few remaining features to it without breaking anything, that's what we intend to do" phase. Today I think the 0.y.z format is best suited for the lone developer, pushing out bits to a handful of early adopters. When your developing in teams, and/or you have lots of early adopters, you'll have groups working on different features simultaneously and they'll want to test for compatibility with there partner's changes as they go, so they'll need the full range of semantics to decide which versions to merge with until their own features have stabilized. What we currently have is simple, and easy to implement tooling for. Hence we have a lot of conforming tooling. What you are proposing is a nice feature to have in a tool (IMO), but should not be promoted to the level of the SemVer spec at this point. I'd like to see your proposal defined using VersionSchema. It's a background task I've been working on for too long already, but I will get some more traction on it by the time we get out of this CoVid19 mess. |
@jwdonahue While I see where you are coming from, mistakes may be introduced regardless of whether the major version is 0. If someone explicitly states that they are using semantic versioning and doesn't increment the patch version for breaking changes, they are implicitly using a stricter subset of the standard. Take Swift Argument Parser as an example. It has already been contributed to by a substantial number of developers, and used by far more, despite being on version 0.0.4. That is safe, because Semantic Versioning 2.0.0 (which they are complying with) allows them to simply declare that patch versions are source-stable. SwiftSyntax, meanwhile, explicitly states that all versions potentially have breaking changes during initial development. That means that consumers must tell their automated tooling to stick with specific versions for it to be safely used. swift-format doesn’t specify which versions have breaking changes, which implicitly means that all of them do. It depends on both Swift Argument Parser and SwiftSyntax, specifying everything up to the next minor version for the former and a specific version for the latter. That’s just three pieces of software from the same company, and there’s still a fair bit of inconsistency between them. Sure, it can be manually resolved, but that’s precisely the sort of hassle that Semantic Versioning is about alleviating. |
SemVer is about communicating risk. Nobody ever gets it right 100% of the time. The spec doesn't really say anything about how consumers should behave, but given the implied levels of risk, it should be obvious enough to them, based on their own quality commitments. SemVer is a very blunt tool, and many producers wind up doing back-flips to shoehorn their specific workflows and quality commitments, into the SemVer syntax, simply for lack of more flexible tooling, or because their customer pool is already invested in SemVer tooling. What's really needed is a way for producers to advertise their work-flows and quality commitments, that consumers can apply their own filters to. Rather than a one size fits all approach, a larger set of best practices can emerge, while still allowing even greater flexibility for both producers and consumers. That's what VersionMeta and VersionSchema are all about. |
Thanks everyone for contributions, you're amazing 🎆 Did you find any consensus? |
It’s been quite a while, and the sole person who was objecting (on the apparent basis that this change is pointless because alternatives to SemVer exist that could do a similar thing) seems to have abandoned the project. Does that constitute consensus? |
@steveklabnik Could this be incorporated into SemVer 2.1? |
@alexandrtovmach @steveklabnik Any update on this? As mentioned almost a year ago, I think consensus has been reached. |
Am I understood correctly that your "consensus" expect to add changes to next version of SemVer? |
Yes. As I said last year, there was only ever one objection, and they ostentatiously abandoned the project. |
SemVer is not really being actively developed right now. I have recently stepped down from most of my other open source duties, and so after some rest time, may try to get things going. If and when that happens, I am happy to review stuff like this, but to answer the question at all, would have to hear from the other folks in charge too. |
My understanding is patch is always reserved for fixes to existing functionality, with no exception.
In a pre-1.0, the minor acts as both the major and the minor. This is one of the motivations to actually commit to the API and go 1.0, since customers won't know if minor releases contain breaking changes in pre-1.0 releases.
Or am I wrong? In a 0.x.y release, does the patch act like a minor, and the minor should be used when introducing breaking changes only?
I've ran into this misunderstanding many times now, and would like to see something in the FAQ that addresses this head-on.
The text was updated successfully, but these errors were encountered: