First and formost... I'm new to Gradle. Having said that, I love it. Unfortunatly, I've hit a snag. I have a series of tasks that are part of a deploy process. One (buildProject
) Calls a shell script, that as part of it's process updates a REVISION
file with the new "version". After that the deployToRemote
task is called to deploy the latest version to the server. It calls getCurrentVersion
to read the latest version from the REVISION
file. All of these tasks are outlined below. The problem is that it appears that getLatestVersion
is called first in spite of proper mustRunAfter
statements, as it always reads in the "PRE" buildProject
version listed in the REVISION
file. How can I make sure that getLatestVersion
reads the file after buildProject
runs?
Here are the tasks:
buildProject:
task buildProject(type:Exec) {
def command = ['./make-release', '-f']
if (deployEnvironment != 'stage') {
command = ['./make-release', "-e ${deployEnvironment}"]
}
commandLine command
}
deployToRemote
task deployToRemote(dependsOn: 'getCurrentVersion') {
doLast {
def version = tasks.getCurrentVersion.hash()
println "Using version ${version}"
println "Using user ${webhostUser}"
println "Using host ${webhostUrl}"
ssh.run {
session(remotes.webhost) {
put from: "dist/project-${version}.tar.gz", into: '/srv/staging/'
execute "cd /srv/staging; ./manual_install.sh ${version}"
}
}
}
}
getCurrentVersion
task getCurrentVersion {
def line
new File("REVISION").withReader { line = it.readLine() }
ext.hash = {
line
}
}
My build.gradle
file has this at the end:
deployToRemote.mustRunAfter buildProject
getCurrentVersion.mustRunAfter buildProject
The REVISION
file looks like this;
1196.dev10
919b642fd5ca5037a437dac28e2cfac0ea18ceed
dev
Gradle build has three phases: Initialization, Configuration and Execution.
The problem you faced is that code in getCurrentVersion
is executed in the configuration phase. In the configuration phase the code in tasks is executed in the order of their definition and dependencies are not taken into account.
Consider this example:
task second(dependsOn: 'first') {
println 'second: this is executed during the configuration phase.'
doLast {
println 'second: This is executed during the execution phase.'
}
}
task first {
println 'first: this is executed during the configuration phase.'
doLast {
println 'first: This is executed during the execution phase.'
}
}
second.mustRunAfter first
If you execute gradle -q second
you'll get:
second: this is executed during the configuration phase.
first: this is executed during the configuration phase.
first: This is executed during the execution phase.
second: This is executed during the execution phase.
To fix your script you need to put the code into doLast
like this:
task getCurrentVersion {
doLast {
def line
new File("REVISION").withReader { line = it.readLine() }
ext.hash = {
line
}
}
}