Skip to content

Making it clear how 0.X.Y versions work#152

Closed
krainboltgreene wants to merge 3 commits intosemver:masterfrom
krainboltgreene:patch-1
Closed

Making it clear how 0.X.Y versions work#152
krainboltgreene wants to merge 3 commits intosemver:masterfrom
krainboltgreene:patch-1

Conversation

@krainboltgreene
Copy link

I've come up against a lot of libraries that stick to 0.X.Y versions and when challenged claim "oh we might change the API". SEMVER is supposed to give you the freedom to change your public API as long as you document the severity of that change in the version. This line gives developers something to hide behind to avoid the scary 1.X.Y declaration when in reality they're well past a stable release and being depended on by others.

I find this to be both annoying and detrimental to the use of Semantic Versioning. One major point of SEMVER is that APIs can safely change as long as a corresponding change happens to their Version.

As such I've removed the wording "api can change" because it's not descriptive of 0.X.Y. 0.X.Y should be simple: If you're still working on minimum viable functionality then you're still 0.X.Y. As soon as someone depends on you, then you should document your public API and bump the major version to 1.X.Y.

I've come up against a lot of libraries that stick to 0.X.Y versions and when challenged claim "oh we might change the API". SEMVER is supposed to give you the freedom to change your public API as long as you document it. This line gives developers something to hide behind to avoid the scary 1.X.Y declaration.

I find this to be both annoying and detrimental to the use of Semantic Versioning. One major point of SEMVER is that *APIs can safely change as long as a corresponding change happens to their Version*.

As such I've removed the wording "api can change" because it's not descriptive of 0.X.Y. 0.X.Y should be simple: If you're still working on minimum viable functionality then you're still 0.X.Y. As soon as someone depends on you, then you should document your public API and bump the major version to 1.X.Y.
semver.md Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we change shouldn't to SHOULD NOT?

@haacked
Copy link
Contributor

haacked commented Aug 12, 2013

I like this change. Would love to hear others chime in before I merge it.

@snarkasonne
Copy link

I feel like the SEMVER specs already handle this situation. I don't think saying "As soon as someone depends on you, then you should document your public API and bump the major version to 1.X.Y" is correct, because the point of being 0.x.y in SEMVER is to let people know not to depend on you, because the Public API could break.

I get the frustration in widely used libraries never going 1.0.0, but I think this change is an over-reaction to that, since there are several legitimate 0.x.y libraries that could break public API, and the reason they are distributed publicly is so people can use it in the real world and give feedback or find bugs so they can work towards a 1.0.0 release. And the definition in SEMVER of what a 0.x.y version number means should be clear enough for the users to know not to depend on it, but to beware that there could be bugs, and that the next release could have large breaking changes.

And I think that in early stages of libraries, it doesn't make sense to force these developers to go to 1.0.0 before a public release, because rapidly increasing major version numbers looks much sillier than just following the current SEMVER spec of keeping it at 0.x.y and bumping the minor version while youre getting your public API straightened out.

I would prefer something closer to ChrisWren's pull request, since it would still allow for developers to release 0.x.y libraries for public use, and provides a clearer distinction to developers on what 0.x.y means and how to use it, while providing the same semantic meaning of "This is not 1.0.0 yet, use at your own risk".

@abotalov
Copy link

abotalov commented Feb 3, 2014

-1 for this
+1 for #127

@krainboltgreene
Copy link
Author

Both of them are similar.

@abotalov
Copy link

abotalov commented Feb 3, 2014

@krainboltgreene #127 says that backwards incompatible changes require updating y in (0.y.z)
So it makes possible to depend even on versions that are below 1.0.0

@krainboltgreene
Copy link
Author

Why do you think my edit makes it impossible to depend on versions below 1.0.0?

@abotalov
Copy link

abotalov commented Feb 3, 2014

Those edits say that :

  1. Distribution of versions below 1.0.0 should be avoided.
    I think it means that library with unstable API should not be open-sourced and released (i.e. distributed) to Github (remember that Git is a "distributed version control system"). So it makes it impossible to use that library by anyone but you.
  2. Versions below 1.0.0 should not be considered for public consumption.
    It raises question on what do you mean by public consumption. For example I've just heard about "a_shiny_library" (that is on version < 1.0.0) and I want to try it out. But this edit says that I shouldn't try it out as I am just a member of public and this library is not for consumption of public.

@krainboltgreene
Copy link
Author

  1. Distribution of versions below 1.0.0 should be avoided.

I think it means that library with unstable API should not be open-sourced and released (i.e. distributed) to Github (remember that Git is a "distributed version control system"). So it makes it impossible to use that library by anyone but you.

