Jenkins Pipeline - How to fix syntax error in matrix section? - jenkins

I've been trying to configure a matrix section in a declarative pipeline, but it keeps failing.
In the official documentation, it states:
Stages in Declarative Pipeline may have a matrix section defining a multi-dimensional matrix of name-value combinations to be run in parallel.
This is my (simplified) pipeline:
pipeline {
agent { label 'production-linux' } // Set where this project can run
stages {
stage("do something") {
matrix {
axes {
axis {
name 'foo'
values 'bar1', 'bar2', 'bar3'
}
}
stages{
stage("using $foo"){
steps{
step {
echo "using variable: $foo"
}
}
}
}
}
}
}
}
But when I run it, I get the following:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 14: Unknown stage section "matrix". Starting with version 0.5, steps in a stage must be in a ‘steps’ block. # line 14, column 9.
stage("do something") {
^
WorkflowScript: 14: Expected one of "steps", "stages", or "parallel" for stage "do something" # line 14, column 9.
stage("do something") {
^
Has the Matrix section been deprecated?

Has the Matrix section been deprecated?
No it has not. The exception tells that it found a syntax error.
Your syntax error appears here:
steps{
step {
echo "using variable: $foo"
}
}
Quoting the official documentation:
The steps section defines a series of one or more steps to be executed
in a given stage directive.
Unfortunately there is no step-keyword directly, every command you execute in the steps is basically a step. To fix your syntax error try the following:
steps{
echo "using variable: $foo"
}

Related

Want to move the entire post steps in Jenkins Global Shared library

I am new to Jenkins and I want to use Jenkins shared library for my post build steps so that I don't have to write them again and again but the problem is when I call my groovy method in the post section of the pipeline it gives the following error.
WorkflowScript: 12: The ‘post’ section can only contain build condition names with code blocks. Valid condition names are [always, changed, fixed, regression, aborted, success, unsuccessful, unstable, failure, notBuilt, cleanup] # line 12, column 9.
build()
^
WorkflowScript: 11: post can not be empty # line 11, column 5.
post {
^
2 errors
My pipeline syntax:
#Library("new-library") _
pipeline {
agent any
stages {
stage('Hello') {
steps {
echo 'Hello world!'
}
}
}
post {
build()
}
}
build is the name of the groovy file.
My groovy file which is on GitHub
def call() {
always {
echo 'This will always run'
}
success {
echo 'This will run only if successful'
}
unstable {
echo 'This will run only if run was marked as unstable'
}
changed {
echo 'This will run only if the state of the pipeline is changed'
echo 'FOR EXAMPLE, if the pipeline was previously failed but not it is successful'
}
}
Simply I want my post steps to be trigger from the Global Shared Library. If there is some other method do let me know as well.
Thank you in advance.

Jenkins post actions on stage level are influenced by buildResult

In my jenkins pipeline i have several post-success actions in different stages that define environment variables depending on the stage results (in success case). I am also using parallel and sequential stages, but i do not believe this is affecting the result. Below is a trimmed excerpt:
stage('stage1') {
agent {
label 'agent1'
}
when {
expression {
return Jenkins.instance.getItem("${'job1'}").isBuildable()
}
environment name: 'job0', value: 'success'
}
steps {
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
build job: 'job1'
}
}
post {
success {
script {
env.job1 = "success"
echo "job1: ${env.job1} !"
}
}
}
}
Now whenever the build result is set to FAILURE within a stage by catchError, all post actions in other stages do not evaluate the related stage result, but the build result instead, which i do not want (and believe they should not do), referring to https://www.jenkins.io/doc/book/pipeline/syntax/#post :
The post section defines one or more additional steps that are run upon the completion of a Pipeline’s or stage’s run (depending on the location of the post section within the Pipeline)
But in my case, after the first error no more stage level post-success actions are executed..
My workaround so far is to modify catcherror, add a post-failure action that sets another variable which is evaluated in the very last stage to set the build result:
stage('stage1') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
build job: 'job1'
}
}
post {
success { .. }
failure {
script {
env.testFail = "true"
echo "testFail: ${testFail} !"
}
}
}
}
..
stage('set buildResult') {
when {
environment name: 'testFail', value: 'true'
}
steps {
script {
bat '''
echo "testFail variable found. Changing buildresult to FAILURE."
exit 1
'''
}
}
}
Is there anything I missed in the docs, or can anybody confirm this behavior? I would appreciate to remove my workaround and let the catchError do all the work for me.
I have already searched through official docs and mailing list, including jenkins issues, but have not found information about this issue anywhere.
This is my first time contributing to stackoverflow, so please forgive me if I made mistakes or did not express myself clearly (leaving reader-only mode).
Jenkins - v2.204.2
Pipeline - v2.6
Pipeline Declarative - v1.8.4

