axion-release-plugin icon indicating copy to clipboard operation
axion-release-plugin copied to clipboard

Incomplete multi-module documentation

Open mklueh opened this issue 3 years ago • 5 comments

Hello,

it is likely the multi-module project documentation is incomplete https://axion-release-plugin.readthedocs.io/en/latest/configuration/basic_usage/#multi-module-project

Here for example I've asked sb about his Gradle config and it turns out you need the scmVersion{} not only in the root of the project but in the subprojects as well. But then Im wondering why you need it even in the root project, because it would generate a version for the root as well which in case of a monorepo makes no sense imo.

I think there should be a full example in the docs, especially if there are edge cases so people won't have to struggle for days to get it up and running. Would be great if the owners would add it.

My current setup looks like this (root build.gradle):

//tell the plugin that we want all modules to be affected that sit in the applications module
scmVersion {
    monorepos {
        projectDirs = project.subprojects.stream()
                 /*
                  * the variable name is a bit misleading - we need to give the plugin a list of modules 
                  * that should NOT be used for the projectDirs property
                  */
                .filter(p -> "applications" != p.getParent().name)
                .map(p -> p.name)
                .collect(Collectors.toList())
    }
}


/**
   *  we apply the plugin and the `scmVersion{}` config 
   *  to all of the modules sitting in the applications directory
   */
