I am trying to have multiple Gradle tasks in my build.gradle
file to deploy a war to different environments. I want to be able to have a deployToLocal
task along with deployToQA
and deployToDev
, after a war file has been generated.
Of course, this means that I want to stop the Tomcat service, delete existing war files and expanded wars in the Tomcat webapps directory, copy the war, and restart Tomcat again to deploy the service.
My question is twofold:
My code so far:
task deleteDirLocalhost(type: Delete){
//delete fileTree(dir: local_Tomcat_webapps_dir)
delete fileTree(dir: 'C:\\Tomcat7.0\\webapps')
}
task deployToLocal{
dependsOn war, tomcatStop, deleteDirLocalhost
println "Starting Cargo"
println "Using war from: $warLocation" // warLocation is a variable defined in gradle.properties file
cargo {
containerId = 'tomcat7x'
port = TomcatPortLocalhost as Integer
local {
homeDir = file(local_Tomcat_webapps_dir) // local_Tomcat_webapps_dir is a variable defined in gradle.properties file
}
deployable {
file = file(warLocation) // This is where I specify where the war file is to be copied from. In the 'local' section, I have specified 'homeDir' as the location where I want this file to be copied to. Is that correct usage?
context = 'web-application'
}
}
tomcatRunWar
}
task deployToQA{
dependsOn war, tomcatStop, deleteDirQA
println "Starting Cargo"
println "Using war from: $warLocation"
cargo {
containerId = 'tomcat7x'
port = TomcatPortQA as Integer
remote {
hostname = server_address_qa // all these are variables defined in the gradle.properties file
username = username_qa
password = password_qa
}
deployable {
file = file(warLocation) // This is where I specify the location of the war file. How do I specify in the 'remote' section in which directory in the server this file should be copied to?
context = 'web-application'
}
}
tomcatRunWar
}
task deployToDev{
dependsOn war, tomcatStop, deleteDirDev
println "Starting Cargo"
println "Using war from: $warLocation"
cargo {
containerId = 'tomcat7x'
port = TomcatPortDev as Integer
remote {
hostname = RT3_webapp_address_dev
username = username_dev
password = password_dev
}
deployable {
file = file(warLocation)
context = 'web-application'
}
}
tomcatRunWar
}
I want to call task gradle deployToLocal
and expect the behavior that local Tomcat instance is stopped, the war is copied to my Tomcat\webapps folder (with any previously existing files or folders in the same folder having been deleted), and then the Tomcat service is started again and the war is deployed.
This doesn't work, and obviously I am missing something. I also scoured the web for a solid fully-worked-out example of an implementation of the gradle cargo/ tomcat plugin without much luck. Could someone please point me in the right direction?
Thank you in advance for any help!
The Tomcat and the Cargo plugins are two distinct plugins and do not work with one another in the way your tried to solve your problem. The Tomcat plugin only provides an in-memory, embedded container for Tomcat (meaning you don't have to have a local installation) whereas Cargo requires you to either point to a local container installation or a remote URL. For your purposes, I'd exclusively go with the Cargo plugin.
All the code you define in your tasks is executed during the configuration phase. Using the DSL of the Cargo plugin in multiple tasks will override the previous declaration. For a better understanding on execution vs. configuration phase, I'd recommend checking the Gradle online user guide. Keep in mind that Cargo in general does not provide management functionality for remote containers (starting/stopping). This was also mentioned in the README file of the plugin. If you want to do something like that, you'd have to write tasks that run remote SSH commands.
Apart from not being able to start/stop containers with the plugin, your actual problem can be solved in multiple ways. Either you use the Cargo plugin DSL and assign the remote hostname, port, username, password dynamically or you create multiple tasks. It seems like you still want to create multiple tasks for each environment. For that apply the cargo-base
plugin and create two tasks of type CargoDeployRemote
, one for your dev and one for your QA environment. In that scenario you are not using the DSL exposed by the plugin. Of course you'd create another task for your local Tomcat installation as well with the appropriate task type.
apply plugin: 'cargo-base'
import com.bmuschko.gradle.cargo.convention.Deployable
import com.bmuschko.gradle.cargo.tasks.remote.CargoDeployRemote
task deployToQA(type: CargoDeployRemote) {
containerId = 'tomcat7x'
hostname = server_address_qa
port = TomcatPortQA as Integer
username = username_qa
password = password_qa
deployables = [new Deployable(file: file(warLocation), context: 'web-application')]
}