how to i set discard old build in this script code in jenkins pipelinejob?
i am using this config in jenkins helm value on kubernetes
- script: >
pipelineJob('my-job') {
properties {
disableConcurrentBuilds()
pipelineTriggers {
triggers {
gitlab {
triggerOnPush(true)
branchFilterType('NameBasedFilter')
includeBranchesSpec('staging')
secretToken('123456')
cancelPendingBuildsOnUpdate(true)
}
}
}
}
definition {
cpsScm {
scriptPath 'jenkinsfile'
scm {
git {
remote {
credentials 'user'
url 'git-repo'
}
branch 'staging'
extensions {}
}
}
}
}
}
I find it.
- script: >
pipelineJob('my-job') {
logRotator {
numToKeep(10)
artifactNumToKeep(10)
}
properties {
disableConcurrentBuilds()
pipelineTriggers {
triggers {
gitlab {
triggerOnPush(true)
branchFilterType('NameBasedFilter')
includeBranchesSpec('staging')
secretToken('123456')
cancelPendingBuildsOnUpdate(true)
}
}
}
}
definition {
cpsScm {
scriptPath 'jenkinsfile'
scm {
git {
remote {
credentials 'user'
url 'git-repo'
}
branch 'staging'
extensions {}
}
}
}
}
}
Related
I have list of apps as checkboxes (using extended choice parameter with ',' as multiSelectDelimiter).
I want to execute a stage if a matching checkbox is checked, else skip it.
For eg: apps: app1,app3 [checkboxes selected]
checkboxes selected image
stages{
paralle{
stage('First'){
when {
// execute this when app1 is selected
}
steps {
}
}
stage('Second'){
when {
// execute this when app2 is selected, should skip this as 'app2' is not checked
}
steps {
}
}
stage('Third'){
when {
// execute this when app3 is selected
}
steps {
}
}
stage('Fourth'){
when {
// execute this when app4 is selected, else skip it
}
steps {
}
}
}
}
It can be done this way
def choice=[]
node {
choice = params["my-checkbox"].split(",")
}
pipeline {
agent any;
parameters {
checkboxParameter name:'my-checkbox', format:'JSON', uri:'https://raw.githubusercontent.com/samitkumarpatel/test0/main/checkbox.json'
/*
consider this is the structure of CheckBox in https://raw.githubusercontent.com/samitkumarpatel/test0/main/checkbox.json URI
{
"key": "stage1",
"value": "stage1"
},
{
"key": "stage2",
"value": "stage2"
},
{
"key": "stage3",
"value": "stage3"
}
*/
}
stages {
stage('stage1') {
when {
expression {
'stage1' in choice
}
}
steps {
echo "${env.STAGE_NAME} execuated"
}
}
stage('stage2') {
when {
expression {
'stage2' in choice
}
}
steps {
echo "${env.STAGE_NAME} execuated"
}
}
stage('stage3') {
when {
expression {
'stage3' in choice
}
}
steps {
echo "${env.STAGE_NAME} execuated"
}
}
}
}
This pipeline will run the stages which are selected during the build
with this parameter, it will only trigger stage1 and stage2
I used below piece in the pipeline to select the stage based on parameters provided in the Jenkins UI. "Boolean parameter" can be useful instead of "Extended Choice Parameter" to avoid clutter in the pipeline.
Reference - https://www.jenkins.io/doc/book/pipeline/syntax/#when
stage("Install Application1"){
when { environment name: 'APP_1', value: 'true' }
steps{
sh '''
Steps to install the application1
'''
}
}
stage("Install Application2"){
when { environment name: 'APP_2', value: 'true' }
steps{
sh '''
Steps to install the application2
'''
}
}
I've a pipeline where multiple stages run in parallel but if any of the stages fails, I want to get its name to show failed stage. With following code, even if it fails in first stage ie Checking Redmine access, it always show last stage as failed i.e. Checking Reviewers list. This is because it runs in parallel and latest assigned value is picked up.
pipeline {
agent {
label {
label "<machine-ip>"
customWorkspace "workspace/RedmineAndReviewboardProject/SVNCheckoutTest"
}
}
stages {
stage('Verify inputs') {
parallel {
stage('Checking Redmine access') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
echo "Redmine"
sh'''hello'''
}
}
}
stage('Checking SVN access') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
echo "SVN"
}
}
}
stage('Checking Reviewers list') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
echo "Reviewer"
}
}
}
}
}
}
post {
failure {
script {
echo "Failed stage is " + FAILED_STAGE
}
}
}
}
Is there any way I can get exactly failed stage of parallel running stages? or it will be also ok with me if parent stage name is returned as failed stage.
I believe you can use a post { failure { block for each stage : see https://www.jenkins.io/doc/book/pipeline/syntax/#post
pipeline {
agent {
label {
label "<machine-ip>"
customWorkspace "workspace/RedmineAndReviewboardProject/SVNCheckoutTest"
}
}
stages {
stage('Verify inputs') {
parallel {
stage('Checking Redmine access') {
steps {
script {
echo "Redmine"
sh'''hello'''
}
}
post {
failure {
script {
echo "Failed stage is ${STAGE_NAME}"
}
}
}
}
stage('Checking SVN access') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
echo "SVN"
}
}
post {
failure {
script {
echo "Failed stage is ${STAGE_NAME}"
}
}
}
}
stage('Checking Reviewers list') {
steps {
script {
FAILED_STAGE = env.STAGE_NAME
echo "Reviewer"
}
}
post {
failure {
script {
echo "Failed stage is ${STAGE_NAME}"
}
}
}
}
}
}
}
}
There is a way to execute steps/post-actions on different nodes in parallel described in this article: https://jenkins.io/blog/2017/09/25/declarative-1/
stage('Run Tests') {
parallel {
stage('Test On Windows') {
agent {
label "windows"
}
steps {
bat "run-tests.bat"
}
post {
always {
junit "**/TEST-*.xml" // DUPLICATE CODE
}
}
}
stage('Test On Linux') {
agent {
label "linux"
}
steps {
sh "run-tests.sh"
}
post {
always {
junit "**/TEST-*.xml" // DUPLICATE CODE
}
}
}
}
}
Is there any possibility to execute same stages on multiple nodes without duplicating code?
Something like this:
stage('Run Tests') {
parallel {
stage("Test On ${NODE_NAME}") {
agents {
label "windows"
label "linux"
}
steps {
// do test steps
}
post {
always {
junit "**/TEST-*.xml"
}
}
}
}
}
You can create dynamic stages, but for your case not needed
pipeline {
agent any
stages {
stage ("Test") {
steps {
script {
testStages = ["Windows", "Linux"].collectEntries {
["${it}" : runTests(it)]
}
parallel testStages
}
}
}
}
}
def runTests(def name){
return {
node(name) {
stage("Run on ${name}") {
script {
command = "run-tests"
try {
switch(name.toLowerCase()) {
case "windows":
command += ".bat"
break;
case "linux":
command += ".sh"
break;
}
echo command
} catch (Exception ex) {
echo ex
} finally {
echo "post ${name}"
}
}
}
}
}
}
Declarative Matrix worked best for me:
pipeline {
agent none
stages {
stage('BuildAndTest') {
matrix {
agent {
label "${PLATFORM}-agent"
}
axes {
axis {
name 'PLATFORM'
values 'linux', 'windows'
}
}
stages {
stage('Test') {
steps {
echo "Do Test for ${PLATFORM}"
}
}
}
post {
always {
junit "**/TEST-*.xml"
}
}
}
}
}
}
This pipeline will execute the defined stages incl. post build actions on both platforms without any code duplication.
Quote from a Jenkins blog post about declartive matrix:
An equivalent pipeline created without matrix would easily be several
times larger, and much harder to understand and maintain.
We use Jenkins 2.176 to manage our CI. In our Jenkinsfile, we've defined a trigger to start the pipeline M-F at 4:30AM, and we want it to skip testing in an ephemeral environment and deploying.
pipeline {
triggers { cron('30 4 * * 1-5') }
stages {
stage('Build') {
...
}
stage('Tests') {
...
}
stage('Test in ephemeral environment') {
when { triggeredBy 'SCMTrigger' }
steps {
...
}
}
stage('Deploy') {
when { allOf { branch 'master'; triggeredBy 'SCMTrigger' } }
steps {
...
}
}
}
}
The problem is: the "Test in ephemeral environment" does not trigger when the branch is pushed via a git hook. The "Build" and "Tests" stages execute, but not the "Test in ephemeral environment". Once merged to master, I suspect I'll have a similar problem with the "Deploy" step but haven't made it that far.
What am I missing to make this work? It seems so straightforward 🤔
My solution was to simply exclude TimerTrigger explicitly from steps I didn't want to execute. From my example, I did this:
pipeline {
triggers { cron('30 4 * * 1-5') }
stages {
stage('Build') {
...
}
stage('Tests') {
...
}
stage('Test in ephemeral environment') {
when { not { triggeredBy 'TimerTrigger' } }
steps {
...
}
}
stage('Deploy') {
when { allOf { branch 'master'; not { triggeredBy 'TimerTrigger' } } }
steps {
...
}
}
}
}
In a declarative Jenkinsfile how can you determine if a job exists?
I want to conditionally run a stage if another job exists, like so:
pipeline {
agent { label 'mylabel' }
// Run the the stages:
stages {
stage('Pre-Build') {
steps {
timestamps { ansiColor('xterm') { sh 'build/jenkins_prebuild.sh' } }
}
}
stage('Pre-Build') {
steps {
timestamps { ansiColor('xterm') { sh 'build/jenkins_build.sh' } }
}
}
stage('Trigger Remote If Exists'){
when { JOB_EXISTS }
steps {
timestamps {
ansiColor('xterm') {
sh 'build/pre-trigger.sh'
build job: "../myjob/foo", wait: false, parameters: [booleanParam(name: 'FOO', value: true)]
}
}
}
}
}
}
Basically, what should I do for JOB_EXISTS?
if (jenkins.model.Jenkins.instance.getItem("YOUR_JOB_NAME") != null) {
}
You may not be able to use the above snippet in your declarative pipeline. But you should be able to use this in a global shared lib.
UPDATE:
An administrator needs to approve this snippet in "Manage Jenkins -> In-process Script Approval" section.
There is also this option: https://stackoverflow.com/a/52076776/3384609
try {
println("Preparing to build the ${jobName}...")
build job:"${jobName}", propagate:false, wait:false
} catch (hudson.AbortException e) {
println("Not building the job ${jobName} as it doesn't exist")
}```