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

CurrentVersion is immediately SNAPSHOT after release #332

Closed
JozoVilcek opened this issue Apr 25, 2020 · 31 comments
Closed

CurrentVersion is immediately SNAPSHOT after release #332

JozoVilcek opened this issue Apr 25, 2020 · 31 comments

Comments

@JozoVilcek
Copy link

JozoVilcek commented Apr 25, 2020

Hi, I have a git repository, monorepo, hosting many independent projects. Each projects pulls in axion-release-plugin configures is prefixTag and does it's own release cycles.

The release process is essentialy 1.) check the build, 2) release, 3) build deployable artifact for released version. This process relies on the fact that if cV is e.g. 1.0.1-SNAPSHOT then right after release it will be 1.0.1, therefore, without snapshot.

This works fine up to axion v1.10.3. In v1.11.0 it breaks. After release, the cV for the above gives 1.0.2-SNAPSHOT. I think the change is introduced here: 7202376

In VersionResolver the ScmPosition position = repository.currentPosition() is changed to
latestChangePosition = repository.positionOfLastChangeIn(projectRootRelativePath, versionRules.monorepoProperties.dirsToExclude)

In case of multiple coexisting projects, it is very likely to not to be on the last change for project for which release is being done (something merged to master between merge of a project and invoking a release). Then boolean onCommitWithLatestChange = currentVersionInfo.commit == latestChangePosition.revision is going to be false and this will set VersionInfo.onReleaseTag to false and leads to isSnapshot.

If my conclusion is correct, then how do I get the correct release version (non snapshot) right after performing a release?

@sradi
Copy link

sradi commented May 6, 2020

I am having that issue, too.

@sradi
Copy link

sradi commented May 6, 2020

After short analysis it seems, that the attribute projectDirs of the monorepos configuration is empty, when the currentVersion task is executed.
If it was set correctly, the lastChangePosition would probably be calculated correctly, so that the resulting value of onCommitWithLatestChange would be true, as expected.

@sradi
Copy link

sradi commented May 6, 2020

@john-tipper would you mind, having a look?

@adamdubiel
Copy link
Collaborator

adamdubiel commented May 31, 2020

I suspect that this could have something to do with the way plugin is initialized. If dirsToExclude is set using some gradle project.projectDir and is empty for currentVersion, then it might be because of how scmVersion being eager (not lazy).

I know that Gradle introduced mechanisms for lazy loading of properties some time ago, meaning project.version = scmVersion.version could be evaluated later in the cycle, which probably would fix a lot of issues.

(sorry for closing, it was a misclick)

@sradi
Copy link

sradi commented May 31, 2020

Not sure, if it's possible to access scmVersion.version lazily, since...

  1. ...Gradle needs to know the actual value of project.version during the configuration phase.
  2. ...lazy configuration (afaik) works for task implementations only, which VersionConfig.getVersion() is not. (Custom) tasks with lazy properties can evaluate the actual value of an extension property during execution time, and only if that task actually needs to be executed.

I think I ran the VersionResolverSubfolderTest few weeks ago, after adding an excluded subfolder 'foo' here:


Still, the projectDirs of the Monorepo configuration were empty.

@adamdubiel
Copy link
Collaborator

Uh, I was hoping to make it lazy, but didn't start playing with it yet. Thanks for the info! I will try to experiment anyways, but with less hope :)

@sradi
Copy link

sradi commented Jun 9, 2020

Hi @adamdubiel - could you already find out more about the cause of this issue?

@gustavkarlsson
Copy link

I'm having the same issue in my project.

It's open source so you could easily verify it yourself:

$ git clone https:/gustavkarlsson/skylight-android.git
$ cd skylight-android
$ git checkout 1.2.1
$ ./gradlew cV

prints:

Project version: 1.2.2-SNAPSHOT

@adamdubiel
Copy link
Collaborator

Thanks for providing this repo! I think I uncovered a serious problem introduced along with monorepo support. This should have been tested by me :/

FYI @john-tipper @sradi it seems like monorepo support feature toggle is needed after all. Without it calculating any multimodule project version works in monorepo mode. I added integration test for this case and need to think of a solution. So far I think that some kind of monorepo.enabled will be required.

@f4lco
Copy link
Contributor

f4lco commented Mar 2, 2021

