xing/rlsr

Create as little ACK-releases as possible and keep ranges as open as possible

Closed this issue · 3 comments

Xiphe commented

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

Xiphe commented

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)
Xiphe commented

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)