How to get build time stamp from Jenkins build variables? - jenkins

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);
}

Related

Display the username who ran the build in Build History

How can I display the username who executed the build next to the build number? like in the image below
Try entering Started by ([\S]+) in the section "Post-build Actions ->
Set build description -> Regular expression" of your job config.
You can add user name to build description.
currentBuild.description = currentBuild.getBuildCauses().shortDescription[0]
Then you will get something like bellow
* #1 Feb 24, 2020 10:00 AM
| Started by user max
If you want use user only then
currentBuild.description = currentBuild.getBuildCauses().userId[0]
Data structure is :
[{"_class":"hudson.model.Cause$UserIdCause","shortDescription":"Started by user max","userId":"max","userName":"max"}]
See, install and enable for the job
https://plugins.jenkins.io/build-user-vars-plugin/
Then change name of build using BUILD_USER_ID variable, like
#${BUILD_NUMBER}: ${GIT_REVISION,length=8} (${GIT_BRANCH}) by ${BUILD_USER_ID}
Add Groovy Postbuild and user build vars plugin
edit job configure,check 【Set jenkins user build variables】,then you can get env variables 'BUILD_USER'
Post-build Actions, add 【Groovy Postbuild】, Groovy Script change to
manager.addShortText(manager.envVars['BUILD_USER'])

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 pass variables from a build to another in Jenkins?

Due to infrastructure constraints, in my Jenkinsfile, I would like to store some variables from build #1 and be able to access them from build #2 and next ones.
I tried to set some env variables, but it seems they are not saved from a build to another.
Is there to acheive that from Jenkinsfile? Or maybe to write them to a text file?
Jenkins version: 2.111
Yes, write them to a text file, and store that as a build artifact in build#1.
Later builds can access the text file as build#1's build artifact (via Web interface, or on disk if running on master).
I finally use this mecanism which fits my requirements and works like a charm, so far:
if (currentBuild.previousBuild != null) {
env.MY_VAR = currentBuild.previousBuild.getBuildVariables().get('MY_VAR ')
echo "Old branch context restored"
} else {
env.MY_VAR = createSomethingAtFirstBuild()
echo "New branch context created"
}

file parameter in declarative pipeline

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

Jenkins: read an existing job's plugin config via Groovy

We are in the early phases of using Jenkins DSL. One challenge we have come across is being able to read in an existing jobs plugin settings so that we retain it before running the DSL. This allows us the ability to give the Jenkins users the option to keep some of their settings. We have successfully retained the schedule settings for our jobs but the newest challenge is being able to retain a plugin setting. Specifically a setting in the "ExtendedEmailPublisher" plugin. We would like to retain the value:
In the config.xml file for this job in the ExtendedEmailPublisher tags we see the following:
<publishers>
<hudson.plugins.emailext.ExtendedEmailPublisher>
<recipientList>Our_Team#Our_Team.com</recipientList>
<configuredTriggers>
<hudson.plugins.emailext.plugins.trigger.FailureTrigger>
<email>
<recipientList/>
<subject>$PROJECT_DEFAULT_SUBJECT</subject>
<body>$PROJECT_DEFAULT_CONTENT</body>
<recipientProviders>
<hudson.plugins.emailext.plugins.recipients.ListRecipientProvider/>
</recipientProviders>
<attachmentsPattern/>
<attachBuildLog>false</attachBuildLog>
<compressBuildLog>false</compressBuildLog>
<replyTo>$PROJECT_DEFAULT_REPLYTO</replyTo>
<contentType>project</contentType>
</email>
</hudson.plugins.emailext.plugins.trigger.FailureTrigger>
</configuredTriggers>
<contentType>default</contentType>
<defaultSubject>$DEFAULT_SUBJECT</defaultSubject>
<defaultContent>$DEFAULT_CONTENT</defaultContent>
<attachmentsPattern/>
<presendScript>$DEFAULT_PRESEND_SCRIPT</presendScript>
<classpath/>
<attachBuildLog>false</attachBuildLog>
<compressBuildLog>false</compressBuildLog>
<replyTo>$DEFAULT_REPLYTO</replyTo>
<saveOutput>false</saveOutput>
<disabled>false</disabled>
</hudson.plugins.emailext.ExtendedEmailPublisher>
</publishers>
The value we would like to extract/preserve from this XML is:
<disabled>false</disabled>
We have tried getting the existing values using groovy but cant seem to find the right code. Our first idea was to try to read the value from the config.xml using the XmlSlurper. We ran this from the Jenkins Script Console:
def projectXml = new XmlSlurper().parseText("curl http://Server_Name:8100/job/Job_Name/api/xml".execute().text);
*we use 8100 for our Jenkins port
Unfortunately while this does return some config info it does not return plugin info.
Then, we also tried running the following to read/replace the existing settings:
def oldJob = hudson.model.Hudson.instance.getItem("Job_Name")
def isDisabled = false // Default Value
for(publisher in oldJob.publishersList) {
if (publisher instanceof hudson.plugins.emailext.ExtendedEmailPublisher) {
isDisabled = publisher.disabled
}
}
And while this works if executed from the Jenkins Script Console, when we try to use it in a DSL Job we get the message:
Processing provided DSL script
ERROR: startup failed:
script: 25: unable to resolve class
hudson.plugins.emailext.ExtendedEmailPublisher
# line 25, column 37.
if (publisher instanceof hudson.plugins.emailext.ExtendedEmailPublisher)
{
1 error
Finished: FAILURE
SOLUTION UPDATE:
Using url #aflat's URL suggestion for getting the raw XML config info, I was able to use the XML Slurper and then use the getProperty method to assign the property I wanted to a variable.
def projectXml = new XmlSlurper().parseText("curl http://Server_Name:8100/job/Job_Name/config.xml".execute().text);
def emailDisabled = projectXml.publishers."hudson.plugins.emailext.ExtendedEmailPublisher".getProperty("disabled");
If you want to parse the config.xml, use
def projectXml = new XmlSlurper().parseText("curl http://Server_Name:8100/job/Job_Name/config.xml");
That should return your raw config.xml data
Under "Manage Jenkins->Configure Global Security" did you try disabling "Enable script security for Job DSL scripts"?

Resources