Skip to content
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

Why PATCH is for Bug Fixes only? #831

Open
felipecrs opened this issue May 2, 2022 · 13 comments
Open

Why PATCH is for Bug Fixes only? #831

felipecrs opened this issue May 2, 2022 · 13 comments

Comments

@felipecrs
Copy link

felipecrs commented May 2, 2022

Why it isn't the following?

1. MAJOR version when you make incompatible API changes,
2. MINOR version when you add functionality in a backwards compatible manner, and
- 3. PATCH version when you make backwards compatible bug fixes.
+ 3. PATCH version when you make backwards compatible changes that does not add functionality.

I just want to know why PATCH bumps are reserved to only Bug Fixes.

What about backwards compatible Performance Improvements, Refactoring, Dependencies Updates, Documentation (that gets shipped with the product), for example? None of them are Bug Fixes, and yet deserves to be released (no?).

@felipecrs felipecrs changed the title Why PATCH is only for backwards compatible _bug fixes_? Why PATCH is for Bug Fixes only? May 2, 2022
@jcornaz
Copy link

jcornaz commented May 3, 2022

Yeah, fully agree. Personally, I bump the patch component notably for performance and documentation improvements.

However, for exact wording I would suggest something like:

PATCH version when you make backwards compatible changes that do not change the API

as semver is all about the declared API:

  • major = incompatible API change
  • minor = compatible API change
  • patch = no API change

@JoshCheek
Copy link

I've always bumped the minor version in these situations, I guess I've always thought of them as being closer to features than bugfixes. But if I use @jcornaz's metrics, then yeah, I agree that they'd be patchlevel.

@epage
Copy link

epage commented May 31, 2022

minor = compatible API change
patch = no API change

imo distinguishing between no API change and compatible API change has little impact on the callers lives. The distinction I tend towards is either

  • Do the changes, in aggregate, increase risk for the caller to worry about when upgrading?
  • Do the semantic changes, in aggregate, need their visibility raised because they might break someone despite it being a bug / undefined behavior?

Or put another way "what is the chance I would need the flexibility to release a hotfix for this release?" (if we were doing hotfixes)

@jcornaz
Copy link

jcornaz commented May 31, 2022

imo distinguishing between no API change and compatible API change has little impact on the callers lives.

Yes. Sure. That's by definition. The only thing that has a big impact on callers lives is: breaking changes. And breaking changes require major bump. As long as a change is not breaking the API, further details have little impact on the callers live. Not to say it has none. I still find it valuable to know from a version number if the API has changed or not.

But there is still a difference that matters for the user. If we think about how easy/risky it is to downgrade:

  • major: cannot upgrade to a major version nor downgrade from a major verision without risk
  • minor: can upgrade safely, but cannot downgrade from a minor version (as the new API introduced by the version may be already in use)
  • patch: can upgrade and downgrade safely, as there is no API change.

@epage
Copy link

epage commented May 31, 2022

But there is still a difference that matters for the user. If we think about how easy/risky it is to downgrade:

patch: can upgrade and downgrade safely, as there is no API change.

Except there are bug fixes that make it unsafe to downgrade.

@jwdonahue
Copy link
Contributor

Adding functionality does not necessarily increase or modify the interface, so the proposed new language has a similar flaw to the original. A library might have a SoundOn interface for instance that was never implemented in the package. The 'I' in API stands for Interface, not implementation, but the spec's intro says the publisher decides what API means in the context of their product.

Addressing the OP's original question:

Why PATCH is for Bug Fixes only?

In practice it is not just for bug fixes. What it applies to is context dependent, where context includes things like:

  • Tool chains.
    • Programing/content language.
    • Compilers, linkers, interpreters.
    • Packaging tools.
  • Runtime environment(s).
  • Ecosystem expectations.
  • What is being versioned.
  • Too many other things to list here.

What about backwards compatible Performance Improvements, Refactoring, Dependencies Updates, Documentation (that gets shipped with the product), for example?

Again context matters:

  • In some cases any change in performance could be a breaking change.
  • Refactoring can cause changes in performance or break things that are dependent on content.
  • For dependencies, see all the discussions around transitive dependencies.
  • Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported.

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

@felipecrs
Copy link
Author

felipecrs commented Nov 18, 2022

