I'm beginner to Jenkins. I have code pipeline structure like this
Repo1 -> Repo2 -> Repo3 -> Deploy
I already created such hierarchy via GUI but I want to create it via pipeline as code.I want to create chain of pipelines where I clone different repos and perform tests on it and then continue to another repo based on current pipeline post result.
This is my jenkinsfile - (psuedo code like as it gives me error to build)
pipeline {
agent any
stages {
stage('Build Repo1') {
steps {
sh 'echo "repo1 build!"'
}
}
stage('Test Repo1') {
steps {
sh 'echo "repo success!"'
}
}
}
post {
success {
pipeline {
agent any
stages {
stage('Build Repo2') {
steps {
sh 'echo "build repo2!"'
}
}
stage('Test Repo2') {
steps {
sh 'echo "test repo2!"'
}
}
}
post {
success {
# continue to generate pipeline for repo3
echo 'This will always run'
}
failure {
echo 'This will run only if failed'
}
}
}
}
failure {
echo 'This will run only if failed'
}
unstable {
echo 'This will run only if the run was marked as unstable'
}
changed {
echo 'This will run only if the state of the Pipeline has changed'
echo 'For example, if the Pipeline was previously failing but is now successful'
}
}
}
Please help!
Related
I have a series of steps in a stage that I want to run even if the first one fails. I want the stage result to fail and the build to get aborted, but only after all steps have run. For example,
pipeline {
agent any
stages {
stage('Run Test') {
steps {
sh "echo running unit-tests"
sh "echo running linting && false" // failure
sh "echo generating report" // This should still run (It currently doesn't)
publishCoverage adapters: [coberturaAdapter("coverage.xml")] // This should still run (It currently doesn't)
junit 'unit-test.xml' // This should still run (It currently doesn't)
}
}
stage('Deploy') {
steps {
echo "deploying" // This should NOT run
}
}
}
}
The result should be a failed build where the "Run Test" stage failed and the "Deploy" stage did not run. Is this possible?
P.S.
I am NOT asking for the same behavior as in Continue Jenkins pipeline past failed stage. I want to run the steps following the failure, but not any of the stages afterwards. I tried to enclose each of the test steps with catchError (buildResult: 'FAILURE', stageResult: 'FAILURE'), but the "Deploy" stage still runs.
EDIT:
I cannot combine all the steps into one big sh step and capture its return code because some of the steps are not shell commands, but instead jenkins steps like junit and publishCoverage.
A script witha non-zero exit code will always cause a jenkins step to fail. You can use returnStatus as true so that jenkins does not fails the step.
Additionally considering your use case, you could use a post always execution, so that the steps are always carried out.
Please see below reference example:
stage('Run Test') {
steps {
def unit_test_result= sh returnStatus: true, script: 'echo "running unit-tests"'
def lint_result= sh returnStatus: true, script: 'echo "running linting"'
if (unit_test_result!=0 || lint_result!=0 ) {
// If the unit_test_result or lint_result status is not 0 then mark this stage as unstable to continue ahead
// and all later stages will be executed
unstable ('Testing failed')
// You can also mark as failed as below and it will not conintue other stages:
// error ('Testing failed')
}
}
post {
always {
// This block would always be executed inspite of failure
sh "echo generating report"
publishCoverage adapters: [coberturaAdapter("coverage.xml")]
junit 'unit-test.xml'
}
}
}
I found a slightly hacky way to get the behavior I want. The other answers didn't work for me, either because they need all the steps to be sh steps, or they don't stop the deploy stage from running. I used catchError to set the build and stage result. But to prevent the next stage from running, I needed to an explicit call to error if the stage failed.
pipeline {
agent any
stages {
stage('Run Test') {
steps {
script {
// catchError sets the stageResult to FAILED, but does not stop next stages from running
catchError (buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo running unit-tests"
}
catchError (buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo running linting && false" // failure
}
catchError (buildResult: 'FAILURE', stageResult: 'FAILURE') {
sh "echo generating report" // This still runs
}
publishCoverage adapters: [coberturaAdapter("coverage.xml")] // This still runs
junit 'unit-test.xml' // This still runs
if (currentBuild.result == "FAILURE") { // This is needed to stop the next stage from running
error("Stage Failed")
}
}
}
}
stage('Deploy') {
steps {
echo "deploying" // This should NOT run
}
}
}
}
Theoretically you should be able to use sh "<command>||true" It would ignore the error on command and continue. However, Jenkins will not fail as it would ignore the error.
If you don't want Jenkins to ignore the error and want it to stop at the end of the stage, you can do something like: sh "<command>||$error=true" then fail the build based on the $error variable. (sh "$error" might be enough but I am not sure, may require an if statement at the end.) It will be only set to true iff command fails.
Another option is to wrap your build steps in a try-catch block! if there's an exception, i.e. return code of build is not 0 you can catch it, mark the build as unstable and then the rest of the pipeline continues on.
here's an example `
pipeline {
agent {
node {
label 'linux'
}
}
options {
timestamps()
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '3'))
}
tools {
maven 'Maven 3.6.3'
jdk 'jdk11'
}
stages {
stage('CleanWS') {
steps {
cleanWs()
}
}
stage('Build') {
steps {
withMaven(options: [artifactsPublisher(disabled: true)]) {
sh "export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -f pom.xml clean install -DskipTests -Pregression-test -Dmaven.javadoc.skip=true"
}
}
}
stage('Test') {
steps {
script {
try {
withMaven(options: [artifactsPublisher(disabled: true)]) {
sh "export MAVEN_OPTS=\"-Xmx2048m\" && export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -B verify -Dmaven.source.skip=true -Dmaven.javadoc.skip=true"
}
} catch (exc) {
currentBuild.result = 'UNSTABLE'
}
}
}
post {
always {
script {
junit "**/surefire-reports/*.xml"
}
}
}
}
stage('Sonar Analyse') {
steps {
script {
withMaven(options: [artifactsPublisher(disabled: true)]) {
withSonarQubeEnv("SonarQube") {
sh "export MAVEN_OPTS=\"-Xmx2048m\" && export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn sonar:sonar"
}
}
}
}
}
stage('Deploy to Nexus') {
steps {
sh "export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -f pom.xml -B clean deploy -DdeployAtEnd=true -DskipTests"
}
}
}
post {
failure {
script {
emailext(
body: "Please go to ${env.BUILD_URL}/console for more details.",
to: emailextrecipients([developers(), requestor()]),
subject: "Nightly-Build-Pipeline Status is ${currentBuild.result}. ${env.BUILD_URL}"
)
}
}
unstable {
script {
emailext(
body: "Please go to ${env.BUILD_URL}/console for more details.",
to: emailextrecipients([developers(), requestor()]),
subject: "Nightly-Build-Pipeline Build Status is ${currentBuild.result}. ${env.BUILD_URL}"
)
}
}
}
}`
Is there any way to re-run only single job in parallel job config in Jenkins?
for example: in given picture there is a Testing stage and in testing stage there is 3 parallel jobs 1,2 and 3. if job 1 will get failed , can we re-run only job 1 again , instead of executing Testing stage again? image
Jenkinsfile:
pipeline {
agent {
label "agent1"
}
stages {
stage('Test') {
parallel {
stage('Test1') {
steps { sh 'echo Test 1 passed' }
}
stage('Test2') {
steps {
sh 'echo Test2 is passed'
}
} stage('Test3') {
steps {
sh 'echo Test 3 passed'
}
}
}
}
}
I am trying to create a pipeline where there are multiple triggers for it - cron, pull request opened and manual. Hence, I wanted to visualize it accordingly.
This is my code with no triggers applied.
pipeline {
agent any
environment {
CI = 'true'
TRIGGER = 'PULL_REQUEST'
}
stages {
stage('Trigger')
{
parallel{
stage('Daily') {
when {
environment name: 'TRIGGER', value: 'DAILY'
}
steps {
sh 'echo "daily build"'
}
}
stage('Pull Request') {
when {
environment name: 'TRIGGER', value: 'PULL_REQUEST'
}
steps {
sh 'echo "pull request trigger"'
}
}
stage('Manual') {
when {
environment name: 'TRIGGER', value: 'MANUAL'
}
steps {
sh 'echo "Manual"'
}
}
}
}
stage('Build') {
steps {
sh 'echo "build step"'
}
}
stage('Test') {
steps {
sh 'echo "test step"'
}
}
stage('Deliver for development') {
when {
environment name: 'CI', value: 'true'
}
steps {
sh 'echo "delivery for development"'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'echo proceeded'
}
}
stage('Deploy for production') {
when {
environment name: 'CI', value: 'false'
}
steps {
sh 'echo "deploy for production"'
input message: 'Finished using the web site? (Click "Proceed" to continue)'
sh 'echo proceeded'
}
}
}
}
I am able to achieve this with the above code :
Now, my objective is to put the triggers in those parallel stages - Daily, Pull Request and Manual. However, I am not able to do so, as trigger is for the complete pipeline and perhaps expected to appear only once in the pipeline. How can I achieve this effect?
These 3 parallel triggers will set some environment variables which will be used in further stages to modify the pipeline flow accordingly, depending on the type of trigger.
I am creating a sample jenkins pipeline, here is the code.
pipeline {
agent any
stages {
stage('test') {
steps {
sh 'echo hello'
}
}
stage('test1') {
steps {
sh 'echo $TEST'
}
}
stage('test3') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
}
this pipeline fails with following error logs
Started by user admin
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 15: Not a valid stage section definition: "if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}". Some extra configuration is required. # line 15, column 9.
stage('test3') {
^
WorkflowScript: 15: Nothing to execute within stage "test3" # line 15, column 9.
stage('test3') {
^
But when i execute the following example from this url, it executes successfully and print the else part.
node {
stage('Example') {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
The only difference i can see is that in the working example there is no stages but in my case it has.
What is wrong here, can anyone please suggest?
your first try is using declarative pipelines, and the second working one is using scripted pipelines. you need to enclose steps in a steps declaration, and you can't use if as a top-level step in declarative, so you need to wrap it in a script step. here's a working declarative version:
pipeline {
agent any
stages {
stage('test') {
steps {
sh 'echo hello'
}
}
stage('test1') {
steps {
sh 'echo $TEST'
}
}
stage('test3') {
steps {
script {
if (env.BRANCH_NAME == 'master') {
echo 'I only execute on the master branch'
} else {
echo 'I execute elsewhere'
}
}
}
}
}
}
you can simplify this and potentially avoid the if statement (as long as you don't need the else) by using "when". See "when directive" at https://jenkins.io/doc/book/pipeline/syntax/. you can also validate jenkinsfiles using the jenkins rest api. it's super sweet. have fun with declarative pipelines in jenkins!
It requires a bit of rearranging, but when does a good job to replace conditionals above. Here's the example from above written using the declarative syntax. Note that test3 stage is now two different stages. One that runs on the master branch and one that runs on anything else.
stage ('Test 3: Master') {
when { branch 'master' }
steps {
echo 'I only execute on the master branch.'
}
}
stage ('Test 3: Dev') {
when { not { branch 'master' } }
steps {
echo 'I execute on non-master branches.'
}
}
If you wanted to create a condition to execute only a stage based on expression you can use keyword when
stage ('test3'){
when { expression { return env.BRANCH_NAME == 'master'} }
steps {
echo 'I only execute on the master branch.'
}
}
}
With the expression key word you can add any condition.
e.g. if stage is dependent on generated file in workspace.
stage ('File Dependent stage'){
when { expression { return fileExists ('myfile') } }
steps {
echo "file exists"
}
}
}
if ( params.build_deploy == '1' ) {
println "build_deploy 是 ${params.build_deploy}"
jobB = build job: 'k8s-core-user_deploy', propagate: false, wait: true, parameters: [
string(name:'environment', value: "${params.environment}"),
string(name:'branch_name', value: "${params.branch_name}"),
string(name:'service_name', value: "${params.service_name}"),
]
println jobB.getResult()
}
How can the Jenkins Continuous Integration Game plugin (ci-game) be used in a Jenkins pipeline as code (Jenkinsfile) job?
Unfortunately, the ci-game plugin does not (yet) support pipelines.
The plugin does not appear in the Plugin Compatibility with Pipeline list.
There's already an open ticket on this issue (JENKINS-42683).
It seems that the latest update 1.26 includes the DSL for ci-game (see https://github.com/jenkinsci/ci-game-plugin/pull/19/commits/89e6c3e6ff11294418c2e741ebade5cfaa53ba1d
)
I tested it out and it seems to work when you put ciGame() :
post {
always {
ciGame()
}
}
However, this writer complained that it doesn't work:
https://github.com/jenkinsci/ci-game-plugin/commit/89e6c3e6ff11294418c2e741ebade5cfaa53ba1d
Simple Jenkins declarative pipeline with single Stage
pipeline {
agent any
stages {
stage('Stage 1') {
steps {
echo 'Hello world!'
}
}
}
}
Simple Jenkins declarative pipeline with multiple Stage
pipeline {
agent any
stages {
stage('Stage 1') {
steps {
echo 'Inside Stage 1'
}
}
stage('Stage 2') {
steps {
echo 'Inside Stage 2'
}
}
}
}
Simple Jenkins declarative pipeline with Post Actions
pipeline {
agent any
stages {
stage('Stage 1') {
steps {
echo 'Inside Stage 1'
}
post {
failure {
script { echo 'failure Inside Stage 1' }
}
success {
script { echo 'failure Inside Stage 1' }
}
}
}
stage('Stage 2') {
steps {
echo 'Inside Stage 2'
}
post {
failure {
script { echo 'failure Inside Stage 2' }
}
success {
script { echo 'failure Inside Stage 1' }
}
}
}
}
https://devopsdiagnosis.wixsite.com/tech/forum/jenkins/jenkins-pipeline