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

Need to be able to force increment a release #325

Closed
john-tipper opened this issue Jan 27, 2020 · 4 comments · May be fixed by #326
Closed

Need to be able to force increment a release #325

john-tipper opened this issue Jan 27, 2020 · 4 comments · May be fixed by #326

Comments

@john-tipper
Copy link
Contributor

john-tipper commented Jan 27, 2020

With the new support for monorepos, there is an issue when a submodule depends on another module but there are no code changes within the dependent module, in that the dependent module does not have its version incremented.

For example, given a project with modules mod_a and mod_b, where both mod_a and mod_b are to be published as artifacts and also where mod_b is dependent on project(":mod_a"), then a change within mod_a will result in the version of mod_a being incremented, but the version of mod_b will not.

Within the Releaser class (https://github.com/allegro/axion-release-plugin/blob/master/src/main/java/pl/allegro/tech/build/axion/release/domain/Releaser.java#L31), there is a check to see if there are changes and if not (i.e. the version is not a snapshot) then the version will not increment. There does not appear to me to be an easy way to request that mod_b's version be incremented too (as opposed to forcing it to be a specific version via -Prelease.forceVersion=x.y.z).

Gradle has a buildNeeded and buildDependents task (c.g. docs here), where, for the example above, I could call :mod_a:buildDependents and :mod_a:build and :mod_b:build would be called.

Ideally, I think under CI/CD it would be nice to just call ./gradlew release and have the version(s) of the modules that changed be incremented (where we count a dependency between the modules as being a material change in the dependent module), even if there were no code changes to the code actually within the dependent modules.

I think this is loosely related to #314.

Whilst this sort of logic does not necessarily need to reside inside this plugin, it would be nice to document within the project how this sort of functionality could be achieved.

@adamdubiel, @kboom and @sradi, what are your thoughts here please?

@sradi
Copy link

sradi commented Jan 27, 2020

Our setup currently doesn't have this issue, as our repository is split into independent builds, which don't reference each other and are only connected through a composite build configuration.

But in another build I have the requirement to build and publish only JARs of those modules, that actually changed. I think the key to achieve this is, to have all inputs of the jar task unchanged, so that it's skipped with 'UP-TO-DATE'.
One important input is the version of the module, but other inputs are the dependencies and the module's output directory.

In my opinion, this feature cannot be accomplished with the axion-release plugin, as long as it is focused on changes in git. This feature needs some sort of dynamic version calculation, where the decision, if the version needs to be incremented, is based on the jar task's inputs.
@john-tipper does this sound related to your goal or am I completely off track?

I recently started a discussion with gradle about my requirement. If there are any suggestions, they can provide, I am going to share them with you.

@john-tipper
Copy link
Contributor Author

I've gone through what the Java plugin does to resolve this and I think we can at least support incrementing the version across dependent modules. Here's what I propose, covering this issue and #314 .

For this issue:

  1. Add a check of a boolean forceIncrementVersion parameter within the if in Releaser and if it is set to true then return a version, same as if versionContext.isSnapshot() is true at present. The parameter will be passed to the release() and releaseAndPush() methods.
  2. I don't think we want to lose the idempotency of the release tasks (repeated calls don't repeatedly generate new releases), so we just change the way Releaser is called from a ReleaseTask or CreateReleaseTask such that the parameter is passed in to Releaser by these tasks (i.e. user cannot specify this config directly, it would only happen if one of the tasks mentioned below is called, see below for details).

For #314, follow the approach taken by the Gradle core Java plugin:

  1. Create 2 new tasks, createReleaseDependents and releaseDependents, where createXXX depends on createRelease and releaseXXX depend on release, respectively. This will be done as per the java plugin, here: https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/plugins/JavaPlugin.java#L396-L411

  2. Add a downstream dependency on projects that refers to their createReleaseDependents/releaseDependents tasks, as per https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/java/org/gradle/api/plugins/JavaPlugin.java#L508-L523, i.e. calling releaseDependents on a project will call (via dependsOn) the release task in that project and then also releaseDependents within all projects that depend on that project, in dependency order, i.e. the release task will be cascaded down the dependency tree.

  3. CreateReleaseTask and ReleaseTask need to be configured such that their internal forceIncrementVersion property is set to true (i.e. even if there are no direct code changes within a submodule, these tasks will still increment the version by calling Releaser.release() or Releaser.releaseAndPush() with forceIncrementVersion=true). We will have a helper task called configureReleaseTasks that will be configured as a dependency on createReleaseDependents/releaseDependents and set to run before CreateReleaseTask and ReleaseTask which will set the forceIncrementVersion property on those tasks (e.g. execution order for releaseDependents would be configureReleaseTasks, release, releaseDependents. Doing this means we don't need to change the behaviour of release via configuration: we inject this value only if releaseDependents is called, but because of the task dependency ordering, releaseDependents will occur after release, hence we need to have a different task that will fire before release that will actually inject our forceIncrementVersion into the appropriate task (CreateReleaseTask and ReleaseTask).

This proposal would result in no breaking changes to any existing project. Only if the new tasks (createReleaseDependents/releaseDependents) are called would there be any new behaviour and this behaviour would not require any new complexity via further configuration changes.

Does anyone have any objections to this approach and are you happy for me to put together a PR for people to have a look at?

@john-tipper
Copy link
Contributor Author

I have managed to come up with a working implementation. It differs in implementation somewhat from the description above, in that I discovered that the version incrementing is performed by VersionFactory, hence it needs to have a flag passed to it that indicates that the version should be incremented, even if there are no changes within that submodule.
The code is non-breaking and retains the idempotency of the release process, i.e. multiple calls to release do not result in multiple releases being created, even across submodules. Details are in PR #326.

john-tipper added a commit to john-tipper/axion-release-plugin that referenced this issue Jan 29, 2020
john-tipper added a commit to john-tipper/axion-release-plugin that referenced this issue Jan 30, 2020
@TabraizChel
Copy link

TabraizChel commented May 10, 2022

@john-tipper Was this ever resolved as I have the same issue

@bgalek bgalek closed this as not planned Won't fix, can't repro, duplicate, stale Feb 16, 2024
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 a pull request may close this issue.

4 participants