That's a shame as it's the exact opposite of what I intended: The avoidance of pushing unstable public APIs to distribution platforms like RubyGems or NPM where people assume libraries are dependable.

  1. Versions below 1.0.0 should not be considered for public consumption.

It raises question on what do you mean by public consumption. For example I've just heard about "a_shiny_library" (that is on version < 1.0.0) and I want to try it out. But this edit says that I shouldn't try it out as I am just a member of public and this library is not for public consumption.

If this library is truly 0.X.Y then you shouldn't depend the stability of it's public API. Do you really want to depend on something that is by definition undependable?

There is nothing in my wording that suggests you shouldn't try out 0.X.Y gems. You should try it out, but the owner shouldn't release into distribution platforms it until they're ready to support a stable public API.

@milesrout
Copy link

@krainboltgreene he said "try out", not "depend on".

@loz
Copy link

loz commented May 8, 2014

I've added a stricter change with some requirements for how to apply server in 0.Y.Z versions:

#195

@haacked
Copy link
Contributor

haacked commented Jul 1, 2014

because the point of being 0.x.y in SEMVER is to let people know not to depend on you

I agree with this sentiment. I think it should be up to Ruby Gems and other package managers to decide if they want to go further. SemVer is about communication the author's intent.

The avoidance of pushing unstable public APIs to distribution platforms like RubyGems or NPM where people assume libraries are dependable.

That should probably be taken up with Ruby Gems. For example, I know gems (and NuGet) have support for pre-release packages. They filter them out of your normal usage and you're required to add a -Pre flag for pre-release packages to be visible.

However, I suspect they do not treat 0.x.y packages in this manner. That seems like a bug in those platforms, not in SemVer, no?

@krainboltgreene
Copy link
Author

You could definitely make the argument for that in NPM (and I would agree with you), but RubyGems is actually "logical versioning", which just happens to include SEMVER. They can't dictate something like that.

Frankly, it wouldn't work if they tried. A significant majority (I've actually got the numbers) of gems are 0.X, despite having a lot of people depend on those gems.

@haacked
Copy link
Contributor

haacked commented Jul 1, 2014

Ok, pretend I made that argument for NPM. And for NuGet. :)

@milesrout
Copy link

0.x doesn't mean "don't depend on me", it means "don't depend on my API being stable between 0.x and 0.y where y != x".

@krainboltgreene
Copy link
Author

You just defined a major version bump: "don't depend on my API being stable
between X.0.0 and Y.0.0 where y != x"

This isn't how ANY other major version number works and it appears by your
definition you're just moving the rules down one notch.

Don't give special rules just for 0, the regular rules work just fine.
Apply them globally or get rid of 0 as a valid semver.

On Tue, Jul 1, 2014 at 4:17 AM, Miles Rout [email protected] wrote:

0.x doesn't mean "don't depend on me", it means "don't depend on my API
being stable between 0.x and 0.y where y != x".


Reply to this email directly or view it on GitHub
#152 (comment).

Kurtis Rainbolt-Greene, Hacker
Software Developer
1631 8th St.
New Orleans, LA
70115

@milesrout
Copy link

What are you on about? That's exactly how every other versioning system works, and it's how SemVer has always worked. 0.x means an in-development work-in-progress pre-launch unstable API.

@krainboltgreene
Copy link
Author

You don't need to be rude, @milesrout.

@milesrout
Copy link

I didn't intend to be rude.

@krainboltgreene
Copy link
Author

I felt like "What are you on?" was an aggressive question.

I'll respond to the rest of your post in piece:

0.x means an in-development work-in-progress pre-launch unstable API.

I will agree that 0.X.Y means "pre-launch" and possibly "unstable", but I disagree with the other terms you've used to describe it the concept. When you publicly release a library with the version 1.0.0 you're probably not done developing the public API, you're probably still working on it.

My point is that the descriptors (as detailed in the other thread) "work in progress" and/or "in development" are useless because all public APIs are works in progress and in development. Rarely does a library stop improving and rarely does a library stop developing new interfaces.

The difference between 1.9.5 and 2.0.0 is that the behavior contract defined in 1.X.Y is likely no longer supported in at least one way.

If you consider this then I ask you: What is truly 0.X.Y? And if it's realistically "unstable" and "pre-launch" then why bother attaching a major, (meaningless) minor, and (meaningless) patch version to it? Why not just release it as version 0 since, by the very definition you've used you have no intent of backwards supporting previous versions.

