Jenkins pipeline with parallel - jenkins

Here is my Jenkins pipeline that i am trying to execute. I am following this tutorial:
pipeline {
agent any
stages {
stage('one') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
stage('two') {
parallel "first" : {
echo "hello"
},
"second": {
echo "world"
}
}
}
}
But the job fails with following message.
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 4: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. # line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Unknown stage section "parallel". Starting with version 0.5, steps in a stage must be in a steps block. # line 12, column 9.
stage('two') {
^
WorkflowScript: 4: Nothing to execute within stage "one" # line 4, column 9.
stage('one') {
^
WorkflowScript: 12: Nothing to execute within stage "two" # line 12, column 9.
stage('two') {
^
4 errors
Can someone please help me out why this is failing.

You need to add a steps block after your stage declaration.
pipeline {
agent any
stages {
stage('Example Stage 1') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
stage('Example Stage 2') {
steps {
parallel(
"step 1": { echo "hello" },
"step 2": { echo "world" },
"step 3": { echo "world" }
)
}
}
}
}
To Make your Stages Parallel use this, both solutions show up very similar in Blue Ocean :
pipeline {
agent any
stages {
stage('Example Stage') {
parallel {
stage('Stage 1') {
steps { sh 'echo stage 1 passed' }
}
stage('Stage 2') {
steps { sh 'echo stage 2 passed' }
}
stage('Stage 3') {
steps { sh 'echo stage 3 passed' }
}
}
}
}
}

You need to upgrade the Declarative Pipeline plugin on your Jenkins to Version 1.2 (Sept 21, 2017) or above

In declarative pipeline, in case if you want to add stage, inside steps, this nesting is also possible.
If the steps are same in that case you can declare step as a function.
def steps = ['first', 'second']
def generateSteps(stepLabel) {
return {
step("${stepLabel}") {
echo "Running on ${stepLabel}"
}
}
}
def parallelStepMap = steps.collectEntries {
["${it}" : generateSteps(it)]
}
pipeline {
agent any
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStepMap
}
}
}
}
}
General need is to execute different stages into different nodes.
in such case above function can be modified to execute on different agent nodes as follows.
def agents = ['master', 'agent1', 'agent2']
def generateStage(nodeLabel) {
return {
stage("Runs on ${nodeLabel}") {
node(nodeLabel) {
echo "Running on ${nodeLabel}"
}
}
}
}
def parallelStagesMap = agents.collectEntries {
["${it}" : generateStage(it)]
}
pipeline {
agent none
stages {
stage('non-parallel stage') {
steps {
echo 'This stage will be executed first.'
}
}
stage('parallel stage') {
steps {
script {
parallel parallelStagesMap
}
}
}
}
}
With nodelabel defined inside the function and agent none during start of pipeline, the stages will be executed into different nodes.

Related

How to use parallelsAlwaysFailFast() in scripted pipeline?

How to use parallelsAlwaysFailFast() in Jenkins Scripted Pipeline?
I could not find any example for this.
Edited, here is the code I use and the 'Blue Ocean' screenshot:
stage("Build") {
parallel([
failFast: true,
"Stage 1":{
stage("Stage 1") {
stage("a1") {
println("a1")
};
stage("a2") {
println("a2")
}
}
},
"Stage 2":{
stage("Stage 2") {
stage("b1") {
sh '''pwd'''
};
stage("b2") {
echo '''Here we can see the InterruptedException'''
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
error "Failing the stage"
}
}
}
}
])
}
Blue Ocean img
How can I make all the stages that are executed in parallel to fail as well?
Thanks.
As far as I know, there is no way to change that behavior for all the future parallel stages.
However one can change it for any given set of parallel stages, like this:
def parallel_stages = [:].asSynchronized()
parallel_stages['one'] = {
stage ('One') {
script {
println "One"
}
}
}
parallel_stages['two'] = {
stage ('Two') {
script {
println "Two"
}
}
}
// Here you set this for the given parallel stage
parallel_stages.failFast = true
parallel parallel_stages

Jenkins pipeline execute job and get status

pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
script {
def job_exec_details = build job: 'build_job'
if (job_exec_details.status == 'Failed') {
echo "JOB FAILED"
}
}
}
}
}
}
I have a pipeline that executing build job, how can I get Job result in jenkins pipeline ?
It should be getResult() and status should be FAILURE not Failed.
so your whole code should be like this
pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
script {
def job_exec_details = build job: 'build_job', propagate: false, wait: true // Here wait: true means current running job will wait for build_job to finish.
if (job_exec_details.getResult() == 'FAILURE') {
echo "JOB FAILED"
}
}
}
}
}
}
Where is a second way of getting results:
pipeline {
agent { label 'master' }
stages {
stage('test') {
steps {
build(job: 'build_job', propagate: true, wait: true)
}
}
}
post {
success {
echo 'Job result is success'
}
failure {
echo 'Job result is failure'
}
}
}
}
You can read more about 'build' step here

