Please suggest a plugin or an approach to achieve the following in Jenkins declarative pipeline.
You don't need any plugin per se, as you can use e.g. curl:
def calendar_url = "https://calendarific.com/api/v2/holidays?&api_key=758f54db8c52c2b500c928282fe83af1b1aa2be8&country=IN&year=2020"
def curl_output = sh returnStdout: true, script: "curl -s ${calendar_url}"
You can convert it to json with readJson utility:
def holidays = readJson text: curl_output
for (holiday in holidays.response.holidays) {
def holiday_date = holiday.date.iso
println holiday_date
}
Defining the current date and bailing out of the build is left as an exercise for the implementor :)
Related
This is related to one question I asked before: Using groovy to parse JSON object in shell scripts for Jenkin
basically I will need to pass a dynamic value as returned from sh scripts to an environment block, so that the following stage can re-use that value and pass the version as a label to JIRA plugin called Xray. But I aware that I cannot pass dynamic values to an environment block during the pipeline execution. So, I think I am going to need try a different route for that, not sure if anyone could give me some tips please?
def setLatestAppVersionLabel() {
def response = sh(script: "curl --silent ${APP_ARTIFACTORY_URL}/${XRAY_PLATFORM}/builds/latest.json", returnStdout: true).trim() as String
def jsonResponse = readJSON text: response
LATEST_VERSION = jsonResponse.id
echo "LATEST_VERSION -> ${LATEST_VERSION}"
}
JSON response looks like that:
{"id":"1.0.0-6",
"version":"1.0.0",
"build":6,
"tag":"android-v1.0.0-6",
"commitHash":"5a78c4665xxxxxxxxxxe1b62c682f84",
"dateCreated":"2020-03-02T08:11:29.912Z"}
and there is an environment block where I would like to pass the value to one of the variable defined there#
environment {
AWS_DEFAULT_REGION = 'uk-xxx'
XRAY_ENVIRONMENT = 'e2e'
VERSION_KEY = 'id'
XRAY_PLATFORM = 'Android'
APP_ARTIFACTORY_URL = 'https://artifactory.example.com/mobile'
LATEST_VERSION = ''
}
If this path not working, what else could I use? Want to re-use the latest version taken from JSON response for the next stage in the pipeline to use.
Next stage looks like this:
stage('Import Result to Xray') {
when {
expression { return fileExists('xxx-executor/target/AndroidxxxxE2EResults/cucumber-reports/Cucumber.json')}
}
steps {
xrayResultsImport('xxx-executor/target/AndroidxxxxxE2EResults/cucumber-reports/Cucumber.json', 'xxx_ANDROID_E2E_xxxxxxx_Tests', XRAY_LABELS, ['E2E', 'Android', LATEST_VERSION], env.BUILD_URL)
}
}
Sorry I have to put xxxx to make this question general due to project confidentiality.
To put it simple, you want to use the version you fetched from a JSON response and want to use it in all stages of your Jenkins pipeline.
Ensure you've jq utility installed in your jenkins agent.
pipeline {
agent any
environment {
XRAY_LATEST_VERSION = ''
}
stages {
stage(‘Get Version ') {
steps {
script {
XRAY_LATEST_VERSION = sh(script: 'curl -s ${APP_ARTIFACTORY_URL}/${XRAY_PLATFORM}/builds/latest.json | jq .version | sed \'s/"//g\'', returnStdout: true).trim()
}
}
}
stage('Print'){
steps{
echo "${XRAY_LATEST_VERSION}"
}
}
}
}
You can use the variable ${XRAY_LATEST_VERSION} in any stages you want the and the value will be rendered across.
I have a pipeline job that runs a maven build. In the "post" section of the pipeline, I want to get the log file so that I can perform some failure analysis on it using some regexes. I have tried the following:
def logContent = Jenkins.getInstance()
.getItemByFullName(JOB_NAME)
.getBuildByNumber(
Integer.parseInt(BUILD_NUMBER))
.logFile.text
Error for the above code
Scripts not permitted to use staticMethod jenkins.model.Jenkins
getInstance
currentBuild.rawBuild.getLogFile()
Error for the above code
Scripts not permitted to use method hudson.model.Run getLogFile
From my research, when I encounter these, I should be able to go to the scriptApproval page and see a prompt to approve these scripts, but when I go to that page, there are no new prompts.
I've also tried loading the script in from a separate file and running it on a different node with no luck.
I'm not sure what else to try at this point, so that's why I'm here. Any help is greatly appreciated.
P.S. I'm aware of the BFA tool, and I've tried manually triggering the analysis early, but in order to do that, I need to be able to access the log file, so I run into the same issue.
You can use pipeline step httpRequest from here
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Test fetch build log'
}
post {
always {
script {
def logUrl = env.BUILD_URL + 'consoleText'
def response = httpRequest(
url: logUrl,
authentication: '<credentialsId of jenkins user>',
ignoreSslErrors: true
)
def log = response.content
echo 'Build log: ' + log
}
}
}
}
}
}
If your jenkins job can run on linux machine, you can use curl to archive same goal.
pipeline {
agent any
stages {
stage('Build') {
environment {
JENKINS_AUTH = credentials('< credentialsId of jenkins user')
}
steps {
sh 'pwd'
}
post {
always {
script {
def logUrl = env.BUILD_URL + 'consoleText'
def cmd = 'curl -u ${JENKINS_AUTH} -k ' + logUrl
def log = sh(returnStdout: true, script: cmd).trim()
echo 'Build log: ' +
echo log
}
}
}
}
}
}
Above two approaches both require the credentials is Username and password format. More detail about what is it and how to add in Jenkins, please look at here
Currently this is not possible via the RunWrapper object that is made available. See https://issues.jenkins.io/browse/JENKINS-46376 for a request to add this.
So the only options are:
explicitly whitelisting the methods
read the log via the URL as described in the other answer, but this requires either anonymous read access or using proper credentials.
Need some help on fetching the GitHub payload into the Jenkins file without installing any plugin.
If anyone can provide the Jenkins file code snippet to access the GitHub payload from the webhook. it would be of great help.
I am able to call the Jenkins job from GitHub webhook. but need the payload as well to process further.
Any help would be appreciated. Thanks.
Please find the below groovy script:
stage('Pull Request Info') {
agent {
docker {
image 'maven'
args '-v $HOME/.m2:/home/jenkins/.m2 -ti -u 496 -e MAVEN_CONFIG=/home/jenkins/.m2 -e MAVEN_OPTS=-Xmx2048m'
}
}
steps {
script {
withCredentials([usernameColonPassword(credentialsId: "${env.STASH_CREDENTIAL_ID}",
variable: 'USERPASS')]) {
def hasChanges = maven.updateDependencies()
if (hasChanges != '') {
def pr1 = sh(
script: "curl -s -u ${"$USERPASS" } -H 'Content-Type: application/json' https://xx.example/rest/some/endpoint",
returnStdout: true
)
def pr = readJSON(text: pr1)
println pr.fromRef
}
}
}
}
}
Above script uses, curl to fetch the details about Pull request. I have stored the credentials in the jenkins and created an environment variable for the credentialId.
You can replace the url with your endpoint. You can also modify the script to use jq if you have jq installed in the machine.
In this case, I'm using readJSON to parse the JSON which is part of pipeline utilities plugin. My question would be, why not use the plugin as it provides the needed functionalities?
If you still dont want to use plugin, take a look at json parsing with groovy.
When I click "rebuild" from the page of a build jenkins rebuilds and runs a new job- a new job with a new jenkins build number.
How do I get the build number of the job where I executed the rebuild?
Im not talking about the previous build number.
Say Im on build 10. I go to build 5 and click rebuild. How do I that build number (5) from inside the pipeline like I can with env.BUILD_NUMBER?
I assume that you are using Groovy Pipeline and already know the Global Variable (see Global Variable Reference).
The currentBuild variable has a field rawBuild that return a hudson.model.Run object
Call rawBuildObject#getCauses() or rawBuildObject#getCauses() and return some Cause object.
script below:
node {
stage('test advance script') {
echo "current build number: ${currentBuild.number}"
echo "previous build number: ${currentBuild.previousBuild.getNumber()}"
def causes = currentBuild.rawBuild.getCauses()
echo "causes: ${causes}"
def rebuildCause0 = currentBuild.rawBuild.getCause(com.sonyericsson.rebuild.RebuildCause)
echo "rebuildCause0: ${rebuildCause0}"
echo "rebuild up number: ${rebuildCause0.getUpstreamBuild()}"
}
}
But as we discuss in chat, the Rebuilder Plugin use CauseAction in a wrong way. If it is fixed as this, console output should be:
current build number: 72
previous build number: 71
causes: [hudson.model.Cause$UserIdCause#679c1066, job/DMP/job/test-pipeline/63[hudson.model.Cause$UserIdCause#679c1066]]
rebuildCause0: job/DMP/job/test-pipeline/63[hudson.model.Cause$UserIdCause#679c1066]
rebuild up number: 63
Remember to scriptApproval when you see errors like this:
Scripts not permitted to use method hudson.model.Run
getCauses. Administrators can decide whether to approve or reject this
signature.
Assuming you can curl your own jenkins builds:
def getOriginalRebuildNum(String jobUrl = "${JOB_URL}"){
def urlJsonPath
def buildNumber
def result
ansiColor('xterm') {
try {
buildNumber = "${BUILD_NUMBER}"
urlJsonPath = "${JOB_URL}/${buildNumber}/api/json"
while (!buildNumber.isEmpty()) {
result = buildNumber
buildNumber = sh(
script:
"""
curl -s $urlJsonPath \
| jq -r '.actions[]
| select(."_class" == "hudson.model.CauseAction") .causes[]
| select(.upstreamBuild != null).upstreamBuild'
""",
returnStdout: true).trim()
urlJsonPath = "${JOB_URL}/${buildNumber}/api/json"
}
echo "Original Build: ${JOB_URL}/${result}/"
}
catch (err) {
"Error: Could not retrieve original Build Number from ${urlJsonPath} - $err"
result = "${BUILD_NUMBER}"
}
}
return result
}
I am trying to render information obtained from the shell in an active Active Choices parameter with a groovy script. I can easily access the shell from a groovy script in a jenkins pipeline with the sh method like this:
node()
{
sh 'git log ...'
}
But when I try this in the groovy script of Active choices, it crashes and the fallback script is executed.
Is it possible to switch to a node in this context and execute a shell command ?
Thanks for the help!
Here is sample snippet using the active choice plugin.
def command = $/aws ec2 describe-instances \
--filters Name=tag:Name,Values=Test \
--query Reservations[*].Instances[*].PrivateIpAddress \
--output text /$
def proc = command.execute()
proc.waitFor()
def output = proc.in.text
def exitcode= proc.exitValue()
def error = proc.err.text
if (error) {
println "Std Err: ${error}"
println "Process exit code: ${exitcode}"
return exitcode
}
//println output.split()
return output.tokenize()