Create as little ACK-releases as possible and keep ranges as open as possible
Closed this issue · 3 comments
As an outcome of internal discussions of our team and consumers of our product I recommend to implement the following:
Given we have a multi-package project with dialog@1.2.3
and button@2.3.4
And the dialog
has a dependency on button
declared using a caret-range
When button
receives a patch update
Then button
gets released as v2.3.5
And dialog
is not touched, since the caret range is covering the new button version
When button
receives a feature update
Then button
gets released as v2.4.0
And dialog
is not touched, since the caret range is covering the new button version
When button
receives a BREAKING update
Then button
gets released as v3.0.0
And the dialog
is updated to depend on button@2.3.4 - 3.x
And the dialog
gets released as v1.2.4
related workflow that is not covered by this automation:
When the dialog
then starts to use new API of the button
in a feature
Then I as a developer must update the dialog
to depend on button@^3.0.0
(or a future version that introduced the feature)
And the dialog
gets released as v1.3.0
Just noticed the following:
When button receives a BREAKING update
And a developer already pre-ACK-ed the change by setting the dependency of dialog
to button@^3.0.0
(for example in the same PR that introduced the BREAKING change on button
Then button gets released as v3.0.0
And the dialog
is not touched
This can be automated/generalised to:
If any change on a package is being released, rlsr
checks all dependants of the package
and only creates ACK releases if the new version is not covered in the dependants range.
That would also allow edge-cases where I deliberately fix a dependency or use a narrow range like ~3.2.1
OK. I put this into coding rules:
- For all bump types: related package has a fixed relation
=> it gets a caret range relation and patch bumped
(e.g.: package 1.1.0->1.2.0, dep 1.1.0->^1.2.0) - For patch and minor bumps: related package has a caret range relation to an older minor / patch version
=> do nothing
(e.g.: package 1.1.0->1.2.0, dep ^1.1.0->remains ) - For major bumps: related package has a caret range relation to an older minor / patch version
=> turn this into a hyphen range relation
(e.g.: package 1.1.0->2.0.0, dep ^1.1.0->1.1.0-2) - For patch and minor bumps: related package has a hyphen range relation to an older minor / patch version
=> do nothing
(e.g.: package 2.0.0->2.1.0, dep ^1.1.0-2->remains ) - For major bumps: related package has a hyphen range relation to an older minor / patch version
=> increase the range of the hyphen range relation
(e.g.: package 2.0.0->3.0.0, dep ^1.1.0-2->1.1.0-3 ) - For all other cases: Use manual manipulation (of the dependency package.json) an commit it separately with an appropriate message (usually you enter a caret range relation)
Totally agree with your description!
I think it can be implemented even simpler:
- For all bump types: check if the new version satisfies the dependency declaration in related package (f.e. using
nodeSemver.satisfies(version, range)
) - If that's the case: do nothing
- If that's not the case:
=> turn this into a hyphen range relation
(e.g.: package 1.1.0->2.0.0, dep ^1.1.0->1.1.0 - 2)
(e.g.: package 1.1.0->1.2.0, dep ~1.1.0->1.1.0 - 1)
(e.g.: package 1.1.0->1.1.1, dep 1.1.0->1.1.0 - 1)