Jenkins multipe post sections per stage

I have two question for usage of post section in Jenkins pipeline
1.Can we use multiple post section per stage in Jenkins declarative Pipeline?
2.Can we run sh command in post section?
pipeline{
stages{
stage("....") {
steps {
script {
....
}
}
post {
failure{
sh "....."
}
}
stage("Second stage") {
when {
expression { /*condition */ }
}
steps {
script{
....
}
post {
always {
script {
sh "..."
}
}
}
}
}
You can find information in https://jenkins.io/doc/book/pipeline/syntax/#post
pipeline {
agent any
stages {
stage('Example') {
steps {
echo 'Hello World'
}
}
}
post {
success {
sh label: 'success', script: 'ls'
}
failure {
sh label: 'failure', script: 'ls'
}
aborted {
sh label: 'aborted', script: 'ls'
}
}
}
You can use Post steps each Stage, but pipeline will stop on first failure. In example below, if Stage 1 fail Stage 2 will be skipped. Post after all stages will always executed.
pipeline{
stages{
stage("Stage 1") {
steps {
catchError(message: 'catch failure') {
script {
sh "echo stage 1"
}
}
}
post {
always {
sh "echo post stage 1"
}
}
}
stage("Stage 2") {
when {
expression { /*condition */ }
}
steps {
script{
sh "echo stage 2"
}
}
post {
always {
script {
sh "echo post stage 2"
}
}
}
}
}
post {
always {
sh "echo post after all stages"
}
}
}

How to run multi stages at the same time using multi parallel blocks?

Here, I need to execute both Parallel test 1 and Parallel test 2 at the same time.
When I tried to put a parallel block on top of these, it throws an error since it mentioned like this in the official site Note: that a stage must have one and only one of steps, stages, or parallel.
pipeline {
agent any
stages {
stage('Parallel Test 1') {
parallel {
stage('Block 1 - Stage 1') {
steps {
echo "Block 1 - Stage 1"
build(job: 'jenkins_job_1')
}
}
stage('Block 1 - Stage 2') {
steps {
echo "Block 1 - Stage 2"
build(job: 'jenkins_job_2')
}
}
}
}
stage('Parallel Test 2') {
parallel {
stage('Block 2 - Stage 1') {
steps {
echo "Block 2 - Stage 1"
build(job: "jenkins_job_3")
}
}
stage('Block 2 - Stage 2') {
steps {
echo "Block 2 - Stage 2"
build(job: "jenkins_job_4")
}
}
}
}
}
}
You don't have to put each call to a parallel-job inside a stage, so you can do it as such:
pipeline {
agent any
stages {
stage('single run') {
parallel {
stage('Parallel Test 1') {
steps {
script {
def group1 = [:]
group1["test_1"] = {
echo "test_1"
sh(script: "date -u")
build(job: 'jenkins_job_1')
}
group1["test_2"] = {
echo "test_2"
sh(script: "date -u")
build(job: 'jenkins_job_2')
}
parallel group1
}
}
}
stage('Parallel Test 2') {
steps {
script {
def group2 = [:]
group2["test_3"] = {
echo "test_3"
sh(script: "date -u")
build(job: 'jenkins_job_3')
}
group2["test_4"] = {
echo "test_4"
sh(script: "date -u")
build(job: 'jenkins_job_4')
}
parallel group2
}
}
}
}
}
}
}

How to modify variable defined in script block in declarative pipeline of jenkins

I have declared a variable TENTATIVE_VERSION in my script, and I need to define/modify it with the value coming from executing a script (or from the script itself in other stage), how can I do this? my current script is something like this:
pipeline {
agent {
label 'machine1'
}
stages {
stage('Non-Parallel Stage') {
agent{label "machine2"}
steps {
script {
TENTATIVE_VERSION="1.0" // working
// TENTATIVE_VERSION="sh echo 123" //not working
}
}
}
stage('Parallel Stage') {
parallel {
stage('A') {
agent {label 'machine3'}
steps {
echo "On other machine"
echo "${TENTATIVE_VERSION}"
build job: 'otherJob', parameters: [[$class: 'StringParameterValue', name: 'VERSION', value: "${TENTATIVE_VERSION}"],
[$class: 'StringParameterValue', name: 'RELEASE', value: '1']]
}
}
stage('B') {
agent {label "machine4"}
steps {
script {
STATUS_S = "OK"
}
echo "On a machine"
}
}
stage('C') {
agent {label "machine5"}
steps {
script {
STATUS_R = "OK"
}
echo "On a machine"
}
}
}
}
}
Try following:
pipeline {
agent {
label 'machine1'
}
stages {
stage('Non-Parallel Stage') {
agent{label "machine2"}
steps {
script {
TENTATIVE_VERSION = sh(returnStdout: true, script: "echo 123").trim()
}
}
}
}
}

Resources