Jenkinsfile does not take into account conditional on branch - jenkins

Here are the stages of my Jenkinsfile
stages {
stage("build") {
when {
expression {
BRANCH_NAME = 'alerta_dev_infra'
}
}
steps {
echo 'buidling the webhook'
}
}
stage("test") {
when {
expression {
env.BRANCH_NAME = 'alerta*'
}
}
steps {
echo 'testing the webhook'
}
}
stage("deploy") {
when {
expression {
env.BRANCH_NAME = 'alerta_dev_infra'
}
}
steps {
echo 'deploying the webhook'
}
}
}
However, when it is executed:
14:10:00 Push event to branch alerta_dev_infra
14:10:00 Started by user pkaramol#foo.bar
14:10:00 Rebuilds build #9
14:10:49 First time build. Skipping changelog.
14:10:49 [Pipeline] }
14:10:49 [Pipeline] // stage
14:10:49 [Pipeline] withEnv
14:10:49 [Pipeline] {
14:10:49 [Pipeline] container
14:10:49 [Pipeline] { (hide)
14:10:49 [Pipeline] stage
14:10:49 [Pipeline] { (build)
14:10:49 Stage "build" skipped due to when conditional
14:10:49 [Pipeline] }
14:10:50 [Pipeline] // stage
14:10:50 [Pipeline] stage
14:10:50 [Pipeline] { (test)
14:10:50 Stage "test" skipped due to when conditional
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // stage
14:10:50 [Pipeline] stage
14:10:50 [Pipeline] { (deploy)
14:10:50 Stage "deploy" skipped due to when conditional
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // stage
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // container
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // withEnv
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // node
14:10:50 [Pipeline] }
14:10:50 [Pipeline] // podTemplate
14:10:50 [Pipeline] End of Pipeline

This worked for me
when {
expression {
return env.GIT_BRANCH == "origin/master"
}
}

I have used the Choice Parameter to provide three choices for branch to select: master, develop and feature-1
Here is the pipeline code to use when conditional on BRANCH_NAME parameter
pipeline {
agent any
stages {
stage ('Build in master') {
when {
expression { params.BRANCH_NAME == 'master' }
}
steps {
echo "Building in master"
}
}
stage ('Build in develop')
{
when {
expression { params.BRANCH_NAME == 'develop' }
}
steps {
echo "Building in develop"
}
}
stage ('Build in feature')
{
when {
expression { params.BRANCH_NAME == 'feature-1' }
}
steps {
echo "Building in feature-1"
}
}
}
}
Output of the pipeline job:

Related

Trigger a multibranch pipeline when there is a change in files in specific folder

I want to run a multibranch pipeline when some files in a folder are pushed to BitBucket . I have tried with polling ignores commits to certain paths. But pipeline is not triggering . Can anyone help to solve the issue. How the path should be exactly specified inside included region of polling ignores commits to certain paths.
I used the following Jenkinsfile in a Git repo that contains 1.txt and 2.txt:
pipeline {
agent any
stages {
stage('1.txt in changelog') {
when {
// see https://www.jenkins.io/doc/book/pipeline/syntax/#built-in-conditions
changelog '1.txt'
}
steps {
echo '1.txt in changelog'
}
}
stage('2.txt in changelog') {
when {
changelog '2.txt'
}
steps {
echo '2.txt in changelog'
}
}
stage('1.txt in changeset') {
when {
changeset '1.txt'
}
steps {
echo '1.txt in changeset'
}
}
stage('2.txt in changeset') {
when {
changeset '2.txt'
}
steps {
echo '2.txt in changeset'
}
}
}
}
After changing and pushing 2.txt the Console Output of an according Multibranch Pipeline project showed:
...
[Pipeline] // stage
[Pipeline] withEnv
[Pipeline] {
[Pipeline] stage
[Pipeline] { (1.txt in changelog)
Stage "1.txt in changelog" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (2.txt in changelog)
[Pipeline] echo
2.txt in changelog
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (1.txt in changeset)
Stage "1.txt in changeset" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (2.txt in changeset)
[Pipeline] echo
2.txt in changeset
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
The same applies to creation of 2.txt but not to deletion of it.

Jenkins Pipeline with conditional "When" expression of choice parameters

I'm new to Groovy. I'm not able to figure out what's wrong here.
Depends on the choice of input, I expect the script to execute either Step 'Hello' or 'Bye' but it skips both. I mostly orientated to this Jenkins pipeline conditional stage using "When" for choice parameters, but still can't figure it out.
How can I use those choice parameters correctly?
pipeline {
agent any
stages {
stage('Init') {
steps('Log-in'){
echo 'Log-in'
}
}
stage('Manual Step') {
input {
message "Hello or Goodbye?"
ok "Say!"
parameters{choice(choices:['Hello','Bye'], description: 'Users Choice', name: 'CHOICE')}
}
steps('Input'){
echo "choice: ${CHOICE}"
echo "choice params.: " + params.CHOICE //null
echo "choice env: " + env.CHOICE //Hello
}
}
stage('Hello') {
when{ expression {env.CHOICE == 'Hello'}}
steps('Execute'){
echo 'Say Hello'
}
}
stage('Bye') {
when{ expression {env.CHOICE == 'Bye'}}
steps('Execute'){
echo 'Say Bye'
}
}
}
}
Output:
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Init)
[Pipeline] echo
Log-in
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Manual Step)
[Pipeline] input
Input requested
Approved by Admin
[Pipeline] withEnv
[Pipeline] {
[Pipeline] echo
choice: Hello
[Pipeline] echo
choice params.: null
[Pipeline] echo
choice env: Hello
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Hello)
Stage "Hello" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Bye)
Stage "Bye" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
From the docs:
Any parameters provided as part of the input submission will be available in the environment for the rest of the stage.
This means that your parameter CHOICE does not exist in the other stages. If you want to have a parameter that's available on all the stages, you can define a parameter outside of the stage, i.e.:
pipeline {
agent any
parameters {
choice(choices:['Hello','Bye'], description: 'Users Choice', name: 'CHOICE')
}
stages {
stage('Init') {
steps('Log-in') {
echo 'Log-in'
}
}
stage('Manual Step') {
steps('Input') {
echo "choice: ${CHOICE}"
echo "choice params.: " + params.CHOICE
echo "choice env: " + env.CHOICE
}
}
stage('Hello') {
when {
expression { env.CHOICE == 'Hello' }
}
steps('Execute') {
echo 'Say Hello'
}
}
stage('Bye') {
when {
expression {env.CHOICE == 'Bye'}
}
steps('Execute'){
echo 'Say Bye'
}
}
}
}
This will behave as expected. The difference is that the job won't ask you for input, instead, you will provide the wanted parameters before pressing build.

jenkinsfile not passing env to sh

I am trying to set environment variable in Jenkinsfile following way,
pipeline {
agent { label 'slave1' }
stages {
stage ('Build') {
steps {
script {
BUILD_VERSION = sh (
script: 'python get_firmware_version.py',
returnStdout: true
).trim()
}
echo "${BUILD_VERSION}"
withCredentials([file(credentialsId: 'image-sign', variable: 'IMAGE_SIGN')]) {
dir('firmware/') {
echo "${BUILD_VERSION}"
sh '''
echo "Building"
echo "${BUILD_VERSION}"
echo "${env.BUILD_VERSION}"
'''
}
}
}
}
}
post {
failure {
script {
echo "Pipeline Failed"
}
}
}
}
But its failing with following error Bad substitution
[Pipeline] echo
0_2_0
[Pipeline] sh
+ echo Building
Building
/home/jenkins/jenkins_slave/workspace/Firmware/Branch/firmware#tmp/durable-54e04481/script.sh: 3: /home/jenkins/jenkins_slave/workspace/Firmware/Branch/firmware#tmp/durable-54e04481/script.sh: Bad substitution
Why I can't set ENV Var and use it in sh step ?
This is Jenkins thing I think. When you use the sh block with '; it will not have access to things like environment variables. Try using the " instead. That should work
sh """
echo "Building"
echo "${env.BUILD_VERSION}"
echo "${env}"
"""
Jenkins should recognise the shell block and escape the " within the """ automatically.
pipeline {
agent { label 'slave1' }
stages {
stage ('Build') {
steps {
script {
BUILD_VERSION = sh (
script: 'python get_firmware_version.py',
returnStdout: true
).trim()
}
echo "${BUILD_VERSION}"
withCredentials([file(credentialsId: 'image-sign', variable: 'IMAGE_SIGN')]) {
dir('firmware/') {
echo "${BUILD_VERSION}"
sh """
echo "Building"
echo "${BUILD_VERSION}"
echo "${env.BUILD_VERSION}"
"""
}
}
}
}
}
post {
failure {
script {
echo "Pipeline Failed"
}
}
}
}
My test case
pipeline {
agent {
node {
label 'devops-jenkins-slave'
}
}
options {
timestamps()
}
stages {
stage('Setup'){
steps {
dir("${WORKSPACE}/"){
script {
BUILD_VERSION = "1"
}
sh """
echo "${BUILD_VERSION}"
"""
}
}
}
}
post {
always {
dir("${WORKSPACE}/"){
deleteDir()
}
}
}
}
Result
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on devops-jenkins-slave in /home/jenkins/workspace/Samples/Test
[Pipeline] {
[Pipeline] timestamps
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Setup)
[Pipeline] dir
22:09:55 Running in /home/jenkins/workspace/Samples/Test
[Pipeline] {
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] sh
22:09:56 [Test] Running shell script
22:09:56 + echo 1
22:09:56 1
[Pipeline] }
[Pipeline] // dir
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Declarative: Post Actions)
[Pipeline] dir
22:09:56 Running in /home/jenkins/workspace/Samples/Test
[Pipeline] {
[Pipeline] deleteDir
[Pipeline] }
[Pipeline] // dir
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // timestamps
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Executing parallel stages with declarative pipeline only using last item from list

