I would like to be able to programmatically decide which tool will be installed in an Agent for a Jenkins pipeline.
This is something I have that's working today:
withEnv(["JAVA_HOME=${tool 'OPENJDK11'}",
"PATH+JAVA=${tool 'OPENJDK11'}"]) {
... do stuff ...
}
So I have a global tool OPENJDK11 installed, along with OPENJDK14, and now I would like to change the Groovy script to be able to decide which JDK to install.
So before the part above I have saved the name of the tool in a variable jdkToInstall, how am I able to reference this variable inside the tool directive?
I have tried:
${tool '${jdkToInstall}'} and ${tool '$jdkToInstall'}.
That doesn't expand my variable, so I get an error message saying it can't find the tool "$jdkToInstall".
I also tried with string concatenation, but that ended up with a similar error message with my plus and everything.
It is sufficient to expand (${}) the variable only once. Following works as expected:
withEnv(["JAVA_HOME=${tool jdkToInstall}", "PATH+JAVA=${tool jdkToInstall}"]) {
... do stuff ...
}
Related
Can an agent label make use of environment variable? Something like this:
pipeline {
environment {
SLAVE_NODE = 'MY_COMPUTER_NAME'
}
agent { label $SLAVE_NODE}
...
Since the editor for pipelines is so small, I would like to have the available space (visible by default) to be the "environment" block, so when I copy a jenkins job I just need to adjust a few environment variables used further in the script... I think I tried all the obvious syntax possibilities by now.
Stumbled upon it by try and error... (and found a duplicate here): Add a string parameter to your jenkins job (e.g. jenkinsNode) and use this in your script:
agent { label "${jenkinsNode}" }
Currently I'm refactoring our Jenkins build pipeline. In the stage of gathering our unittests I'm trying to enumerate all '**/.test.dll' files, or '.test.dll' at least. Read somewhere that this could be achieved using eachFileRecurse from the File-object.
But... all calls failed reporting FileNotFoundException.
Using the Scriptconsole on the specific slave I tried the same code and it works as expected. Adding some addition debug lines in our jenkins-file shows that the pipeline always returns false.
def TestFile(path)
{
def file = new File(path)
echo "File '${file}' exists: ${file.exists()}"
}
TestFile(WORKSPACE)
TestFile(pwd())
TestFile(BUILDPATH)
All result a 'exists: false', even though all these paths are already used during the build.
(How) can I use the File-object in a pipeline or how can I get the files I need?
Use fileExists together otherwise it will not work.
For example in your case it will be like this
echo "fileExists '${file}' exists: '${file}'"
I have a Pylint running in a Jenkins pipeline. To implement it, I used Gerrit trigger plugin and Next Generation Warnings plugin. Everything is working as expected - Jenkins is joining the review, checks change with pylint and generates report.
Now, I'd like to post pylint score in a custom "Build successful" message. I wanted to pass the pylint score to a environment variable and use it in dedicated window for Gerrit plugin message.
Unfortunately no matter what I try, I cannot pass any "new" variable to the message. Passing parameters embedded in pipeline works (e.g. patchset number).
I created new environment variable in Configure Jenkins menu, tried exporting to shell, writing to it (via $VAR and env. syntax) but nothing works - that is, build message displays raw string like $VAR instead of what variable contains.
What should I do to pass local pylint score (distinct for every pipeline occurence) to the custom build message for Gerrit?
I don't think the custom message can be used for this. This is just supposed to be a static message.
They way I do this is to use the SSH command to perform the review. You can also achieve the same using the REST API.
First I run my linting and white space checking script that will generate a json file with the information I would like to pass to Gerrit. Next I send it to Gerrit using SSH. See below my pipeline script and an example json file.
As a bonus I have added the robot comments. This will now show up in your review as a remark from Jenkins that line 8 of my Jenkins file has a trailing white space. You can easily replace this with your lint result of you like or just ignore it and only put the message. It is easier to use a json file as it will make it easier to create multi line messages
node('master') {
sh """
cat lint_change.json | ssh -p ${env.GERRIT_PORT} ${env.GERRIT_HOST} gerrit review ${env.GERRIT_PATCHSET_REVISION} --json
"""
}
Example json file:
{
"labels": {
"Code-Style": "-1"
},
"message": "Lint Bot Review\nLint Results:\n Errors: 0\n Warnings: 0\n\nWhitespace results:\n Errors: 1",
"robot_comments": {
"Jenkinsfile": [
{
"robot_id": "lint-bot",
"line": "8",
"message": "trailing whitespace."
}
]
}
}
Alternatively, you may want to look at a new gerrit-code-review-plugin that should make this things even easier. However, I have not tried this yet.
I am developing declarative pipeline and want to use file parameter to read its content, but its not working as expected
parameters{
file(fileLocation:'list.txt', description:'contains list of projects to be build')
}
I am getting following error
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 12: Invalid parameter "fileLocation", did you mean "description"? # line 12, column 14.
file(fileLocation:'release-list.txt', description:'contains list of projects to be build')
Following is another option mentioned for basic step plugin
readFile: Read file from workspace
Reads a file from a relative path (with root in current directory, usually workspace) and returns its content as a plain string.
file
Relative ( /-separated) path to file within a workspace to read.
Type: String
encoding (optional)
Type: String
its working in script step like
def myfile = readFile('list.txt')
echo "${myfile}"
But how to use it directly in declarative script as we used other basic steps like dir??
The correct arguments for the file parameter are name and description. So it should be:
file(name:'list.txt', description:'contains list of projects to be build')
However there's an open jenkins issue dating back from 2015 about the file parameter not working for pipelines, so I don't think even this will solve your issue. https://issues.jenkins-ci.org/browse/JENKINS-27413
Following syntax is working
parameters{
file name:'list.txt', description:'contains list of projects to be build'
}
But fileLocation parameter is not acceptable still.
Below syntax is available in Jenkins2 Up & Running book but its not working
parameters{
file(fileLocation:'list.txt', description:'contains list of projects to be build')
}
Till outstanding issues gets fixed, I believe we may have to stick to freestyle mode & handle things either in downstream pipeline job or within same job leveraging needy plugin feature.
Here is my attempt which looks to work file irrespective (yes supports Binaries as well) types : https://i.stack.imgur.com/vH7mQ.png
${list.txt} will point to right file in your case..
Take a look at the plug-in https://plugins.jenkins.io/file-parameters/.
This plug-in adds support for file parameters in your Jenkinsfile: https://plugins.jenkins.io/file-parameters/#plugin-content-usage-in-declarative-pipeline
parameters {
base64File 'small'
stashedFile 'large'
}
https://github.com/jenkinsci/file-parameters-plugin
We use clover for code coverage testing but it interferes with stack traces and error information. I want to be able to use cloverGenerateReport when doing automated builds via jenkins but to skip this step entirely when doing local builds.
I've tried the various suggestions from searches for 'gradle optional dependencies' but I can't seem to get clover completely out of the way.
Suggestions?
You can use the method onlyIf.
cloverGenerateReport.onlyIf {
project.hasProperty('enableClover') ? Boolean.valueOf(project.getProperty('enableClover')) : false
}
On the command line you can enable it by providing the project property:
gradle cloverGenerateReport -PenableClover=true
One solution would be to check if the environment variable "JENKINS_HOME" exists. If it does, then set cloverGenerateReport as a dependency to another task.
In your build.gradle:
def env = System.getenv()
if(env.containsKey('JENKINS_HOME')){
reportTask.dependsOn cloverGenerateReport
}