Thanks for the answer!

In practice it is not just for bug fixes.

But my concern is about the theory, which is what this specification is.

Again context matters:

That's why I started the sentence being explicitly clear that I'm talking about backwards compatible, i.e. non breaking changes.

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

I understand. But it may be something to have in mind for a newer version of the specification.

@jcornaz
Copy link

jcornaz commented Nov 18, 2022

The spec's authors have never attempted to cover all use cases. It's not the most well written specification, but it has sufficed to convey the gist of the original author's intent at the time.

I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability.

Tool chains.
Programing/content language.
Compilers, linkers, interpreters.
Packaging tools.
Runtime environment(s).
Ecosystem expectations.
What is being versioned.
Too many other things to list here.

In some cases any change in performance could be a breaking change.

There is already a clear rule about breaking change. If it is a breaking change, bump the major version.

Refactoring can cause changes in performance or break things that are dependent on content.

If it changes something in the API (incl. changing documented behavior), then it is not refactoring.
"refactoring" means changing the implementation without changing the API or the behavior.

If you promised behavior or performance in your documentation, then a change that would violate those promises should be considered as breaking (major bump). If you didn't document the behavior or perf or you still deliver the promised behavior and perf, then bump the patch.

For dependencies, see all the discussions around transitive dependencies.
Documentation changes can be tricky as well, particularly if the language indicates that something that seemed to be supported is, or should, no longer be supported.

The same concept applies...

Of course, it is sometimes (often?) tricky to determine what is a breaking change and what is not. Personally, I like very much the documentation on what constitutes a breaking change for the rust ecosystem: https://github.com/rust-lang/rfcs/blob/master/text/1105-api-evolution.md

But the present issue is not discussing the wording of what constitutes a breaking change. It is discussing the wording of what constitutes a patch change. I think it is already clear that to be a patch it should be neither breaking nor a feature.

@jwdonahue
Copy link
Contributor

I think a good specification minimizes the risk of diverging interpretations. SemVer should aim to maximize its clarity and applicability

Spend some time reading all of the closed issues on this site and you'll likely come to the conclusion that I did, namely that that is not the intent of the maintainers. The maintainers are package tool owners serving diverse ecosystems. There are many, much tighter specs out there, mostly for very narrowly defined use cases.

If it changes something in the API (incl. changing documented behavior), then it is not refactoring.
"refactoring" means changing the implementation without changing the API or the behavior.

Just pointing out to the OP that refactorings are not always patch level changes.

I think it is already clear that to be a patch it should be neither breaking nor a feature.

Exactly!

The issue here is many people suggest modifying the spec to make it more clear, or to cover a use case they perceive to be useful, most of which would require a major version bump on the spec itself. Just about everybody can think of ways to clarify the language with respect to how they perceive that it should be applied, but nobody wants to put in the work that would cover all the ways it is currently applied. Attempting to do so would would require more words and for every one of those you add to it, the range of possible interpretations will either increase such that it is less clear or be restricted, such that it breaks a sizable fraction of the currently "SemVer compliant" implementations.

The maintainers have been reluctant to discuss SemVer 3. They own packaging tools that serve large silos, each of which has its own peculiar needs and practices. In that sense, the SemVer spec has been a huge success so far.

@jcornaz
Copy link

jcornaz commented Nov 18, 2022

So we are doomed and any effort to improve the spec is in vain. We are left with a versioning spec that is not even good enough to version itself and that every developer understands differently and argues about. I've even seen people refusing to release a new version of the software that's full of CVE, because "there is no functional change".

Sadly, it does look like that is the case indeed. Not that I am happy about it. Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway.

@jwdonahue
Copy link
Contributor

Personally, I have stopped saying on my projects that they follow semantic versioning, as different people will understand it differently anyway.

SemVer is just one of many semantic versioning schemes.

@ljharb
Copy link
Contributor

ljharb commented May 3, 2023

It's the only one that has any kind of adoption though, so it's pretty reasonable to conflate the two terms.

@Nikasyo25
Copy link

Nikasyo25 commented May 4, 2023 via email

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

No branches or pull requests

8 participants
@ljharb @epage @JoshCheek @jcornaz @jwdonahue @felipecrs @Nikasyo25 and others