I'm not sure what i'm doing wrong here, since currently when i try to iterate on a list the creation of the stages seems fine, but when executing the shellscript, the value used is allways the last item of the list:
Working pipeline:
pipeline {
agent any
stages {
stage('set servers') {
steps {
script {
my_list = ['server1','server-2','server-3']
}
}
}
stage('Execute then') {
parallel {
stage('shouter') {
steps {
script {
shouter = [:]
script {
for(i in my_list) {
shouter["${i}"] = {
echo "standupandshout.sh ${i}"
}
}
}
parallel shouter
}
}
}
}
}
}
}
Output:
Console Output:
Replayed #4
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/test
[Pipeline] {
[Pipeline] stage
[Pipeline] { (set servers)
[Pipeline] script
[Pipeline] {
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Execute then)
[Pipeline] parallel
[Pipeline] [shouter] { (Branch: shouter)
[Pipeline] [shouter] stage
[Pipeline] [shouter] { (shouter)
[Pipeline] [shouter] script
[Pipeline] [shouter] {
[Pipeline] [shouter] script
[Pipeline] [shouter] {
[Pipeline] [shouter] }
[Pipeline] [shouter] // script
[Pipeline] [shouter] parallel
[Pipeline] [server1] { (Branch: server1)
[Pipeline] [server-2] { (Branch: server-2)
[Pipeline] [server-3] { (Branch: server-3)
[Pipeline] [server1] echo
[server1] standupandshout.sh server-3
[Pipeline] [server1] }
[Pipeline] [server-2] echo
[server-2] standupandshout.sh server-3
[Pipeline] [server-2] }
[Pipeline] [server-3] echo
[server-3] standupandshout.sh server-3
[Pipeline] [server-3] }
[Pipeline] [shouter] // parallel
[Pipeline] [shouter] }
[Pipeline] [shouter] // script
[Pipeline] [shouter] }
[Pipeline] [shouter] // stage
[Pipeline] [shouter] }
[Pipeline] // parallel
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS
Desired output:
[Pipeline] [server1] echo
[server1] standupandshout.sh server-1
[Pipeline] [server1] }
[Pipeline] [server-2] echo
[server-2] standupandshout.sh server-2
[Pipeline] [server-2] }
[Pipeline] [server-3] echo
[server-3] standupandshout.sh server-3
This is due to groovy closures and when the code they contain gets evaluated.
http://blog.freeside.co/2013/03/29/groovy-gotcha-for-loops-and-closure-scope/
When the closures are run the value that is bound to the variable i is the value it had on the final iteration of the loop rather than the iteration where the closure was created. The closures' scopes have references to i and by the time any of the closures are executed i is 5.
Variables local to the loop body do not behave like this, obviously because each closure scope contains a reference to a different variable
This is why your stage name is ok but your value is not.
What’s the solution? Should we always use .each rather than a for loop? Well, I kind of like for loops in many cases and there can be memory utilization differences (don’t take that to mean loops are "better" or "more efficient").
If you simply alias the loop variable and refer to that alias in the
closure body all will be well
def fns = []
for (i in (1..5)) {
def myi = i
def isq = i * i
fns << {->
println "$myi squared is $isq"
}
}
fns.each { it() }
So this should work:
script {
shouter = [:]
for(i in my_list) {
def val = i
shouter["${i}"] = {
echo "standupandshout.sh ${val}"
}
}
parallel shouter
}

