gradlegroovybuild.gradlegradle-plugingradle-release-plugin

Gradle release composite build with a release order


I have a gradle composite build in following directory structure.

.
├── component-1
├── component-2
├── component-3
└── composite-build

Here, all components are multi-project builds. Each component has implemented the release plugin and can be released individually. The composite-build has following settings.gradle.

rootProject.name = 'composite-build'

includeBuild '../component-1'
includeBuild '../component-2'
includeBuild '../component-3'

I want to execute release task of each component in a specific order but I couldn't find a proper way. Following are some cases that I tried and failed. In these cases individual release tasks are also failing due to conflicting git tag commits done by release plugin.

Case 1:

In build.gradle

task releaseAll {
    dependsOn gradle.includedBuild('component-1').task(':release')
    dependsOn gradle.includedBuild('component-2').task(':release')
    dependsOn gradle.includedBuild('component-3').task(':release')
}

Case 2:

In build.gradle

task releaseComponent1 {
    dependsOn gradle.includedBuild('component-1').task(':release')
}

task releaseComponent2 {
    dependsOn gradle.includedBuild('component-2').task(':release')
}

task releaseComponent3 {
    dependsOn gradle.includedBuild('component-3').task(':release')
}

releaseComponent2.configure {
    mustRunAfter releaseComponent1
}

releaseComponent3.configure {
    mustRunAfter releaseComponent2
}

task releaseAll {
    dependsOn releaseComponent1
    dependsOn releaseComponent2
    dependsOn releaseComponent3
}

Sample error message:

> Task :component-1:component-1-release:preTagCommit FAILED
Running [git, commit, -m,  [Gradle Release Plugin] - pre tag commit:  'component-1-0.1.10'., -a] produced an error: []
Running [git, push, --porcelain, origin, main] produced an error: [error: failed to push some refs to 'https://github.com/<username>/<repo-name>.git']

> Task :component-1:release FAILED
Release process failed, reverting back any changes made by Release Plugin.
Running [git, checkout, gradle.properties] produced an error: [error: pathspec 'gradle.properties' did not match any file(s) known to git]

1: Task failed with an exception.
-----------
* What went wrong:
Execution failed for task ':component-1:component-1-release:preTagCommit'.
> Failed to push to remote - [To https://github.com/<username>/<repo-name>.git
  !     refs/heads/main:refs/heads/main [remote rejected] (cannot lock ref 'refs/heads/main': is at <xxxx> but expected <yyyy>)
  Done
  ][error: failed to push some refs to 'https://github.com/<username>/<repo-name>.git'
  ]

Solution

  • There is always an option with gradle where you can automate and link task execution with finalizedBy and you can test this simple code to check how it work :

    task A() {
        println 'taskA'
    }
    task B() {
        println 'taskB'
    }
    tasks.named("B") { finalizedBy("A") }
    
    task C() {
        println 'taskC'
    }
    tasks.named("C") { finalizedBy("B") }
    

    This way, by calling gradle C it will backtrack to execute A then B then C

    Same way, You can do 3 tasks to get the desired ordered execution like this

    task c1release(type:Exec) {
      workingDir '.\\component-1'
      commandLine("cmd", "/c", "gradle", "release")
         doLast {
             println "component-1 release is being excuted"
         }
    }
    tasks.named("c1release") { finalizedBy("c2release") }
    
    task c2release(type:Exec) {
      workingDir '.\\component-2'
      commandLine("cmd", "/c", "gradle", "release")
         doLast {
             println "component-2 release is being excuted"
         }
    }
    tasks.named("c2release") { finalizedBy("c3release") }
    
    
    task c3release(type:Exec) {
      workingDir '.\\component-3'
      commandLine("cmd", "/c", "gradle", "release")
         doLast {
             println "component-3 release is being excuted"
         }
    }
    tasks.named("releaseAll") { finalizedBy("c1release") }
    
    task releaseAll() {
        println "Start releasing"
    }
    

    by calling gradle releaseAll it will execute c1release first then c2release then c3release

    But I still wish ti know what kind of error you got with the cases you have included in your question.