For example I have following job and I would like to put condition using when, right now it doesn't allow me to put when inside parallel, I only want to run testusers if bool is true
dir("abc") {
parallel (users: {
sh "add_user users.json"
},
when{ ${TEST_USERS} == "true" }
testusers: {
sh "add_user testusers.json"
})
}
}
}
when blocks only operate on stages, so something like:
parallel {
stage('testusers') {
when {
environment name: 'TEST_USERS', value: 'true'
}
steps {
sh "add_user testusers.json"
}
stage('users') {
steps {
sh "add_user users.json"
}
}
}
In scripted, you would just use an if block. This looks like:
parallel ([
'users': {
sh 'add_user users.json'
},
'testusers': {
if (TEST_USERS == 'true') {
sh 'add_user testusers.json'
}
}
])
Related
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
I would like to run pipeline with 2 stages. If any of the stage is failed, next stage should be started (not skipped). Currently if 1st stage is failed, next stage will be skipped.
Thank you for any help.
pipeline {
options { buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '5')) }
agent { label 'docker_gradle' }
triggers {
cron(env.BRANCH_NAME == 'develop' || env.BRANCH_NAME == 'master' ? '#daily' : '')
}
stages {
stage('Init') {
steps {
sh 'chmod +x gradlew'
}
}
stage('task1') {
when { anyOf { branch 'feature/*'; branch 'develop' }}
steps {
container(name: 'gradle') {
sh 'gradle clean task1'
}
}
}
stage('task2') {
when { anyOf { branch 'feature/*'; branch 'develop' }}
steps {
container(name: 'gradle') {
sh 'gradle clean task2'
}
}
}
}
post {
always {
script {
currentBuild.result = currentBuild.result ?: 'SUCCESS'
cucumber buildStatus: 'UNSTABLE',
failedFeaturesNumber: 1,
failedScenariosNumber: 1,
skippedStepsNumber: 1,
failedStepsNumber: 1,
reportTitle: 'Reoport',
fileIncludePattern: '**/cucumber.json',
sortingMethod: 'ALPHABETICAL',
trendsLimit: 100
}
}
}
}
1.You can change sh 'gradle clean task1' to
sh 'gradle clean task1 || true'
This will make sh return success even if sh scrip fails
2.You can also use try catch
Check this link: https://www.jenkins.io/doc/book/pipeline/syntax/#flow-control
for example:
stage("task1"){
steps {
script {
try {
sh 'gradle clean task1'
} catch (err) {
echo err.getMessage()
}
}
}
}
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"
}
}
}
I try to use the post steps with the Jenkins kubernetes plugin. Does anyone has an idea?
java.lang.NoSuchMethodError: No such DSL method 'post' found among steps
My pipeline:
podTemplate(
label: 'jenkins-pipeline',
cloud: 'minikube',
volumes: [
hostPathVolume(mountPath: '/var/run/docker.sock', hostPath: '/var/run/docker.sock'),
]) {
node('jenkins-pipeline') {
stage('test') {
container('maven') {
println 'do some testing stuff'
}
}
post {
always {
println "test"
}
}
}
}
As of this writing, Post is only supported in declarative pipelines.
You could have a look at their declarative example if you absolutely must use post.
pipeline {
agent {
kubernetes {
//cloud 'kubernetes'
label 'mypod'
containerTemplate {
name 'maven'
image 'maven:3.3.9-jdk-8-alpine'
ttyEnabled true
command 'cat'
}
}
}
stages {
stage('Run maven') {
steps {
container('maven') {
sh 'mvn -version'
}
}
}
}
}
This example shows how to use the post step using the Kubernetes plugin:
pipeline {
agent {
kubernetes {
label "my-test-pipeline-${BUILD_NUMBER}"
containerTemplate {
name "my-container"
image "alpine:3.15.0"
command "sleep"
args "99d"
}
}
}
stages {
stage('Stage 1') {
steps {
container('my-container') {
sh '''
set -e
echo "Hello world!"
sleep 10
echo "I waited"
echo "forcing a fail"
exit 1
'''
}
}
}
}
post {
unsuccessful {
container('my-container') {
sh '''
set +e
echo "Cleaning up stuff here"
'''
}
}
}
}
I have several jenkins pipelines that in my case call "docker-compose up" at the end of the build to run the containers/application. Now, I don't need the containers/application to be up all the time and I would like to have a way from the jenkins pipeline page to shutdown (docker-compose stop) the application to free resources for other builds. Do you know any good way to do this?
You can declare a choice parameter (ex: stop_containers) with values YES and NO in your Jenkins job that is responsible for stopping the containers.
Then in the Build section select Execute shell and add the following script to it:
#!/bin/bash
if [ "$stop_containers" = "YES" ]
then
//Command for stopping containers....
else
echo "Do Nothing."
fi
Now, whenever you will run your job it will ask if you want to stop the containers or not. Choose the required option, YES if you want to stop the containers.
If it is a Pipeline Job then you can define a stage to perform the stopping the container operation.
stage('stop containers') {
properties(
[parameters([choice(choices: ["YES", "NO"].join("\n"),
description: 'Some choice parameter',
name: 'STOP_CONTAINERS')])])
agent label:'some-node'
when {
expression {
return env.STOP_CONTAINERS = 'YES';
}
}
steps {
//command to stop containers
}
}
This is the way I have done it looking at
Converting Conditional Build Steps to Jenkins Pipeline.
pipeline {
agent any
parameters {
choice(
choices: 'full_deploy_and_run_docker_container\nrun_docker_containers\nstop_docker_containers',
description: '',
name: 'REQUESTED_ACTION')
}
tools {
maven 'Maven x.x.x'
jdk 'jdkYuWZ'
}
environment {
SVN_URL = 'http://svn.myexample.com/svn/myproject/trunk/'
DOCKER_PROJECT_DIR = '/home/myuser/docker/containers/myproject/trunk'
}
stages {
stage ('Initialize') {
steps {
sh '''
echo "Initialize..."
'''
}
}
stage ('Checkout') {
when {
expression { params.REQUESTED_ACTION == 'full_deploy_and_run_docker_container' }
}
steps {
checkout([$class: 'SubversionSCM', additionalCredentials: [], excludedCommitMessages: '', excludedRegions: '', excludedRevprop: '', excludedUsers: '', filterChangelog: false, ignoreDirPropChanges: false, includedRegions: '', locations: [[credentialsId: ' something here ', depthOption: 'infinity', ignoreExternalsOption: true, local: '.', remote: "$SVN_URL"]], workspaceUpdater: [$class: 'UpdateUpdater']])
}
}
stage ('Build') {
when {
expression { params.REQUESTED_ACTION == 'full_deploy_and_run_docker_container' }
}
steps {
sh 'mvn clean package'
}
}
stage ('Test') {
when {
expression { params.REQUESTED_ACTION == 'full_deploy_and_run_docker_container' }
}
steps {
sh 'echo "Other tests..."'
}
}
stage ('Deploy') {
when {
expression { params.REQUESTED_ACTION == 'full_deploy_and_run_docker_container' }
}
steps {
sh 'echo "The deploy here"'
}
}
stage ('Docker compose run') {
when {
expression { params.REQUESTED_ACTION == 'full_deploy_and_run_docker_container' ||
params.REQUESTED_ACTION == 'run_docker_containers'
}
}
steps {
sh '''
cd $DOCKER_PROJECT_DIR
docker-compose up -d
'''
}
}
stage ('Docker compose stop') {
when {
expression { params.REQUESTED_ACTION == 'stop_docker_containers' }
}
steps {
sh '''
cd $DOCKER_PROJECT_DIR
docker-compose stop
'''
}
}
stage ('Cleanup') {
steps {
cleanWs()
}
}
}
}
A simple way, you can use sh command in jenkins pipeline for this.
node {
stage('stop') {
sh "ssh root#host.com"
sh "cd /diretorio_do_docker-compose/"
sh "docker-compose stop"
}
}