+1 for the monorepo feature toggle. I got bitten by this as well (f4lco/libyear-gradle-plugin@ba7cba7).

To paraphrase:

In case of multiple coexisting projects, it is very likely to not to be on the last change for project for which release is being done (something merged to master between merge of a project and invoking a release).

If I want to release, and the last change for this feature set touched the top-level README, the Gradle project in a separate folder will have a -SNAPSHOT version, despite the fact that HEAD carries a release tag.

@LWogan
Copy link

LWogan commented Mar 24, 2021

This issue is a blocker for anyone wanting to use this plugin when they have a multi gradle project monorepo.

When a release for a subproject tags the repo it tags the most recent commit in the monorepo with the release regardless of what project it is from. However when it is trying to derive the current version for a subproject, if the most recent commit is in the root project or any other sub project then it will think it is ahead of the commit on the latest released tag when it is actually behind it.

As pointed out by the first poster boolean onCommitWithLatestChange = currentVersionInfo.commit == latestChangePosition.revision is going to be false. currentVersionInfo will likely be a commit to a different project. The latestChangePosition is the latest commit to the current subproject.

This needs to be changed to something like: is latestChangePosition ahead of the most recent commit with a tag matching the pattern.

It should be noted that this wasn't an issue for multi gradle project monorepos before monorepo support was added in 1.11.0. However an important part of the monorepo support was the change to allow subprojects to be prefixes of each other in tags. This only came in 1.11.0. It would be really nice if this change was patched to 1.10.0 as a temporary solution. #307. I'm brand new to this project so I'm not sure who to ask to do that @bgalek / @adamdubiel ?

I would be interesting in trying to fix the core issue in 1.12.1 if I have time this week.

@tjuszczyk
Copy link

Hi @adamdubiel,
Is there any recommended workaround for this issue, especially if team would like to start using gradle 7.x?
With gradle 7.x using axion-release-plugin 1.10.x is not an option because axion tasks properties are missing an input or output annotation.

@bgalek
Copy link
Member

bgalek commented Aug 5, 2021

@tjuszczyk master snapshot already supports gradle 7.x, yet as I understand this issue the behaviour of latest versions are different then old ones

@tjuszczyk
Copy link

Hi @bgalek
Yes. Currently released version as all releases starting from v1.11.0 have broken behaviour for monorepos.
As described in the issue, straight after successful release currentVersion returns next -SNAPSHOT version, not the one just released.
Version 1.10.x on the other hand does not work with gradle 7.x

@shashken
Copy link
Contributor

shashken commented Aug 8, 2021

Is there an estimate for a fix for this? @bgalek @adamdubiel
I have a monorepo repository and gradle release gradle publish results in -SNAPSHOT versions (gradle 7.0 and no option to go back ATM)

@shashken
Copy link
Contributor

shashken commented Aug 10, 2021

I think I might have been able to solve this with the new version with a workaround, invoking scmVersion.getMonorepoConfig().projectDirs before the version get to avoid the lazy load problem in the new versions of the plugin + gradle. Unless I missed something this worked with axion & gradle latest versions (1.13.3, 7.1.1)
example:
global build.gradle

allprojects {
...
    scmVersion {
        tag.prefix = "${project.name}-"
        monorepos {
            projectDirs = project.getRootProject().subprojects.collect({p -> relativePath(p.projectDir.path)})
        }
        versionCreator 'versionWithBranch'
    }
...
}

and in each project:

scmVersion.getMonorepoConfig().projectDirs  // To fix the lazy load of version
project.version = scmVersion.version

@farrukhnajmi
Copy link

farrukhnajmi commented Sep 30, 2021

I have the same monorepo use case and am faced with the same issue as OP. It is a serious blocker for using this excellent plugin. Would be grateful if someone knowledgeable / dev team can comment on any workarounds that are confirmed to work and plan for a fix.

Note that I tried the workaround suggested by @shashken but it did not work.

@shashken
Copy link
Contributor

shashken commented Oct 3, 2021

I get flaky results now with the workaround I suggested, I noticed that when I'm doing normal merge (not squash commits) it does not detect the version and I get a snapshot (straight after a release like OP suggested)
Now when I looked into this I saw that this line might cause the problems:

lastCommit = jgitRepository.log().setMaxCount(1).addPath(unixStylePath).call().iterator().next();

