Gradle builds can resolve dependencies, deploy artifacts and publish build-info to Artifactory.
Gradle Compatibility
The minimum Gradle version supported is 4.10
To run Gradle builds with Artifactory from your Pipeline script, you first need to create an Artifactory server instance, as described at the beginning of this article.
Here's an example:
def server = Artifactory.server 'my-server-id'
The next step is to create an Artifactory Gradle Build instance:
def rtGradle = Artifactory.newGradleBuild()
Now let's define where the Gradle build should download its dependencies from. Let's say you want the dependencies to be resolved from the 'libs-release' repository, located on the Artifactory server instance you defined above. Here's how you define this, using the Artifactory Gradle Build instance we created:
rtGradle.resolver server: server, repo: 'libs-release'
Now let's define where our build artifacts should be deployed to. Once again, we define the Artifactory server and repositories on the 'rtGradle' instance:
rtGradle.deployer server: server, repo: 'libs-release-local'
If you're using gradle to build a project, which produces maven artifacts, you also have the option of defining two deployment repositories - one repository will be used for snapshot artifacts and one for release artifacts. Here's how you define it:
rtGradle.deployer server: server, releaseRepo: 'libs-release-local', snapshotRepo: 'libs-snapshot-local'
Gradle allows customizing the list of deployed artifacts by defining publications as part fo the Gradle build script. Gradle publications are used to group artifacts together. You have the option of defining which of the defined publications Jenkins should use. Only the artifacts grouped by these publications will be deployed to Artifactory. If you do not define the publications, a default publication, which includes the list of the produced artifacts by a java project will be used. Here's how you define the list of publications:
rtGradle.deployer.publications.add("mavenJava").add("ivyJava")
If you'd like to deploy the artifacts from all the publications defined in the gradle script, you can set the "ALL_PUBLICATIONS" string as follows.
rtGradle.deployer.publications.add("ALL_PUBLICATIONS")
By default, all the build artifacts are deployed to Artifactory. In case you want to deploy only some artifacts, you can filter them based on their names, using the 'addInclude' method. In the following example, we are deploying only artifacts with names that start with 'frog'
rtGradle.deployer.artifactDeploymentPatterns.addInclude("frog*")
You can also exclude artifacts from being deployed. In the following example, we are deploying all artifacts, except for those that are zip files:
rtGradle.deployer.artifactDeploymentPatterns.addExclude("*.zip")
And to make things more interesting, you can combine both methods. For example, to deploy all artifacts with names that start with 'frog', but are not zip files, do the following:
rtGradle.deployer.artifactDeploymentPatterns.addInclude("frog*").addExclude("*.zip")
If you'd like to add custom properties to the deployed artifacts, you can do that as follows:
rtGradle.deployer.addProperty("status", "in-qa").addProperty("compatibility", "1", "2", "3")
By default, 3 threads will be used for uploading the artifacts to Artifactory. You can modify the number of threads used as follows:
rtGradle.deployer.threads = 6
In some cases, you want to disable artifacts deployment to Artifactory or make the deployment conditional. Here's how you do it:
rtGradle.deployer.deployArtifacts = false
In case the "com.jfrog.artifactory" Gradle Plugin is already applied in your Gradle script, we need to let Jenkins know it shouldn't apply it. Here's how we do it:
rtGradle.usesPlugin = true
In case you'd like to use the Gradle Wrapper for this build, add this:
rtGradle.useWrapper = true
If you don't want to use the Gradle Wrapper, and set a Gradle installation instead, you should define a Gradle Tool through Jenkins Manage, and then, set the tool name as follows:
rtGradle.tool = 'gradle tool name'
In case you'd like Gradle to use a different JDK than your build agent's default, no problem.
Simply set the JAVA_HOME environment variable to the desired JDK path (the path to the directory above the bin directory, which includes the java executable).
Here's you do it:
env.JAVA_HOME = 'path to JDK'
OK, looks like we're ready to run our Gradle build. Here's how we define the build.gradle file path (relative to the workspace) and the Gradle tasks. The deployment to Artifactory is performed as part of the 'artifactoryPublish' task:
def buildInfo = rtGradle.run rootDir: "projectDir/", buildFile: 'build.gradle', tasks: 'clean artifactoryPublish'
The above method runs the Gradle build. Notice that the method returns a buildInfo instance, which can be later published to Artifactory.
In some cases though, you'd like to pass an existing buildInfo instance to be used by the build. This can come in handy is when you want to set custom build name or build number on the build-info instance, or when you'd like to aggregate multiple builds into the same build-info instance. Here's how you pass an existing build-info instance to the rtGradle.run method:
rtGradle.run rootDir: "projectDir/", buildFile: 'build.gradle', tasks: 'clean artifactoryPublish', buildInfo: existingBuildInfo
By default, the build artifacts will be deployed to Artifactory, unless the rtGradle.deployer.deployArtifacts property was set to false. This can come in handy in two cases:
You do not wish to publish the artifacts.
You'd like to publish the artifacts later down the road. Here's how you can publish the artifacts at a later stage:
rtGradle.deployer.deployArtifacts buildInfo
Make sure to use the same buildInfo instance you received from the rtGradle.run method. Also make sure to run the above method on the same agent that ran the rtGradle.run method, because the artifacts were built and stored on the file-system of this agent.
What about the build-info?
The build-info has not yet been published to Artifactory, but it is stored locally in the 'buildInfo' instance returned by the 'run' method. You can now publish it to Artifactory as follows:
server.publishBuildInfo buildInfo
You can also merge multiple buildInfo instances into one buildInfo instance and publish it to Artifactory as one build, as described in the Publishing Build-Info to Artifactory section in this article.
That's it! We're all set.
The rtGradle instance supports additional configuration APIs. You can use these APIs as follows:
def rtGradle = Artifactory.newGradleBuild() // Deploy Maven descriptors to Artifactory: rtGradle.deployer.deployMavenDescriptors = true // Deploy Ivy descriptors (pom.xml files) to Artifactory: rtGradle.deployer.deployIvyDescriptors = true // The following properties are used for Ivy publication configuration. // The values below are the defaults. // Set the deployed Ivy descriptor pattern: rtGradle.deployer.ivyPattern = '[organisation]/[module]/ivy-[revision].xml' // Set the deployed Ivy artifacts pattern: rtGradle.deployer.artifactPattern = '[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]' // Set mavenCompatible to true, if you wish to replace dots with slashes in the Ivy layout path, to match the Maven layout: rtGradle.deployer.mavenCompatible = true
Note
You also have the option of defining default values in the Gradle build script. Read more about it here.