Issue with transitioning ticket status using Jenkins Jira steps plugin - jenkins

I am getting below error when using transition issue status from jenkins pipeline when using plugin
JIRA: Site - jira - Transition issue with idOrKey: TEST-12345
Error Code: 500
Error Message: {"errorMessages":["Internal server error"],"errors":{}}
Below is my code snippet in pipeline
node {
stage('JIRA') {
withEnv(['JIRA_SITE=jira']) {
def issue = jiraGetIssue idOrKey: 'TEST-12345'
def transitionInput =
[
transition: [
id: '1234'
]
]
def issue_status = issue.data.fields.status.name.toString()
echo issue_status
if ( issue_status == "Build Ready") {
jiraTransitionIssue idOrKey: 'TEST-12345', input: transitionInput, site: 'jira'
} else { echo "JIRA ticket status " }
}
}
}

Related

Jenkins file groovy issues

Hi My jenkins file code is as follows : I am basically trying to make call to a python script and execute it, I have defined some variables in my code : And when i am trying to run it, It gives no such property error in the beginning and I cant find out the reason behind it.
I would really appreciate any suggestions on this .
import groovy.json.*
pipeline {
agent {
label 'test'
}
parameters {
choice(choices: '''\
env1
env2'''
, description: 'Environment to deploy', name: 'vpc-stack')
choice(choices: '''\
node1
node2'''
, description: '(choose )', name: 'stack')
}
stages {
stage('Tooling') {
steps {
script {
//set up terraform
def tfHome = tool name: 'Terraform 0.12.24'
env.PATH = "${tfHome}:${env.PATH}"
env.TFHOME = "${tfHome}"
}
}
}
stage('Build all modules') {
steps {
wrap([$class: 'BuildUser']) {
// build all modules
script {
if (params.refresh) {
echo "Jenkins refresh!"
currentBuild.result = 'ABORTED'
error('Jenkinsfile refresh! Aborting any real runs!')
}
sh(script: """pwd""")
def status_code = sh(script: """PYTHONUNBUFFERED=1 python3 scripts/test/test_script.py /$vpc-stack""", returnStatus: true)
if (status_code == 0) {
currentBuild.result = 'SUCCESS'
}
if (status_code == 1) {
currentBuild.result = 'FAILURE'
}
}
}
}
}
}
post {
always {
echo 'cleaning workspace'
step([$class: 'WsCleanup'])
}
}
}
And this code is giving me the following error :
hudson.remoting.ProxyException: groovy.lang.MissingPropertyException: No such property: vpc for class
Any suggestions what can be done to resolve this.
Use another name for the choice variable without the dash sign -, e.g. vpc_stack or vpcstack and replace the variable name in python call.

Getting error while deleting Jenkins build history

Hello All I am getting below error while deleting build history of jenkins jobs
No build logs found in calcmanager-pull-request and build history count is : 0
[Pipeline] End of Pipeline
java.lang.NullPointerException: Cannot invoke method getLastBuild() on null object
Below is the pipeline script I am using. calcmanager-pull-request job contains build history but it is displaying as zero
pipeline {
agent { label 'master' }
stages {
stage('delete all jobs build history'){
steps {
script {
def buildLogCount=10
Jenkins.instance.getAllItems(Job.class).each { jobitem ->
def jobName = jobitem.name
def jobInfo = Jenkins.instance.getItem(jobName)
if(jobInfo.getLastBuild()){
def lastBuildNum=jobInfo.getLastBuild().getNumber()
if(lastBuildNum>=buildLogCount){
def deletedBuildNum=lastBuildNum - buildLogCount
def deletedNumRange = Fingerprint.RangeSet.fromString("0-${deletedBuildNum}",false);
def buildCount=jobInfo.getBuilds(deletedNumRange).size()
if(buildCount==0){
println "No build logs found in ${jobName} and build history count is : ${buildCount}"
}
else{
jobInfo.getBuilds(deletedNumRange).each { item ->
item.delete()
}
}
}
else{
println "No build logs to delete in ${jobName}"
}
}
else{
println "No build logs found in ${jobName}"
}
}
}
}
}
}
}
}
You got that error due to some of jobs was never run. It doesn't have history.
So you can build a List with jobs with history:
Jenkins.instance.getAllItems(Job.class)
.findAll { it.getLastBuild()?.getNumber() } // if job doesn't not history it will return null == false
.each { job ->
def lastBuildNum=job.getLastBuild().getNumber()
/// you code is here
}
Above code works fine if you don't have any multi branch pipeline jobs. If you have multibranch pipeline jobs then use below code in jenkins file.
properties(
[
buildDiscarder(logRotator(daysToKeepStr: '60', numToKeepStr: '7')),
]
)