Of course this ultimately assumes that the people actually releasing public APIs actually cared to use your definition of 0.X.Y. In fact the statistics I've gathered suggest people release (more like dump) a library at 0.1.Y, with the intent of eventually releasing 1.0.0, realize that their work is "good enough" and then never release a "real" 1.0.0.

Their "unstable" or "pre-launch" versioned library gets treated as something to depend on for production projects, something explicitly talked about in the FAQ.

My aggressive suggestion is to get rid of the 0.X.Y idea. My statistics tell me that even the strictest library package manager doesn't enforce or enforce the idea that 0.X.Y shouldn't be dependable.

My least aggressive suggestion is (as seen in my PR) that the 0.X.Y documentation doesn't convey the (as you described) unreliability and instability in a consistent api contract.

@mojombo
Copy link
Contributor

mojombo commented Jul 3, 2014

Version 0.y.z. is intended to denote a development period in which a public API has not been defined yet or is changing so rapidly that incrementing major version numbers for every breaking change would seem silly. It doesn't mean that nobody should depend on a 0.y.z package; only that a user should not expect any semantic information from the minor and patch versions changing during that phase. The ideal approach for a consumer would be to require an exact version of a 0.y.z package only (no ranges). Each new 0.y.z release needs to be evaluated independently since anything may change at any time.

If you're still working on minimum viable functionality then you're still 0.X.Y. As soon as someone depends on you, then you should document your public API and bump the major version to 1.X.Y.

This feels too rigid. In an ideal world this would happen, but our world is far from ideal, and so we must build in mechanisms that allow normal people to adhere to the spec.

If you consider this then I ask you: What is truly 0.X.Y? And if it's realistically "unstable" and "pre-launch" then why bother attaching a major, (meaningless) minor, and (meaningless) patch version to it? Why not just release it as version 0 since, by the very definition you've used you have no intent of backwards supporting previous versions.

You're right in that minor and patch numbers are meaningless in 0.y.z versions. They're mainly there as a way to communicate progress to consumers and to give them something to specify in their dependency managers other than a SHA1. They may not have formal semantics, but they're still extremely useful in showing the evolution of an early project.

In fact the statistics I've gathered suggest people release (more like dump) a library at 0.1.Y, with the intent of eventually releasing 1.0.0, realize that their work is "good enough" and then never release a "real" 1.0.0.

I totally feel your pain regarding people that keep their packages 0.y.z for too long. That sucks. A lot. But as I mentioned in another PR, I think this is a social issue, not something that the spec can fix. And it seems unlikely that someone that would just dump a project at 0.1.0 and then forget about it would follow a more burdensome process simply because Semver said to.

Their "unstable" or "pre-launch" versioned library gets treated as something to depend on for production projects, something explicitly talked about in the FAQ.

And this is fine. Depending on v0.7.3 of something is great. It gets you what you want. But for some reason the author doesn't think their project is ready to be 1.0.0 yet, or doesn't want to do the work to keep track of backwards compatibility. If 1000 people are using that project, then this is a problem with how that person thinks about responsible software development. This is already addressed in the FAQ section.

My aggressive suggestion is to get rid of the 0.X.Y idea. My statistics tell me that even the strictest library package manager doesn't enforce or enforce the idea that 0.X.Y shouldn't be dependable.

I don't know that they need to enforce it. It would be cool if your package manager told you that depending on ranges of 0.y.z versions is a bad idea, but good developers will already know that. In any case, I don't think that's a reason to axe the flexibility of the 0.y.z. phase.

My least aggressive suggestion is (as seen in my PR) that the 0.X.Y documentation doesn't convey the (as you described) unreliability and instability in a consistent api contract.

I feel like it does. It seems to say exactly that to me: "Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable."

Your proposal is the following:

Major version zero (0.y.z) is for initial development and SHOULD NOT be considered for public consumption. Avoid distribution to avoid dependency on an unstable API.

Which I disagree with. I think it's great when people distribute early software on package management systems. It makes it easy for a huge audience to try things out. Having to pull stuff from GitHub or tarball sucks and will limit how many people experiment with new ideas.

@milesrout
Copy link

So, what I think is missing in the semver spec is a clarification on how to handle depending on versions 0.x.y: Always depend on an exact version and don't use ranges. I know that this is what The public API should not be considered stable. refers to but it's not obvious, as seen by the confusion in these two issues.

The SemVer spec doesn't tell you what to do with packages, it tells you how to version them.

@FichteFoll
Copy link

It can be added to the FAQ though.

@RWOverdijk
Copy link

Is this going somewhere? Because I agree with the point being made. I don't think that 0.x.y deserves having its own set of rules unless it literally means "don't rely on this code too much, it's not done yet".

@EddieGarmon
Copy link
Contributor