BlueOcean is showing green steps even when Pipeline is broken

I am using Jenkins Declarative syntax to define my pipeline.
My pipeline is broken in my Sonar Quality Gate and all the stages are skipped but the latest one is showing green denoting successful.
Is this an issue with the BlueOcean Plugin or I am doing something wrong:
BlueOcean View
My Code
pipeline{
agent { label 'maven-build-slave' }
options {
skipDefaultCheckout()
buildDiscarder(logRotator(numToKeepStr: '5'))
}
stages{
stage("Checkout Project"){
steps{
checkout scm
}
}
stage('Unit Test & Build Application') {
steps{
buildApplication()
}
}
stage("Sonar Quality & Security"){
steps{
sonarScanner()
sonarAnalysis()
}
}
stage('Checkout JBoss Binaries') {
steps{
checkoutBinaries()
}
}
stage('Pull WARs') {
steps{
copyBuildArtifacts()
}
}
stage('Pull Configuration') {
steps{
pullConfiguration()
}
}
stage('Configure Vaults') {
steps{
configureVaults()
}
}
stage('Configure Secrets') {
steps{
configureConfigMap()
}
}
stage('Configure Properties') {
steps{
configureBuildConfig()
}
}
stage('Deploy Image') {
steps{
configureAndDeploy()
}
}
stage("Integration Tests"){
parallel {
stage("Integration (REST API)"){
steps{
runIntegrationTestsRest()
}
}
stage("Integration (Workflow)"){
steps{
runIntegrationTestsWorkflow()
}
}
stage("Integration (SoapUI)"){
agent { label 'jenkins-slave-soapui' }
steps{
runIntegrationTestSoapUi()
}
}
}
}
}
post{
always{
script{
sendNotification status: currentBuild.result,
subject: "Deployment Completed"
}
}
}
}
Jenkins logs
The Jenkins logs show the rest of the stages that were skipped:
Stage 'Checkout JBoss Binaries' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Pull WARs)
Stage 'Pull WARs' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Pull Configuration)
Stage 'Pull Configuration' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Configure Vaults)
Stage 'Configure Vaults' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Configure Secrets)
Stage 'Configure Secrets' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Configure Properties)
Stage 'Configure Properties' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Deploy Image)
Stage 'Deploy Image' skipped due to earlier failure(s)
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (Integration Tests)
Stage 'Integration Tests' skipped due to earlier failure(s)
[Pipeline] parallel
[Pipeline] [Integration (REST API)] { (Branch: Integration (REST API))
[Pipeline] [Integration (Workflow)] { (Branch: Integration (Workflow))
[Pipeline] [Integration (SoapUI)] { (Branch: Integration (SoapUI))
[Pipeline] [Integration (REST API)] stage
[Pipeline] [Integration (REST API)] { (Integration (REST API))
[Pipeline] [Integration (Workflow)] stage
[Pipeline] [Integration (Workflow)] { (Integration (Workflow))
[Pipeline] [Integration (SoapUI)] stage
[Pipeline] [Integration (SoapUI)] { (Integration (SoapUI))
Stage 'Integration (REST API)' skipped due to earlier failure(s)
Stage 'Integration (Workflow)' skipped due to earlier failure(s)
Stage 'Integration (SoapUI)' skipped due to earlier failure(s)
[Pipeline] [Integration (REST API)] }
[Pipeline] [Integration (Workflow)] }
[Pipeline] [Integration (SoapUI)] }
[Pipeline] [Integration (REST API)] // stage
[Pipeline] [Integration (Workflow)] // stage
[Pipeline] [Integration (SoapUI)] // stage
[Pipeline] [Integration (REST API)] }
[Pipeline] [Integration (Workflow)] }
[Pipeline] [Integration (SoapUI)] }
[Pipeline] // parallel
[Pipeline] }
Any ideas?
I would like to see the Integration Test Stage as empty also. I didn't run the tests at all, the only issue here is the green color is essentially a false-positive for my pipeline.

Resources