Jenkins declarative pipeline: find out triggering job

We have a Jenkins job that uses a declarative pipeline.
This job can be triggered by different other builds.
In the declarative pipeline how can I find out which build has triggered the pipeline?
Code sample below
pipeline {
agent any
stages {
stage('find upstream job') {
steps {
script {
def causes = currentBuild.rawBuild.getCauses()
for(cause in causes) {
if (cause.class.toString().contains("UpstreamCause")) {
println "This job was caused by job " + cause.upstreamProject
} else {
println "Root cause : " + cause.toString()
}
}
}
}
}
}
}
You can check the job's REST API to get extra information like below
{
"_class" : "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions" : [
{
"_class" : "hudson.model.ParametersAction",
"parameters" : [
]
},
{
"_class" : "hudson.model.CauseAction",
"causes" : [
{
"_class" : "hudson.model.Cause$UpstreamCause",
"shortDescription" : "Started by upstream project \"larrycai-sto-46908390\" build number 7",
"upstreamBuild" : 7,
"upstreamProject" : "larrycai-sto-46908390",
"upstreamUrl" : "job/larrycai-sto-46908390/"
}
]
},
Reference:
https://jenkins.io/doc/pipeline/examples/#get-build-cause
Get Jenkins upstream jobs
I realize that this is a couple years old, but the previous response required some additional security setup in my Jenkins instance. After a bit of research, I found that there was a new feature request completed in 11/2018 that addresses this need and exposes build causes in currentBuild. Here is a little lib I wrote that returns the cause with the string "JOB/" prepended if the build was triggered by another build:
def call(body) {
if (body == null) {body = {DEBUG = false}}
def myParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = myParams
body()
def causes = currentBuild.getBuildCauses()
if (myParams.DEBUG) {
echo "causes count: " + causes.size().toString()
echo "causes text : " + causes.toString()
}
for(cause in causes) {
// echo cause
if (cause._class.toString().contains("UpstreamCause")) {
return "JOB/" + cause.upstreamProject
} else {
return cause.toString()
}
}
}
To use this, I place it in a library in a file named "buildCause.groovy". Then I reference the library at the top of my Jenkinsfile:
library identifier: 'lib#master', retriever: modernSCM(
[$class: 'GitSCMSource', remote: '<LIBRARY_REPO_URL>',
credentialsId: '<LIBRARY_REPO_CRED_ID', includes: '*'])
Then I can call it as needed within my pipeline:
def cause=buildCause()
echo cause
if (!cause.contains('JOB/')) {
echo "started by user"
} else {
echo "triggered by job"
}
Larry's answer didn't quite work for me.
But, after I've modified it slightly with the help of these docs and this version works:
def causes = currentBuild.getBuildCauses()
for(cause in causes) {
if (cause._class.toString().contains("UpstreamCause")) {
println "This job was caused by job " + cause.upstreamProject
} else {
println "Root cause : " + cause.toString()
}
}
P.S. Actually, Daniel's answer mentions this method, but there's too much clutter, I only noticed it after I wrote my solution.

How to send Slack notification after a Jenkins pipeline build failed?

I have a pipeline groovy script in Jenkins v2.19. Also I have a
"Slack Notification Plugin" v2.0.1 and "Groovy Postbuild Plugin" installed.
I can successfully send "build started" and "build finished" messages.
When a build fails, how can I send the "Build failed" message to a Slack channel?
You could do something like this and use a try catch block.
Here is some example Code:
node {
try {
notifyBuild('STARTED')
stage('Prepare code') {
echo 'do checkout stuff'
}
stage('Testing') {
echo 'Testing'
echo 'Testing - publish coverage results'
}
stage('Staging') {
echo 'Deploy Stage'
}
stage('Deploy') {
echo 'Deploy - Backend'
echo 'Deploy - Frontend'
}
} catch (e) {
// If there was an exception thrown, the build failed
currentBuild.result = "FAILED"
throw e
} finally {
// Success or failure, always send notifications
notifyBuild(currentBuild.result)
}
}
def notifyBuild(String buildStatus = 'STARTED') {
// build status of null means successful
buildStatus = buildStatus ?: 'SUCCESSFUL'
// Default values
def colorName = 'RED'
def colorCode = '#FF0000'
def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
def summary = "${subject} (${env.BUILD_URL})"
// Override default values based on build status
if (buildStatus == 'STARTED') {
color = 'YELLOW'
colorCode = '#FFFF00'
} else if (buildStatus == 'SUCCESSFUL') {
color = 'GREEN'
colorCode = '#00FF00'
} else {
color = 'RED'
colorCode = '#FF0000'
}
// Send notifications
slackSend (color: colorCode, message: summary)
}
Complete snippet can be found here Jenkinsfile Template
Just in case if in Declarative Syntax,
Now, Jenkins provides post. You can check result at the end of pipeline.
https://jenkins.io/doc/book/pipeline/syntax/#post-example
Using like:
pipeline {
stages { ... }
post {
// only triggered when blue or green sign
success {
slackSend ...
}
// triggered when red sign
failure {
slackSend ...
}
// trigger every-works
always {
slackSend ...
}
}
}
It would be used in every stage also. See the document link please.
Based on Liam Newman's blog post, have a look at this cleaned up snippet for Slack only in scripted pipelines (declarative pipeline users scroll down). It uses original Jenkins results, message formatting, better colors (based on EclEmma), and some Groovy features like default arguments:
def notifySlack(String buildStatus = 'STARTED') {
// Build status of null means success.
buildStatus = buildStatus ?: 'SUCCESS'
def color
if (buildStatus == 'STARTED') {
color = '#D4DADF'
} else if (buildStatus == 'SUCCESS') {
color = '#BDFFC3'
} else if (buildStatus == 'UNSTABLE') {
color = '#FFFE89'
} else {
color = '#FF9FA1'
}
def msg = "${buildStatus}: `${env.JOB_NAME}` #${env.BUILD_NUMBER}:\n${env.BUILD_URL}"
slackSend(color: color, message: msg)
}
node {
try {
notifySlack()
// Existing build steps.
} catch (e) {
currentBuild.result = 'FAILURE'
throw e
} finally {
notifySlack(currentBuild.result)
}
}
The output will be something like this (play around with different formatting styles here):
Maybe env.JOB_NAME contains encoded slashes (%2F) which can be fixed with replaceAll("%2F", "/"). Check out this Gist to see how to notify HipChat as well.
If you have a declarative pipeline, have a look at the Jenkins documentation on "Cleaning up and notifications" or Liam Newman's follow-up post "Declarative Pipeline: Notifications and Shared Libraries".

Access Stage name during the build in Jenkins pipeline

Let's say we have the following Jenkinsfile:
stage name: "Cool stage"
sh 'whoami'
stage name: "Better stage"
def current_stage = getCurrentStageName()
echo "CONGRATULATIONS, you are on stage: $current_stage"
The question is how to implement getCurrentStageName(). I know, that I can get an access to build run-time using currentBuild.rawBuild.
But how to get stage name from that point?
I need this for some customization in email notifications, so that I can always catch failed stage name and include it into email body.
You can now do this in a built-in manner, since Jenkins 2.3. Like so:
steps {
updateGitlabCommitStatus name: STAGE_NAME, state: 'running'
echo '${STAGE_NAME}'
}
For more information see: https://issues.jenkins-ci.org/browse/JENKINS-44456
This should work from a pipeline shared library:
#!/usr/bin/env groovy
import hudson.model.Action;
import org.jenkinsci.plugins.workflow.graph.FlowNode
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode
import org.jenkinsci.plugins.workflow.actions.LabelAction
def getStage(currentBuild){
def build = currentBuild.getRawBuild()
def execution = build.getExecution()
def executionHeads = execution.getCurrentHeads()
def stepStartNode = getStepStartNode(executionHeads)
if(stepStartNode){
return stepStartNode.getDisplayName()
}
}
def getStepStartNode(List<FlowNode> flowNodes){
def currentFlowNode = null
def labelAction = null
for (FlowNode flowNode: flowNodes){
currentFlowNode = flowNode
labelAction = false
if (flowNode instanceof StepStartNode){
labelAction = hasLabelAction(flowNode)
}
if (labelAction){
return flowNode
}
}
if (currentFlowNode == null) {
return null
}
return getStepStartNode(currentFlowNode.getParents())
}
def hasLabelAction(FlowNode flowNode){
def actions = flowNode.getActions()
for (Action action: actions){
if (action instanceof LabelAction) {
return true
}
}
return false
}
def call() {
return getStage(currentBuild)
}
Example usage:
node {
stage('Stage One'){
echo getCurrentStage()
}
stage('Stage Two'){
echo getCurrentStage()
}
}
Aleks' workaround works fine, just thought it's worth sharing the code
node ("docker") {
def sendOk = {
String stage -> slackSend color: 'good', message: stage + " completed, project - ${env.JOB_NAME}:1.0.${env.BUILD_NUMBER}"
}
def sendProblem = {
String stage, error -> slackSend color: 'danger', message: stage + " did not succeed, project - ${env.JOB_NAME}:1.0.${env.BUILD_NUMBER}, error: ${error}, Find details here: ${env.BUILD_URL}"
}
def exec = {
work, stageName ->
stage (stageName) {
try {
work.call();
sendOk(stageName)
}
catch(error) {
sendProblem(stageName, error)
throw error
}
}
}
exec({
git credentialsId: 'github-root', url: 'https://github.com/abc'
dir ('src') {
git credentialsId: 'github-root', url: 'https://github.com/abc-jenkins'
}
sh "chmod +x *.sh"
}, "pull")
exec({ sh "./Jenkinsfile-clean.sh \"1.0.${env.BUILD_NUMBER}\"" }, "clean")
exec({ sh "./Jenkinsfile-unit.sh \"1.0.${env.BUILD_NUMBER}\"" }, "unit")
exec({ sh "./Jenkinsfile-build.sh \"1.0.${env.BUILD_NUMBER}\"" }, "build")
exec({ sh "./Jenkinsfile-dockerize.sh \"1.0.${env.BUILD_NUMBER}\"" }, "dockerize")
exec({ sh "./Jenkinsfile-push.sh \"1.0.${env.BUILD_NUMBER}\"" }, "push")
exec({ sh "./Jenkinsfile-prod-like.sh \"1.0.${env.BUILD_NUMBER}\"" }, "swarm")
}
As a workaround, in the failure email I include a link to the Pipeline Steps page. This page clearly shows green and red balls for each step, making it easy for the email recipient to figure out not just the stage, but the step that failed.
In the following example email body, the FlowGraphTable link links to Pipeline Steps:
def details = """<p>Job '${env.JOB_NAME}', build ${env.BUILD_NUMBER} result was ${buildStatus}.
Please scrutinize the build and take corrective action.</p>
<p>Quick links to the details:
<ul>
<li>${env.JOB_NAME} job main page</li>
<li>Build ${env.BUILD_NUMBER} main page</li>
<ul>
<li>Console output</li>
<li>Git changes</li>
<li>Pipeline steps.
This page will show you which step failed, and give you access
to the job workspace.</li>
</ul>
</ul></p>"""
This is an excerpt from my implementation of notifyBuild() that BitwiseMan of CloudBees presents in his article, Sending Notifications in Pipeline.

Resources