Mark a stage in Jenkins Pipeline as eg "UNSTABLE" but proceed with future stages?

I'm going to use Jenkins pipeline plugin to test several binaries A B C on several nodes 1 2 3.
In the end of my test I would like to have every single result of all possible combinations. So my Pipe may not abort when a single stage fails. It should proceed.
eg: A1 green, A2 green, A3 red, B1 green, B2 red, ..., C3 green
But when the first binary returns with an value unequal zero ("Binary not working on the system") it's stage is marked as FAILURE and any other stages are skipped.
Is there a possibility in Jenkins Pipeline to mark a stage as "UNSTABLE" but proceed with running the other tests?
According to Continue Jenkins job after failed stage while marking stage as failed can't mark this step as failed. The solution of this in running tasks in parallel is not working for my setup. So is it possible to safely mark it as something else? Is it possible to manipulate the result of a stage?
This question How to continue past a failing stage in Jenkins declarative pipeline syntax intents to use a scripted pipeline. I would like to avoid that if it is possible to do it in an other way.
pipeline {
agent {label 'master'}
stages {
stage('A1') {
agent {label 'Node1'}
steps {
sh 'binA'
}
}
stage('A2') {
agent {label 'Node1'}
steps {
sh 'binB' // If this bin fails, all following stages are skipped
}
}
// ...
stage('C3'){
agent {label 'Node3'}
steps {
sh 'binC'
}
}
}
}
Declarative Pipeline: Though using currentBuild.result = 'UNSTABLE' works in declarative pipelines too, Blue Ocean displays all stages as unstable irrespective of which stage fails.
To mark only specific stages as unstable, use the step unstable(message: String) as described here within your stage and install/update the following plugins:
Pipeline: Basic Steps to 2.16 or newer
Pipeline: API Plugin to 2.34 or newer
Pipeline: Groovy to 2.70 or newer
Pipeline Graph Analysis to 1.10 or newer
Sample pipeline stage:
stage('Sign Code') {
steps {
script {
try {
pwd()
sh "<YOUR SCRIPT HERE>"
}
catch (err) {
unstable(message: "${STAGE_NAME} is unstable")
}
}
}
}
Note: This also marks the overall build status as unstable.
There is now a more elegant solution, that not only allows you to set a stage and the job result to unstable. Using catchError, you can set any combination of stage and build result:
pipeline {
agent any
stages {
stage('1') {
steps {
sh 'exit 0'
}
}
stage('2') {
steps {
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
sh "exit 1"
}
}
}
stage('3') {
steps {
sh 'exit 0'
}
}
}
}
In the example above, all stages will execute, the pipeline will be successful, but stage 2 will show as failed:
As mentioned above, you can freely choose the buildResult and stageResult. You can even fail the build and continue the execution of the pipeline.
Just make sure your Jenkins is up to date, since this is a fairly new feature. (Pipeline: Basic Steps needs to be 2.18 or newer)
For scripted pipeline, you can use try .. catch blocks inside the stages and then set currentBuild.result = 'UNSTABLE'
in the exception handler.

which plugin or pre-installation are need to dockerize build on jenkins?