Maybe for 0.x.y versions: s/unstable/unfinished

@krainboltgreene
Copy link
Author

0.X.Y is the worst concept ever, and gives so many developers a scapegoat
for the fear of real releases. The excuse I see time and time again is "but
my library isn't finished" (rarely does a library ever "finish", that's the
reason we have version numbers) and "but my api could change at any time"
(that's literally what major versions are designed to document).

Frankly, any tool is broken if it tries to document the public API
compatibility for a period of life in a codebase where there are no plans
to be compatible.

Want to not be broken? Strike the definition from the record, tell everyone
to get some courage and realize their library is probably used in
production and needs to be 1.0.0 immediately.

On Tue, Apr 21, 2015 at 3:48 PM Eddie Garmon [email protected]
wrote:

Maybe for 0.x.y versions: s/unstable/unfinished


Reply to this email directly or view it on GitHub
#152 (comment).

@FichteFoll
Copy link

Imo 0.x.y is needed for rapidly changing products or those which don't really have a defined public API yet. If you are in early development and following semver strictly but started with 1.0.0, you are likely approaching 100.0.0 quickly.

The only problem is that people often miss the point where their product should actually be 1.0.0 already, and you need to remind them of it. I'm all for an international "1.0.0 day" or "major 1 day" where developers revisit their old code to check if a 1.0.0 release is feasable or necessary.

What semver should do in this regard is probably reword the 0.x.y section a bit or add a sentence that clarifies how sub-1.0.0 versions must be depended on explicitly.
What that means is, usually you would only specify >=x.y.z <x+1.0.0 as a version selector, where x.y.z contains the latest feature addition or bugfix you need. For 0.x.y releases you MUST NOT use selector ranges but may only depend on an exact version, as anything can change any time.

@krainboltgreene
Copy link
Author

All projects can be rapidly changing. The whole point of SEMVER is
documenting the result of change and releases.

On Tue, Apr 21, 2015 at 4:26 PM FichteFoll [email protected] wrote:

Imo 0.x.y is needed for rapidly changing products or those which don't
really have a defined public API yet. If you are in early development and
following semver strictly but started with 1.0.0, you are likely
approaching 100.0.0 quickly.

The only problem is that people often miss the point where their product
should actually be 1.0.0 already, and you need to remind them of it. I'm
all for an international "1.0.0 day" or "major 1 day" where developers
revisit their old code to check if a 1.0.0 release is feasable or necessary.

What semver should do in this regard is probably reword the 0.x.y section
a bit or add a sentence that clarifies how sub-1.0.0 versions must be
depended on explicitly
. Usually you would only specify >=x.y.z <x+1.0.0
as a version selector, where x.y.z contains the latest feature addition or
bugfix you need. For 0.x.y releases you MUST NOT use selector ranges but
may only depend on an exact version, as anything can change any time.


Reply to this email directly or view it on GitHub
#152 (comment).

@crazedsanity
Copy link

I agree with @FichteFoll in that 0.x.y releases MUST NOT use selector ranges but may only depend on an exact version, as anything can change any time. It is both logical and follows unspoken principles of many existing libraries.

@RWOverdijk
Copy link

So if I understand correctly, you're saying that 0.x.y (or any tag for that matter) is production ready, but has an unstable API, so you must depend on an exact version to make sure you don't shoot yourself in the foot.

I feel there's something wrong with this. Being able to trust bug fixes and security patches in PATCH bumps is a major win for developers. Now I have to go through change logs for every 0.x.y lib I use, if I wish to update. That should only happen for major bumps imo.

Also, @FichteFoll I don't think that's true. If you're in early development, usually there's a preview of some sort (edge). Even then, I don't think it really matters if you're on 100.0.0. It probably just means you tagged to early, or you don't know what you're doing. That's what PRs are for.

@milesrout
Copy link

0.x.y is absolutely fine as it is. Versioning something doesn't mean it is finalized. It seems a lot of the comments here are just people venting that npm contains a lot of 0.x.y packages, which is something wrong with them, not with semver.

@krainboltgreene
Copy link
Author

Yeah, it's just a problem endemic of at least two huge package managers
that use SEMVER. It's totally not SEMVER's fault. Just coincidence.

I'm closing the ticket since it's like talking to brick walls.

On Wed, Apr 22, 2015 at 5:02 PM Miles Rout [email protected] wrote:

0.x.y is absolutely fine as it is. Versioning something doesn't mean it is
finalized. It seems a lot of the comments here are just people venting that
npm contains a lot of 0.x.y packages, which is something wrong with them,
not with semver.


Reply to this email directly or view it on GitHub
#152 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.