The problem there as I understood it is that addPath causes the git tree search to ignore the latest commit (the merge to master) and find the last commit in the subtree as the latest one, this causes the tag (that is on the proper commit) to be different from the latest commit found for the path and for the version to be detected as snapshot. (saw all this when I attached a debugger to the run of the plugin)

  • Note that im not 100% about this, my groovy is pretty bad and i never commited to this repo, just found it thought it was awesome and wanted to use it. Please if there is a maintainer here that can help us it would be awesome! @farrukhnajmi @bgalek

@farrukhnajmi
Copy link

farrukhnajmi commented Oct 3, 2021 via email

@bgalek
Copy link
Member

bgalek commented Oct 4, 2021

Hi all! First of all we need a test specifying the behavior, then we can try to fix it. @shashken @farrukhnajmi I'll be happy to review the changes if you start a PR :)

@shashken
Copy link
Contributor

shashken commented Oct 6, 2021

@bgalek I made a PR, can you please review it? #422

@marclohrer
Copy link

Are there concrete plans as to when a fixed version will be available?
This bug is currently a real showstopper for our project and we have to decide whether we can wait for a solution or have to switch to an alternative way to handle our versioning.

@shashken
Copy link
Contributor

shashken commented Oct 18, 2021

@marclohrer I have a solution for this problem at #422 @bgalek said there that we might be able to merge today.
Either way you can try to use the snapshot version to see if it works until it gets merged:
build the local shadow jar of the plugin then:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath files('/path/to/axion-release-plugin-1.13.4-full_monorepo_support-SNAPSHOT.jar')
    }
}

...

apply plugin: 'pl.allegro.tech.build.axion-release'

@marclohrer
Copy link

@shashken Thanks for the quick answer. I gave it a try as you proposed but failed badly when instantiating the plugin.
"gradlew cV" triggered an error:

Failed to apply plugin 'pl.allegro.tech.build.axion-release'.
Could not create an instance of type pl.allegro.tech.build.axion.release.domain.VersionConfig.
> Receiver class pl.allegro.tech.build.axion.release.domain.TagNameSerializer does not define or inherit an implementation of the resolved method 'abstract java.lang.Object getProperty(java.lang.String)' of interface groovy.lang.GroovyObject.

I'm sure I miss something obvious, but if you intend to release the fix soon now I'm happy to wait for the release.

@bgalek
Copy link
Member

bgalek commented Oct 18, 2021

Yes, I'lm reviewiewing all changes in this release and I'm going to publish it today!

@marclohrer
Copy link

@bgalek Thanks for the quick release. However something fundamental seems broken.
Boilerplate:

  • empty test project (gradle init), gradle version 6.8.1
  • build.gradle plugins section: id 'pl.allegro.tech.build.axion-release' version '1.13.4'

Now any gradle task fails with this error:

An exception occurred applying plugin request [id: 'pl.allegro.tech.build.axion-release', version: '1.13.4']
Failed to apply plugin 'pl.allegro.tech.build.axion-release'.
Could not create an instance of type pl.allegro.tech.build.axion.release.domain.VersionConfig.
> Receiver class pl.allegro.tech.build.axion.release.domain.TagNameSerializer does not define or inherit an implementation of the resolved method 'abstract java.lang.Object getProperty(java.lang.String)' of interface groovy.lang.GroovyObject.

What am I missing? Only the new 1.13.4 version shows this problem.

@shashken
Copy link
Contributor

Those doesn't seem related to the change I made, maybe #425 .
I am running gradle 7.1.1. maybe give it a try.

@marclohrer
Copy link

@shashken Confirmed. 1.13.4 works with gradle 7.2. Thanks.
@bgalek It's not an issue for me now, but the gradle6 compatibility will be fixed, right?

@bgalek
Copy link
Member

bgalek commented Oct 19, 2021

@marclohrer yes, I'll fix it ASAP, I'll also need to think a way to test it cross gradle version ;(

@bgalek
Copy link
Member

bgalek commented Oct 19, 2021

https:/allegro/axion-release-plugin/releases/tag/v1.13.5 fixed backward compability

@marclohrer
Copy link

@bgalek Confirmed, 1.13.5 works now with gradle6. Thanks for the quick fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests