How to define jenkins build trigger in jenkinsfile to start build after other job - jenkins-pipeline

I would like to define a build trigger in my Jenkinsfile. I know how to do it for the BuildDiscarderProperty:
properties([[$class: 'jenkins.model.BuildDiscarderProperty', strategy: [$class: 'LogRotator', numToKeepStr: '50', artifactNumToKeepStr: '20']]])
How can I set the Build Trigger that starts the job, when another project has been built. I cannot find a suitable entry in the Java API docs.
Edit:
My solution is to use the following code:
stage('Build Agent'){
if (env.BRANCH_NAME == 'develop') {
try {
// try to start subsequent job, but don't wait for it to finish
build job: '../Agent/develop', wait: false
} catch(Exception ex) {
echo "An error occurred while building the agent."
}
}
if (env.BRANCH_NAME == 'master') {
// start subsequent job and wait for it to finish
build '../Agent/master', wait: true
}
}

I just looked for the same thing and found this Jenkinsfilein jenkins-infra/jenkins.io
In short:
properties([
pipelineTriggers([cron('H/30 * * * *')])
])

This is an example:
#Project test1
pipeline {
agent {
any
}
stages {
stage('hello') {
steps {
container('dind') {
sh """
echo "Hello world!"
"""
}
}
}
}
post {
success{
build propagate: false, job: 'test2'
}
}
}
post {} will be execute when project test1 is built and the code inside
success {} will only be executed when project test1 is successful.
build propagate: false, job: 'test2' will call project test2.
propogate: false ensures that project test1 does not wait for project test2's
completion and simply invokes it.

Related

Jenkins pipeline - edit build name on a build triggered from another pipeline

