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

New feature: separateMultiplePatch and separateMultipleMinor #6576

Closed
grebenyuksv-preply opened this issue Jun 24, 2020 · 31 comments · Fixed by #24538
Closed

New feature: separateMultiplePatch and separateMultipleMinor #6576

grebenyuksv-preply opened this issue Jun 24, 2020 · 31 comments · Fixed by #24538
Labels
priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)

Comments

@grebenyuksv-preply
Copy link

What would you like Renovate to be able to do?
We at preply.com are always frustrated when we're either blocked or catching bugs after the following actions:

  • we've tested Renovate's PR updating a dependency to v4.5.6, and we're ready to merge
  • Renovate updates the PR with potentially buggy v4.5.7 or v4.6.0
  • Now, we have to either re-test it all or merge without testing since the v4.5.6 commit is no longer there.

Describe the solution you'd like
We would love a separate PR for every version.

Describe alternatives you've considered
Neither separateMajorMinor nor separateMultipleMajor nor separateMinorPatch seem to be expected to do that thing.

Additional context
Our NPM packages are continuously developed, merged, and deployed by independent teams. Different teams are allowed to contribute to shared packages. Once contributors have tested a Renovate's PR, they wanna see it live immediately.

Thank you for kindly considering my request. Please me if that makes sense and if you want me to code that.

@rarkins rarkins changed the title separateMultipleMajor and separateMultiplePatch New feature: separateMultiplePatch Jun 24, 2020
@rarkins rarkins added type:feature Feature (new functionality) priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others ready and removed ready labels Jun 24, 2020
@rarkins
Copy link
Collaborator

rarkins commented Jun 24, 2020

I have no objection to a new feature separateMultiplePatch. Although we'd need to work out what the expected behavior is if you're on 4.5.5 and all the following exist:

  • 4.5.6
  • 4.5.7
  • 4.6.0
  • 4.6.1
  • 5.0.0
  • 5.0.1

i.e. do you expect to get 6 separate PRs?

@grebenyuksv-preply
Copy link
Author

Yeah, that's exactly what we need!

@rarkins
Copy link
Collaborator

rarkins commented Jun 25, 2020

Thinking that through, I think that means that if separateMultiplePatch=true then Renovate essentially ignores all the other separateX options because they don't make a difference.

I'm also wondering if there'd be anyone who wants 4 PRs not 6, i.e.

  • 4.5.6
  • 4.5.7
  • 4.6.1
  • 5.0.1

If that's a possibility then maybe our new option for your case should be named something more explicit like separateAllReleases.

@grebenyuksv-preply grebenyuksv-preply changed the title New feature: separateMultiplePatch New feature: separateMultiplePatch and separateMultipleMinor Jun 26, 2020
@grebenyuksv-preply
Copy link
Author

Thinking that through, I think that means that if separateMultiplePatch=true then Renovate essentially ignores all the other separateX options because they don't make a difference.

If that's a possibility then maybe our new option for your case should be named something more explicit like separateAllReleases.

Well, I haven't explored the code very deeply yet, here's how I perceive those options as a user, please correct me if I'm wrong:

  • separateMajorMinor separates 4.6.1 from 5.0.1, ignoring any 4.x.x < 4.6.1 or any 5.x.x < 5.0.1
  • separateMultipleMajor separates 5.0.1 from 6.1.2, ignoring any 5.x.x < 5.0.1 or 6.x.x < 6.1.2
  • separateMinorPatch separates 4.5.7 from 4.6.1, ignoring any 4.5.x < 4.5.7 or 4.6.x < 4.6.1

I think I understand your idea behind separateAllReleases, and I think separateMultipleMinor and separateMultiplePatch sound better to me for two reasons:

  1. they would complement the existing options instead of conflicting with them or overriding them
  2. they would enable more granular configurations

Here's how they would work:

  • separateMultiplePatch alone would generate 4.6.1, 4.6.2, still ignoring any 4.x.x < 4.6
  • separateMultipleMinor alone would generate 4.5.7, 4.6.1, still ignoring any 4.5.x < 4.5.7 or 4.6.x < 4.6.1
  • separateMultiplePatch & separateMultipleMinor would generate 5.0.0, 5.0.1, 5.1.0
  • separateMultipleMajor & separateMultiplePatch & separateMultipleMinor would generate 4.5.6, 4.5.7, 4.6.0, 4.6.1, 5.0.0, 5.0.1