subprojects.stream()
        .filter(p -> "applications" == p.getParent().name)
        .forEach(p -> {
            p.configure(p) {
                apply plugin: 'pl.allegro.tech.build.axion-release'
                scmVersion {
                    useHighestVersion = true
                    versionCreator 'versionWithBranch'
                    repository {
                        pushTagsOnly = true
                    }
                    tag {
                        /*
                         * prevent conflicts with the plugin in case the project name 
                         * has the same separator as the tag separator
                         * /
                        prefix = project.name.replace('-', '_')
                        versionSeparator = "-"
                    }
                    nextVersion {
                        suffix = 'alpha' // tag suffix
                        separator = '-'
                    }
                    checks {
                        aheadOfRemote = true
                        uncommittedChanges = true
                        snapshotDependencies = false
                    }
                }

                project.version = scmVersion.version
            }
        })

While it works locally, I think something is off / missing, as the task fails with an exception pl.allegro.tech.build.axion.release.ReleaseFailedException (no error message) that does not tell me anything in Github CI

> Task :applications:my-application:release
Working on released version 0.1.0, nothing to release
Pushing all to remote: origin
12 actionable tasks: 12 executed

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':applications:my-application:release'.
> pl.allegro.tech.build.axion.release.ReleaseFailedException (no error message)

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.

* Get more help at https://help.gradle.org/

BUILD FAILED in 19s

mklueh avatar May 20 '22 06:05 mklueh

@mklueh thx! would you like to make a PR with your suggestions in docs? :) I'll be happy to merge

bgalek avatar May 20 '22 07:05 bgalek

@bgalek happy to do so if I manage to get it working. Do you have any opinion on the error message and the configs? Do you see any mistake there?

Also, it seems that there is also a version for the root project. Is there any chance to suppress versioning for the root in a multi module?

mklueh avatar May 20 '22 07:05 mklueh

@mklueh sorry, but provided fragment does not ring any bell without all other context (tags, repository layout, build.gradle files etc.) Of course, error message could be better.... have you tried looking on it with --stacktrace option?

bgalek avatar May 20 '22 09:05 bgalek

@bgalek sry, of course.

I split this into two problems, the first is kind of solved, although this configuration makes no sense to me

First problem

So it seems it is trying to create a version for the application, which is correctly determined. The last one in existence is 0.1.1 and it creates 0.1.2.

However, according to the exception, it then also tries to push the version of the root of the project 0.1.9 which already exists in my repository.

This is also why I assumed something must be wrong with my setup because my root is just a shell for the applications and does not necessarily need its own version and I do not know why it even tries to generate it, as I don't have this line for my root project

> Task :applications:my-application:release
Working on released version 0.1.2, nothing to release
Pushing all to remote: origin
	at org.gradle.internal.execution.steps.CaptureStateBeforeExecutionStep.execute(CaptureStateBeforeExecutionStep.java:50)
6 actionable tasks: 6 executed
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.executeWithNoEmptySources(SkipEmptyWorkStep.java:249)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:86)
	at org.gradle.internal.execution.steps.SkipEmptyWorkStep.execute(SkipEmptyWorkStep.java:54)
	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:32)
	at org.gradle.internal.execution.steps.RemoveUntrackedExecutionStateStep.execute(RemoveUntrackedExecutionStateStep.java:21)
	at org.gradle.internal.execution.steps.legacy.MarkSnapshottingInputsStartedStep.execute(MarkSnapshottingInputsStartedStep.java:38)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:43)
	at org.gradle.internal.execution.steps.LoadPreviousExecutionStateStep.execute(LoadPreviousExecutionStateStep.java:31)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.lambda$execute$0(AssignWorkspaceStep.java:40)
	at org.gradle.api.internal.tasks.execution.TaskExecution$4.withWorkspace(TaskExecution.java:287)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:40)
	at org.gradle.internal.execution.steps.AssignWorkspaceStep.execute(AssignWorkspaceStep.java:30)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:37)
	at org.gradle.internal.execution.steps.IdentityCacheStep.execute(IdentityCacheStep.java:27)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:44)
	at org.gradle.internal.execution.steps.IdentifyStep.execute(IdentifyStep.java:33)
	at org.gradle.internal.execution.impl.DefaultExecutionEngine$1.execute(DefaultExecutionEngine.java:76)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:144)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:133)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:333)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:320)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:313)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:299)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:143)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:227)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:218)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:140)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
Caused by: axion.org.eclipse.jgit.api.errors.RefAlreadyExistsException: tag 'Tag={
object 72634d0f97739c682211ddcf16c0c57369659d4c
type commit
tag v0.1.9
tagger PersonIdent[runner, runner@fv-az196-178.jtpmctcvnzqejnuy0st5dkw3nb.bx.internal.cloudapp.net, Sat May 21 07:57:47 2022 +0000]

}' already exists
	at axion.org.eclipse.jgit.api.TagCommand.updateTagRef(TagCommand.java:[188](https://github.com/my-repo/my-project/runs/6535661944?check_suite_focus=true#step:6:189))
	at axion.org.eclipse.jgit.api.TagCommand.call(TagCommand.java:152)
	at pl.allegro.tech.build.axion.release.infrastructure.git.GitRepository.tag(GitRepository.java:106)
	... 124 more


* Get more help at https://help.gradle.org/

Solving the first problem

When I change the scmVersion{} of the root project from

scmVersion {
    monorepos {
        projectDirs = project.subprojects.stream()
                 /*
                  * the variable name is a bit misleading - we need to give the plugin a list of modules 
                  * that should NOT be used for the projectDirs property
                  */
                .filter(p -> "applications" != p.getParent().name)
                .map(p -> p.name)
                .collect(Collectors.toList())
    }
}

to this instead

scmVersion {
    useHighestVersion = true
    versionCreator 'versionWithBranch'
    repository {
        pushTagsOnly = true
    }
    tag {
        prefix = "my-root-project"
        versionSeparator = "-"
    }
    nextVersion {
        suffix = 'alpha' // tag suffix
        separator = '-'
    }
    monorepos {
        projectDirs = project.subprojects.stream()
                .filter(p -> "applications" != p.getParent().name)
                .map(p -> p.name)
                .collect(Collectors.toList())
    }
}

Second problem

I'm running into pl.allegro.tech.build.axion.release.ReleaseFailedException (no error message)

FAILURE: Build failed with an exception.

Execution failed for task ':applications:my-application:release'.
> pl.allegro.tech.build.axion.release.ReleaseFailedException (no error message)
Looking for uncommitted changes.. 

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':applications:my-application:release'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:147)
	at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:145)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:133)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
	at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:56)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:[52](https://github.com/my-repo/my-project/runs/6535822226?check_suite_focus=true#step:6:53))
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:[53](https://github.com/my-repo/my-project/runs/6535822226?check_suite_focus=true#step:6:54))
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
	at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:74)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:333)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:320)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:313)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:299)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.lambda$run$0(DefaultPlanExecutor.java:143)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:227)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.executeNextNode(DefaultPlanExecutor.java:218)
	at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:140)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:[64](https://github.com/my-repo/my-project/runs/6535822226?check_suite_focus=true#step:6:65))
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
Caused by: pl.allegro.tech.build.axion.release.ReleaseFailedException: 


* Get more help at https://help.gradle.org/

BUILD FAILED in 45s

And here I'm stuck

mklueh avatar May 21 '22 08:05 mklueh

Me again, I have still not managed to get it working in my project, but I think the easiest way it would work would be to disable the tag generation of the root project because this always causes trouble with tags that are already existing for some reason

Is this possible somehow? @bgalek

mklueh avatar Jun 04 '22 09:06 mklueh