which plugin or pre-installation are need to dockerize build on jenkins?
I keep having this stupid stack !
WorkflowScript: 74: Expected a symbol # line 74, column 15.
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
^
WorkflowScript: 74: "error" should have 1 arguments but has 2 arguments instead. # line 74, column 15.
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
Edit : I have the docker pipeline plugin installed
the full jenkinsfile
stage('docker') {
steps {
checkout scm
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
writeFile file: 'settings.xml', text: "<settings><localRepository>${pwd()}/.m2repo</localRepository></settings>"
sh 'mvn clean install'
}
}
Mostly scripted/declarative pipeline are mixed.
docker.image is scripted pipeline, see https://jenkins.io/doc/book/pipeline/docker/, therefore it needs to be wrapped with script {} inside declarative pipeline.
Here are two working sample, with jenkins slave dockerserver
Scripted pipeline
node("dockerserver") {
stage('docker') {
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
writeFile file: 'settings.xml', text: "${pwd()}/.m2repo"
sh 'ls'
}
}
}
Declarative pipeline:
pipeline {
agent { label "dockerserver" }
stages {
stage('docker') {
steps {
script {
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
writeFile file: 'settings.xml', text: "${pwd()}/.m2repo"
sh 'ls'
}
}
}
}
}
}
You can see a similar error in issue JENKINS-44749
It seems the problem is deeper than I though since the Docker Pipeline Plugin also fails but with the following message:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
WorkflowScript: 46: Expected a symbol # line 46, column 25.
docker.image(‘node:7-alpine’).inside {
After reinstalling all plugins and updating Jenkins to 2.64 the original error is gone but I still get the error from the above comment.
Wrapping docker.image in a script block makes it work, but it wasn't needed before.
steps {
script {
docker.image('maven:3.3.3-jdk-8').inside("-v $PWD:/data") {
writeFile file: 'settings.xml', text: "<settings><localRepository>${pwd()}/.m2repo</localRepository></settings>"
sh 'mvn clean install'
}
}
}

Jenkins pipeline - try catch for particular stage and subsequent conditional step

I'm trying to replicate the equivalent of a conditional stage in Jenkins pipeline using a try / catch around a preceding stage, which then sets a success variable, which is used to trigger the conditional stage.
It appears that a try catch block is the way to go, setting a success var to SUCCESS or FAILED, which is used as part of a when statement later (as part of the conditional stage).
The code I am using is as follows:
pipeline {
agent any
stages {
try{
stage("Run unit tests"){
steps{
sh '''
# Run unit tests without capturing stdout or logs, generates cobetura reports
cd ./python
nosetests3 --with-xcoverage --nocapture --with-xunit --nologcapture --cover-package=application
cd ..
'''
currentBuild.result = 'SUCCESS'
}
}
} catch(Exception e) {
// Do something with the exception
currentBuild.result = 'SUCCESS'
}
stage ('Speak') {
when {
expression { currentBuild.result == 'SUCCESS' }
}
steps{
echo "Hello, CONDITIONAL"
}
}
}
}
The latest syntax error I am receiving is as follows:
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed:
WorkflowScript: 4: Expected a stage # line 4, column 9.
try{
I've also tried lots of variations.
Am I taking the wrong approach here? This seems like a fairly common requirement.
Thanks.
This might solve your problem depending on what you are going for. Stages are only run when the preceding stages succeed, so if you actually have two stages like in your example, and if you want the second to only run when the first succeeds, you want to ensure that the first stage fails appropriately when tests fail. Catching will prevent the (desirable) failure. Finally will preserve the failure, and can also still be used to grab your test results.
So here, the second stage will only run when the tests pass, and the test results will be recorded regardless:
pipeline {
agent any
stages {
stage("Run unit tests"){
steps {
script {
try {
sh '''
# Run unit tests without capturing stdout or logs, generates cobetura reports
cd ./python
nosetests3 --with-xcoverage --nocapture --with-xunit --nologcapture --cover-package=application
cd ..
'''
} finally {
junit 'nosetests.xml'
}
}
}
}
stage ('Speak') {
steps{
echo "Hello, CONDITIONAL"
}
}
}
}
Note that I'm actually using try in a declarative pipeline, but like StephenKing says, you can't just use try directly (you have to wrap arbitrary groovy code in the script step).

Resources