I have a Jenkins pipeline, that runs sereval other jobs. Something like
pipeline {
...
stage('Job_1') {
build job: 'job-1', parameters: [
...
string(name: 'BUILD_NAME', value: params.BUILD_NAME),
]
}
stage('Job_2') {
build job: 'job-2', parameters: [
...
string(name: 'BUILD_NAME', value: params.BUILD_NAME),
]
}
and job-1, job-2 being matrixJobs. I would like to set the build names using parameter passed to the parent pipeline. The job-1 looking like
matrixJob('job-1') {
...
parameters {
...
stringParam('BUILD_NAME', "#${BUILD_NUMBER} - x", 'Name for the build')
}
wrappers {
...
buildName("${BUILD_NAME}")
}
steps {
...
}
It seems in matrixJob parameters cannot be used in build name, I get error
ERROR: (job_1.groovy, line 39) No such property: BUILD_NAME for class: javaposse.jobdsl.dsl.helpers.wrapper.WrapperContext
I would like to ask how is it possible to change the build name to add e.g. a product version. Or perhaps if there is another way to achieve this besides passing build name as a parameter.
EDIT:
I worked around this problem using script in parent pipeline. Something like this
stage('Job_1') {
build job: 'job-1', parameters: [
...
]
}
stage('Job_2') {
build job: 'job-2', parameters: [
...
]
}
stage('Set_names') {
def build = jenkins.model.Jenkins.instance.getItem('job-1').lastBuild
if(build.getResult() != hudson.model.Result.SUCCESS) {
build.displayName = params.BUILD_NAME
}
}
no tweaking of child jobs was needed.
I worked around this problem using script in parent pipeline. Something like this
stage('Job_1') {
build job: 'job-1', parameters: [
...
]
}
stage('Job_2') {
build job: 'job-2', parameters: [
...
]
}
stage('Set_names') {
def build = jenkins.model.Jenkins.instance.getItem('job-1').lastBuild
if(build.getResult() != hudson.model.Result.SUCCESS) {
build.displayName = params.BUILD_NAME
}
}
no tweaking of child jobs was needed.

Retry and timeout in Jenkins DSL Pipeline job

I have a logic for deployment on certain environment that I need to retry. And that logic have some timeout too. So I wrote the DSL code as below:
Pipeline {
stages {
stage('Promote To Stage2 Environment') {
options {
timeout(time: "${env.STAGE_TIME_OUT}", unit: "HOURS")
retry("${env.RETRY_COUNT}")
}
steps {
script {
//my logic
}
}
}
}
}
Now , I need to perform rollback action and need to terminate pipeline job, in case retry exceeded or timeout exceeded while doing deployment on particular environment. So I modified the code as below:
pipeline {
stages {
stage('Promote To Stage2 Environment') {
steps {
script {
try {
timeout(time: "${env.STAGE_TIME_OUT}", unit: "HOURS") {
retry("${env.RETRY_COUNT}") {
//my logic
}
}
}
} catch (err) {
//Need rollback. action to be required , in case retry exceeded or timeout happen
performRollBack('env')
error('Deployment on Stage1 failed..... Build rolled back....')
}
}
}
}
}
Is this is a right way, or something I am missing.
you can also do like below example:
pipeline {
agent any
stages {
stage('debug') {
options {
timeout(time: 10, unit: 'SECONDS')
retry(2)
}
steps {
// uncomment below to check post failure
sh "exit 1"
// uncomment below to check post unsuccessful scenario
//sleep 100
}
}
}
post {
always {
echo 'I will execute always'
}
failure {
echo 'I will execute if a failure occured'
}
unsuccessful {
echo 'I will execute if a job is timedout and failed'
}
}
}
Retry scenario the output will be
Timeout scenario the output will be
you can find more post build action here

Is there a way to move the entire post {} build section in Jenkinsfile to the global pipeline library?

I'm relatively new to Jenkins pipelines, but having implemented already a few, I've realised I need to start using jenkins shared library before I go mad.
Have already figured out how to define some repetitive steps in the library and call them with less clutter from Jenkinsfile, but not sure if the same thing can be done for the entire post build section (thought I've read about to how to define the entire pipeline in the lib and similar), as this is pretty much static end of every single pipeline code:
#Library('jenkins-shared-library')_
pipeline {
agent none
stages {
stage ('System Info') { agent any
steps { printSysInfo() }
}
stage ('Init'){ agent {label 'WinZipSE'}
steps { init('SCMroot') }
}
stage('Build') { agent any
steps { doMagic() }
}
}
// This entire 'post {}' section needs to go to a shared lib
// and be called just with a simple methed call, e.g.
// doPostBuild()
post {
always {
node ('master') {
googlechatnotification (
message: '[$BUILD_STATUS] Build $JOB_NAME $BUILD_NUMBER has finished',
url: 'id:credential_id_for_Ubuntu')
step (
[$class: 'Mailer',
recipients: 'sysadmins#example.com me#example.com',
notifyEveryUnstableBuild: true,
sendToIndividuals: true]
)
}
}
success {
node ('master') {
echo 'This will run only if successful'
}
}
failure {
node ('master') {
echo 'This will run only if failed'
}
}
// and so on
}
}
I just dunno how to syntactically achieve that. For sure, I can define the entire post build section an a lib/var like: doPotBuild.groovy
def call () {
post {...}
}
but how I will eventually call it from within my Jenkinsfile outside of that defined post {} build block section (AKA stages).
I can call it within some stage('post build){doPostBuild()}, but it won't serve the way how the true post {} section is supposed to work, e.g. it won't get executed it there was failure in one of the previous stages.
Any thoughts on that and mainly working examples?
I am not entirely if this will work as I don't use declarative pipelines, so am unsure how rigid the top level structure is. But I would revert to a script block.
#Library('jenkins-shared-library')_
pipeline {
agent none
stages {
stage ('System Info') { agent any
steps { printSysInfo() }
}
stage ('Init'){ agent {label 'WinZipSE'}
steps { init('SCMroot') }
}
stage('Build') { agent any
steps { doMagic() }
}
}
// This entire 'post {}' section needs to go to a shared lib
// and be called just with a simple methed call, e.g.
// doPostBuild()
script {
doPostBuild()
}
}

How to trigger a multiple run in a single pipeline job of jenkins?

I have a pipeline job which run with below pipeline groovy script,
pipeline {
parameters{
string(name: 'Unique_Number', defaultValue: '', description: 'Enter Unique Number')
}
stages {
stage('Build') {
agent { node { label 'Build' } }
steps {
script {
sh build.sh
}
}
stage('Deploy') {
agent { node { label 'Deploy' } }
steps {
script {
sh deploy.sh
}
}
stage('Test') {
agent { node { label 'Test' } }
steps {
script {
sh test.sh
}
}
}
}
I just trigger this job multiple times with different unique ID number as input parameter. So as a result i will have multiple run/build for this job at different stages.
With this, i need to trigger a multiple run/build to be promote to next stage (i.e., from build to deploy or from deploy to test) in this pipeline job as a one single build instead of triggering each and every single run/build to next stage. Is there any possibility?
I was also trying to do the same thing and found no relevant answers. May this help to someone.
This will read a file that contains the Jenkins Job name and run them iteratively from one single job.
Please change below code accordingly in your Jenkins.
pipeline {
agent any
stages {
stage('Hello') {
steps {
script{
git branch: 'Your Branch name', credentialsId: 'Your crendiatails', url: ' Your BitBucket Repo URL '
##To read file from workspace which will contain the Jenkins Job Name ###
def filePath = readFile "${WORKSPACE}/ Your File Location"
##To read file line by line ###
def lines = filePath.readLines()
##To iterate and run Jenkins Jobs one by one ####
for (line in lines) {
build(job: "$line/branchName",
parameters:
[string(name: 'vertical', value: "${params.vertical}"),
string(name: 'environment', value: "${params.environment}"),
string(name: 'branch', value: "${params.aerdevops_branch}"),
string(name: 'project', value: "${params.host_project}")
]
)
}
}
}
}
}
}
You can start multiple jobs from one pipeline if you run something as:
build job:"One", wait: false
build job:"Two", wait: false
Your main job starts children pipelines and children pipelines will run in parallel.
You can read PipeLine Build Step documentation for more information.
Also, you can read about the parallel run in declarative pipeline
Here you can find a lot of examples for parallel running

How to skip a stage in Jenkinsfile pipeline when pipeline name ends with deliver?

I have 2 pipelines one for review and one for deploy. So when the pipeline ends with review, I want to skip Jenkinsfile execution. However, when it ends with deploy, it should execute the stage or the Jenkinsfile.
I tried to use if, but this is a declarative pipeline, so when should be used. I want to avoid execution of stage using when condition if I encounter deploy pipeline end.
#!/usr/bin/env groovy
final boolean Deploy = (env.JOB_NAME as String).endsWith("-deploy")
pipeline {
agent any
parameters {
choice(
choices: ['greeting' , 'silence'],
description: '',
name: 'REQUESTED_ACTION')
}
stages {
//how to ouse when here to use deploy vairable to avoide execution of stage below
stage ('Speak') {
steps {
echo "Hello, bitwiseman!"
}
}
}
}
You can skip stages in declarative pipelines using when, so the following should work.
stages {
stage('Deploy') {
when { equals expected: true, actual: Deploy }
steps {
// ...
}
}
}
An alternative to #StephenKing’s answer, which is also correct, you can rewrite the when block when evaluating Booleans as follows:
stages {
stage('Deploy') {
when {
expression {
return Deploy
}
}
steps {
echo "Hello, bitwiseman!" // Step executes only when Deploy is true
}
}
}
This will execute the stage Deploy only when the variable Deploy evaluates to true, else the stage will be skipped.
I've got quite a hard time to find it too, but finally:
stage('Speak') {
when {
expression { params.REQUESTED_ACTION != 'SILENCE' }
}
steps {
echo "Hello, bitwiseman!"
}
}
Jenkins docs with examples here: https://jenkins.io/doc/book/pipeline/syntax/#when-example
Here is an example for a Jenkins scripted pipeline:
stage('Input of Scratch instance and Access token') {
timeout(time: 60, unit: 'SECONDS') {
script {
try {
env.SCRATCH_INSTANCE_URL = input message: 'Please enter the SCRATCH_INSTANCE_URL',
parameters: [string(defaultValue: '',
description: '',
name: 'SCRATCH_INSTANCE_URL')]
env.SCRATCH_ACCESS_TOKEN = input message: 'Please enter the SCRATCH_ACCESS_TOKEN',
parameters: [string(defaultValue: '',
description: '',
name: 'SCRATCH_ACCESS_TOKEN')]
} catch (Throwable e) {
echo "Caught ${e.toString()}"
currentBuild.result = "SUCCESS"
}
}
}
}
// -------------------------------------------------------------------------
// Logout from Dev Hub.
// -------------------------------------------------------------------------
stage('Logout from DevHub') {
if (env.SCRATCH_INSTANCE_URL == null) {
rc = command '''export SFDX_USE_GENERIC_UNIX_KEYCHAIN=true
sfdx force:auth:logout --targetusername ${DEV_HUB_USERNAME} -p
echo ${SCRATCH_INSTANCE_URL}
echo ${SCRATCH_ACCESS_TOKEN}
'''
} else {
echo "Skipping this stage"
}
}
Even you can skip some parts of the steps using below code. Let's say REQUIRED_UPLOAD_INSTALL is a parameter.
stage('Checking Mail List') {
steps {
script {
if(!(env.REQUIRED_UPLOAD_INSTALL.toBoolean())) {
env.mail_list = 'test#testg.com'
}
}
}
}
But it doesn't support in post steps, not even in the when syntax.

Resources