Tell me if that makes sense to you, you know better :)

@rarkins
Copy link
Collaborator

rarkins commented Jun 26, 2020

I think I need to put it in a table/matrix to better visualize it

@rarkins
Copy link
Collaborator

rarkins commented Jun 26, 2020

separateAll separateMultiplePatch separateMultipleMinor separateMinorPatch separateMajorMinor separateMultipleMajor 4.5.6 4.5.7 4.6.0 4.6.1 4.7.0 5.0.0 5.1.0 6.0.0
X
T X X
T T X X X
T T T X X X X
T T T T X X X X X
T T T T T X X X X X X
T T T T T T X X X X X X X X

@rarkins rarkins added the status:requirements Full requirements are not yet known, so implementation should not be started label Jan 12, 2021
@karfau
Copy link
Contributor

karfau commented Jun 27, 2021

It's very interesting that this was requested nearly exactly one year ago and today I asked for something very similar in #10628 and #10629 (now closed in favor of this one).
And that the conversation led to a very similar looking table regarding "what should happen when combining those options (do some combinations even make sense) and how hard it is to understand this.

Here is my "conclusion" that I want to contribute to the discussion:

And the underlying "issue" with all those options is that it get's harder and harder to understand what should happen. So thinking about a different way of configuring and describing it (and most likely also implementing it) makes sense.

E.g. there could be one option for all of it, e.g. separateVersions in which you would define the lowest or multiple levels at which you want to receive PRs and whether you want to join multiple by setting it to values like patchEach, patchMultiple (or patchJoined?), minorEach, minorMultiple, majorEach, majorMultiple.
The way I imagine it, the current defaults would reflect this property to be set to ["minorMultiple", "majorMultiple"] and only setting separateMultipleMajor to true would become ["minorMultiple", "majorEach"].

Or there could be one option for each level separatePatch, separateMinor, separateMajor that can be set to either

  • false: joined with higher level, default for separatePatch, not allowed for separateMajor 😉
  • multiple or latest: groups all available updates on that (and possibly lower levels if they are set to false), default for separateMinor and separateMajor (to reflect current defaults)
  • each: will create a PR for each increment on that level (possible including lower levels if set to false), current separateMultipleMajor would be reflected in setting separateMajor to each.

Or maybe this way of thinking about how to make it configurable in a way that's easy to understand, leads to something even better?

PS: I did see that this is not the first attempt in getting those options more clear and that there is quite an amount of issues and discussions related to those options.

@HonkingGoose HonkingGoose added status:ready and removed status:requirements Full requirements are not yet known, so implementation should not be started labels Jun 28, 2021
@HonkingGoose
Copy link
Collaborator

I'll take the liberty to move this to status:ready, seeing as @rarkins said on @10629:

Implement as new option, the logic will need to be added in both the lookup "bucket" logic as well as on the branch naming logic, similar to how separateMinorPatch works

Feel free to revert this if needed. 😉

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2021

The proposed solution here does not match the stated requirements. Having a branch for every version is different to supporting separateMultipleX. It would be like separateEveryVersion which overrides all the others. If we implemented this it should come with a warning that this would cause too much noise for most projects.

@rarkins
Copy link
Collaborator

rarkins commented Jun 28, 2021

The most important is separateMultipleMinor and it does not need to be held up waiting for a PR which covers the other two, so ideally the separateMultipleX ones are in separate feature request issues while this can be separateEveryVersion

@rarkins
Copy link
Collaborator

rarkins commented Jun 29, 2021

BTW if we have multiple related options like this, but some of them combined make no sense or contradict, then it's a sign we should think of consolidating multiple options into less such that they can no longer contradict each other.

@HonkingGoose
Copy link
Collaborator

@rarkins Can you maybe make a short summary of where we stand now, in simplified terms? I find that the current discussion is flying way over my head. 🙈

I guess you want separate issues to split this issue into smaller parts? But then you also say you want to consolidate the separateThings behavior in such a way that individual options no longer contradict each other?

If you want new issues, I think it's best if you create them. 😉 You seem to know the direction you want to take this in... 😄

@rarkins
Copy link
Collaborator

rarkins commented Jul 18, 2021

If we keep going with the existing approach, we can get contradictions:

image

However it's pretty easy to resolve/override them, so that doesn't mean we should avoid them. Is there any more elegant way which could improve on this approach?

