Mask variables in jenkins - jenkins

I need to hide some values in Jenkins pipelines. I've created some libraries with classes that handle some common operations. The problem is some of these classes execute commands with sh but it shows sensitive information. My problem is I cannot use withCredentials because I don't have this credentials stored in Jenkins(they come from yaml files in the repository and are decrypted with a library). Is there a way to use withCredentials without having the credentials stored in jenkins? Could say to jenkins to hide some values?
I need something like:
maskVariables([var1: 'secret value 1', var2: 'secret value 2']) {
pipeline.sh('echo "don't show $var1 $var2"')
}
//don't show ************** **************

Related

How to pass pipeline variables to post build gerrit message?

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.

How to access collected artifacts from Jenkins pipeline groovy script?

I wan to check from groovy pipeline if a specific file (artifact) was collected or not.
How can I access the list of artefacts?
archiveArtifacts artifacts: 'foo.txt', allowEmptyArchive: true
...
// much later
// check if 'foo.txt' was collected?
Please note that I am looking for a solution that does not imply modification of the code that collects the artifacts. This is because this code is in multiple places, I only need something to do at the end, not at any possible call of archiveArtifacts (which can be deeply hidden).
You can get the list of artifacts using jenkins api in either XML/JSON format.
call the below url. insert job-name and build-number
http://localhost:8080/jenkins/job/job-name/build-number/api/json?pretty=true
Json Example:
"artifacts" : [
{
"displayPath" : "temp.jar",
"fileName" : "temp.jar",
"relativePath" : "target/temp.jar"
}
]
It's possible to access the artifacts using something like currentBuild.rawBuild.artifacts.each { println it.fileName }, but you will need to whitelist rawBuild, artifacts and fileName properties.

Jenkinsfile pipeline source an outside file for dynamic parameters?

I have a unique issue. I have one build system that needs one set of params to start a job and another jenkins server that needs to use the same Jenkinsfile but have a different set of options to select from. Think of it as a jenkins server in region 1 and another in region 2 and they need a different set of options
I have this
pipeline {
agent any
environment {
ENV_NAMES = readFile "/etc/env_list"
}
parameters {
// choices are newline separated
choice(choices: "${env.ENV_NAMES}", description: 'What Environment?', name: 'env')
}
}
Right now the choice is coming up as null but i'd love a way to source an outside file to import those.
I have config management that can place a file with data in it.
So server one would get like
env1
env2
env3
And server2 would get
prod1
prod2
prod3

Pass large amount of parameters between jobs

I have two Jenkins jobs that tun on separate computers. On computer 1 I read properties file and use it for environment variables. But i need the same file on PC 2 and it only exist on the first one. When the first Jenkins job finishes it starts the second one and it can pass parameters file via job but I have to receive with creation of separate parameter with Parameterized Trigger Plugin for each parameter, and I have a lot and don`t want to do so. Is there simple solution for this issue?
Forget Jenkins 1 and the plugins Parameterized Trigger Plugin. Using Jenkins 2, here's an example of your need:
node ("pc1") {
stage "step1"
stash name: "app", includes: "properties_dir/*"
}
node ("pc2") {
stage "step2"
dir("dir_to_unstash") {
unstash "app"
}
}

How to get build time stamp from Jenkins build variables?

How can I get build time stamp of the latest build from Jenkins?
I want to insert this value in the Email subject in post build actions.
Build Timestamp Plugin will be the Best Answer to get the TIMESTAMPS in the Build process.
Follow the below Simple steps to get the "BUILD_TIMESTAMP" variable enabled.
STEP 1:
Manage Jenkins -> Plugin Manager -> Installed...
Search for "Build Timestamp Plugin".
Install with or without Restart.
STEP 2:
Manage Jenkins -> Configure System.
Search for 'Build Timestamp' section, then Enable the CHECKBOX.
Select the TIMEZONE, TIME format you want to setup with..Save the Page.
USAGE:
When Configuring the Build with ANT or MAVEN,
Please declare a Global variable as,
E.G. btime=${BUILD_TIMESTAMP}
(use this in your Properties box in ANT or MAVEN Build Section)
use 'btime' in your Code to any String Variables etc..
NOTE: This changed in Jenkins 1.597, Please see here for more info regarding the migration
You should be able to view all the global environment variables that are available during the build by navigating to https://<your-jenkins>/env-vars.html.
Replace https://<your-jenkins>/ with the URL you use to get to Jenkins webpage (for example, it could be http://localhost:8080/env-vars.html).
One of the environment variables is :
BUILD_ID
The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss)
If you use jenkins editable email notification, you should be able to use ${ENV, var="BUILD_ID"} in the subject line of your email.
One way this can be done is using shell script in global environment section, here, I am using UNIX timestamp but you can use any shell script syntax compatible time format:
pipeline {
agent any
environment {
def BUILDVERSION = sh(script: "echo `date +%s`", returnStdout: true).trim()
}
stages {
stage("Awesome Stage") {
steps {
echo "Current build version :: $BUILDVERSION"
}
}
}
}
Try use Build Timestamp Plugin and use BUILD_TIMESTAMP variable.
Generate environment variables from script (Unix script) :
echo "BUILD_DATE=$(date +%F-%T)"
I know its late replying to this question, but I have recently found a better solution to this problem without installing any plugin. We can create a formatted version number and can then use the variable created to display the build date/time.
Steps to create: Build Environment --> Create a formatted version number:
Environment Variable Name: BUILD_DATE
Version Number Format String: ${BUILD_DATE_FORMATTED}
thats it. Just use the variable created above in the email subject line as ${ENV, var="BUILD_DATE"} and you will get the date/time of the current build.
You can use the Jenkins object to fetch the start time directly
Jenkins.getInstance().getItemByFullName(<your_job_name>).getBuildByNumber(<your_build_number>).getTime()
also answered it here:
https://stackoverflow.com/a/63074829/1968948
BUILD_ID used to provide this information but they changed it to provide the Build Number since Jenkins 1.597. Refer this for more information.
You can achieve this using the Build Time Stamp plugin as pointed out in the other answers.
However, if you are not allowed or not willing to use a plugin, follow the below method:
def BUILD_TIMESTAMP = null
withCredentials([usernamePassword(credentialsId: 'JenkinsCredentials', passwordVariable: 'JENKINS_PASSWORD', usernameVariable: 'JENKINS_USERNAME')]) {
sh(script: "curl https://${JENKINS_USERNAME}:${JENKINS_PASSWORD}#<JENKINS_URL>/job/<JOB_NAME>/lastBuild/buildTimestamp", returnStdout: true).trim();
}
println BUILD_TIMESTAMP
This might seem a bit of overkill but manages to get the job done.
The credentials for accessing your Jenkins should be added and the id needs to be passed in the withCredentials statement, in place of 'JenkinsCredentials'. Feel free to omit that step if your Jenkins doesn't use authentication.
This answer below shows another method using "regexp feature of the Description Setter Plugin" which solved my problem as I could not install new plugins on Jenkins due to permission issues:
Use build timestamp in setting build description Jenkins
If you want add a timestamp to every request from browser to jenkins server.
You can refer to the jenkins crumb issuer mechanism, and you can hack the /scripts/hudson-behavior.js add modify here. so it will transform a timestamp to server.
/**
* Puts a hidden input field to the form so that the form submission will have the crumb value
*/
appendToForm : function(form) {
// add here. ..... you code
if(this.fieldName==null) return; // noop
var div = document.createElement("div");
div.innerHTML = "<input type=hidden name='"+this.fieldName+"' value='"+this.value+"'>";
form.appendChild(div);
}

Resources