Any way to send Gradle parameters TO Jenkins?


#1

I’ve seen many articles for sending Jenkins parameters to Gradle, which are passed as System variables, but have not come across doing the opposite. In my build.gradle file I have specified 2 parameters for a file name and version number. In order to pass this file name to the next job in the pipeline, I’d like to send the parameters to the next Jenkins job so it can make use of the file.

I’ve looked at just running a shell command to get the filename with a combo of awk/sed but it wouldn’t be flexible enough over time if the name/version details changed significantly.

Is sending gradle params back to Jenkins possible using built in functionality?


(davidmichaelkarr) #2

When it comes down to it, Jenkins is running a process, being the Gradle build step. If your Jenkins script expects the stdout from Gradle to have certain content, then Jenkins can store that into a variable and do whatever it likes with it. There is no reasonable strategy for Gradle “knowing” that it’s being called from Jenkins and trying to communicate back somehow to that Jenkins instance.


#3

Thank you David, I think what you’re saying does make sense. After seeing your reply, I considered the option to write the variable into a text file, which I can then have Jenkins read. The code I’m using is below, it outputs the version number fine but I can’t find the exact method to append the basename before the version number, after trying a number of ways. What I want the file’s content to be is just “Archive-APR-1.01”

version = '1.01'
archiveValue = 'Archive-APR'
tasks.create('versionFile') {
  outputs.file('versionFile.txt')
  inputs.property "archiveValue"
  inputs.property ('version', property.version)

doLast {
    project.file('versionFile.txt') << property.version
  }
}

UPDATE: After looking some more, I saw a simpler approach to achieve the purpose. This code seems to work well for my need, and also achieves the other goal, to overwrite the file rather than append:

version = '1.01
def archiveValue = 'Archive-APR'

task versionTxt() {
  doLast {
    new File("version.txt").text = "${archiveValue}-${version}"
    }
}

(davidmichaelkarr) #4

Why are you writing it to a file? Just print it to stdout and have jenkins store that in a variable.


(Andrew Oberstar) #5

If you use the Jenkins pipeline plugin, this is entirely doable. (Note this is pseudocode to just point you in the right direction. I’ve used this approach before, but don’t have an example handy.)

Gradle can know it’s being run by Jenkins using environment variables. And Gradle has a WriteProperties task type that can communicate key-value pairs out.

if (System.env['JENKINS_HOME']) {
  task jenkinsProps(type: WriteProperties) {
    outputFile file('build/jenkins.properties')
    property 'myProp', 'myValue'
  }
}

And you can read that properties file in from Jenkins using the readProperties pipeline step.

// inside a stage's steps
sh './gradlew build jenkinsProps'
def props = readProperties file: 'build/jenkins.properties'
// ...

#6

While that’s technically true, I’d still question whether it should.

@SP3, make sure you actually need this before you do it. My advice would be to try and script your whole build in Gradle itself and make Jenkins execute the exact same steps a developer would execute when building a release manually.

If that’s your goal, you can easily break up the Gradle build into multiple stages in Jenkins by stashing/unstashing build results in the Jenkins pipeline and using Gradle’s -x command line parameter if necessary. That way, you keep most of the logic in the Gradle build.


(Andrew Oberstar) #7

@Moe This kind of approach is a step towards your CI tool doing the equivalent of calling the tooling API and getting model data about your project (a la Eclipse or InteliJ). This can be helpful in keeping Jenkins pipelines the same across projects and rely on the properties Gradle provides to indicate specific values for things like a folder path or version number.

This may not be needed for @SP3 use case.


#8

That sounds interesting. Can you elaborate? We might want something like that for our team, since we have quite a few projects with similar Gradle builds…


#9

Sorry to reply so late, but to answer your question, I wrote to the file so I can make use of it in downstream jobs, and as a complete package that can be downloaded from a repo and processed by Jenkins by other jobs that are manually run.