BTW there can also be a new option separateEveryVersion which overrides all other separateX settings.

@rarkins rarkins added status:requirements Full requirements are not yet known, so implementation should not be started and removed status:ready labels Jul 18, 2021
@danports
Copy link
Contributor

I'm not sure that I understand all of the use cases for the existing options, but what about something simple like this? Replace all of the separate* settings with a single separateUpgradesBy setting, an enum with the following values:

  • none: You only get a PR for the latest release (like separateMajorMinor: false).
  • major: You get a PR for the latest patch release of the current and every newer major release (like separateMultipleMajor: true).
  • minor: You get a PR for the latest patch release of the current and every newer minor release (like the separateMultipleMinor: true option discussed here).
  • patch: You get a PR for every single newer patch release (slightly different from the current separateMinorPatch: true option if I'm understanding that right).

There could perhaps be another setting for controlling which versions Renovate generates PRs for so that you don't wind up with a ton of pending minor or patch upgrades, but it might be helpful to distinguish that setting from separateUpgradesBy to reduce complexity.

@rarkins
Copy link
Collaborator

rarkins commented Jan 27, 2022

The above is not compatible with today's default, which in simple terms means "One latest major PR, and one latest minor PR". I.e. it doesn't give you one PR per major release - just the highest major

@danports
Copy link
Contributor

Yeah, separateUpgradesBy wouldn't cover the default behavior, or the current separateMinorPatch behavior. I think there are basically three knobs we are trying to control:

  • Whether to separate or lump together major/minor/patch upgrades (what I was trying to achieve with the separateUpgradesBy concept)
  • Whether to allow skipping over major/minor/patch upgrades to catch up to the latest release (e.g. I would like PRs for every single minor release, or just the latest minor release)
  • How many PRs to generate at each level (e.g. I would like PRs for the next patch release, the next 3 minor releases, and every newer major release - not sure if we need that level of granularity, that's just an example)

For example, with Kubernetes, I'd like to be able to tell Renovate, "I'd like a PR for the latest patch of the current minor release, and a PR for every newer minor release."

I'm just not sure how to translate the knobs above into a straightforward set of configuration parameters yet. 🤔

@rarkins
Copy link
Collaborator

rarkins commented Jan 30, 2022

I'm trying to think if we can understand and then maybe improve the semantics:

  1. First of all, you have the option to just "take the latest", i.e. separateMajorMinor=false, and don't split by minor or major. In this case you only ever have ​one update per dependency
  2. Next, you have the option of ​one update for the current major, and one for the latest major. This is our default behavior right now (separateMajorMinor)
  3. Next, you can have one update per major stream (separateMultipleMajor)
  4. If you've picked (2) or (3) above, you can choose to get one update for the current minor stream and another for the latest minor stream (separateMinorPatch)
  5. Alternatively instead of (4) you could in future choose to get one release for each minor stream (separateMultipleMinor)

Let's assume we're on 1.0.0 and the available updates are 1.0.1, 1.0.2, 1.1.0, 1.1.1, 1.2.0, 2.0.0, 2.0.1, 2.1.0, 3.0.0

So although in theory 4 options would give us 16 permutations, the only valid ones are:

  • latest version: 3.0.0
  • latest major, latest non-major: 1.2.0, 3.0.0
  • every major: 1.2.0, 2.1.0, 3.0.0
  • latest major, latest minor, latest patch: 1.0.2, 1.2.0, 3.0.0
  • every major, latest minor, latest patch: 1.0.2, 1.2.0, 2.1.0, 3.0.0
  • latest major, every minor: 1.0.2, 1.1.1, 1.2.0, 3.0.0
  • every major, every minor: 1.0.2, 1.1.1, 1.2.0, 2.1.0, 3.0.0

And if we add the capability for separateMultiplePatch then we'd add:

  • latest major, latest minor, every patch: 1.0.1, 1.0.2, 1.2.0, 3.0.0
  • every major, latest minor, every patch: 1.0.1, 1.0.2, 1.2.0, 2.1.0, 3.0.0
  • latest major, every minor, every patch: 1.0.1, 1.0.2, 1.1.1, 1.2.0, 3.0.0
  • every major, every minor, every patch: 1.0.1, 1.0.2, 1.1.1, 1.2.0, 2.1.0, 3.0.0

Another way of framing it:

  • separateMajor: all, current+latest, none
  • separateMinor: all, current+latest, none
  • separatePatch: all, none

If you get a "none" on one row, the ones below it are ignored (must be none). Default behavior is currently separateMajor=current+latest.

This doesn't seem perfect, but the best idea so far

@ccopsey
Copy link
Contributor

ccopsey commented Jan 30, 2022

I think each of your "every major, every minor" permutations should include 2.0.1.

@rarkins
Copy link
Collaborator

rarkins commented Jan 30, 2022

It's intentional not to separate minor streams in major releases, although I admit it's not well described by "every major, every minot". I don't think such an option is practical or useful except in some very rare edge cases.

@ccopsey
Copy link
Contributor

ccopsey commented Jan 30, 2022

In your example, if 3.1.0 was also available, would 3.0.0 and 3.1.0 both be candidates in a “every major, every minor” scenario?

If so I think your comment is reasonable, although potentially unintuitive given the configuration options. And hopefully this shouldn’t crop up in practice as the user should track the latest much more closely.

@rarkins
Copy link
Collaborator

rarkins commented Jan 30, 2022

No, my intention was that you don't separate minor other than in the current major stream

@ccopsey
Copy link
Contributor

ccopsey commented Jan 30, 2022

I would need separate minors for the latest major to ensure there are candidate versions that satisfy my stability criteria, otherwise the latest major is always out of reach. Without manual intervention I’m always 1 major behind, and each upgrade is large.

Is this really an edge case?

@rarkins
Copy link
Collaborator

rarkins commented Jan 30, 2022

What's an example of your "stability criteria"?

@ccopsey
Copy link
Contributor

ccopsey commented Jan 30, 2022

I run renovate via docker and so have control over the version that runs. It is subject to the same 7 stabilityDays that I apply to everything. As it stands I’m still on v30 as there hasn’t been a period of 7 days when the latest v31 has remained constant.

Perhaps the answer here is that due to the continuous deployment nature of renovate, and the fact it is a utility rather than a dependency, stabilityDays doesn’t make as much sense. Maybe this is an edge case.

@rarkins
Copy link
Collaborator

rarkins commented Jan 30, 2022

Check out the config option internalChecksFilter=strict. But old doesn't necessarily mean bug-free..

@MPV
Copy link
Contributor

MPV commented May 10, 2022

No, my intention was that you don't separate minor other than in the current major stream

@rarkins I guess it depends.

Intuitively, in my head, if I've dropped behind on a dependency, I'd prefer to upgrade in batches, first small lower-risk ones (patch version by version), and as I get up to speed I'd feel more comfortable biting of larger chunks of upgrades (as I may have a warm testing habit/framework/automation to use when I get to newer versions).

Any thoughts on how to move this forward in general?

@viceice
Copy link
Member

viceice commented May 10, 2022

you can workaround this with a package rule and allows versions filter.

@ekristen
Copy link

I would be in favor of a separateMultipleMinor as there are many projects that treat "minor" as the "major" and the "major" never gets incremented.

@SchroederSteffen
Copy link
Contributor

We're currently also missing a separateMultipleMinor option. 👍

In our case, our Angular v14 project is still on TypeScript v4.7, because the v4.8 update was failing because of some other reason.
By now, Renovate suggests the TypeScript v4.9 and Angular v15 updates.
Though, neither of them work, because Angular v14 requires TS <= v4.8 and Angular v15 requires TS >= 4.8.
This means that we need to do the TS v4.8 update manually now.

=> We would like to be able to write a package rule that enables separateMultipleMinor for TypeScript.

@djmcgreal-cc
Copy link

Hi. I came here from #19194 where the use-case is slightly different.

For what it's worth, I'd been thinking of a maximumSimultaneousIncrement option, which could somehow constrain how far you'd like to go before opening a separate PR (or in my case waiting for the existing one to close, perhaps with a rate-limit by packageRule?). I don't know if that's at all relevant for this case too, though.

@rarkins rarkins removed the status:requirements Full requirements are not yet known, so implementation should not be started label Oct 1, 2023
@renovate-release
Copy link
Collaborator

🎉 This issue has been resolved in version 37.269.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Apr 26, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
priority-3-medium Default priority, "should be done" but isn't prioritised ahead of others type:feature Feature (new functionality)
Projects
None yet
Development

Successfully merging a pull request may close this issue.