terraform fmt fails within a Jenkins pipeline - jenkins

I am running
sh "terraform fmt -list=true -write=false -diff=true -check=true"
within a Jenkins pipeline, and got the following weird error message:
ERROR: Terraform Lint failed due to: hudson.AbortException: script returned exit code 3
Finished: FAILURE
If I just run the terraform fmt ... without the pipeline, then it is ok. Any suggestion on how I can fix this weird error?

As mentioned in the Release Notes for Terraform 0.10.5 (but not in the documentation), the -check parameter
makes it return a non-zero exit status if any formatting changes are required
When you run it locally, it will not output any error, but if you would afterwards check the exit code echo $?, it would be again 3.
In Jenkins, however, any sh step returning non-zero status is treated as failure. So you either remove the -check option, or you deal with it correctly, i.e.,
def fmtStatus = sh "terraform fmt -list=true -write=false -diff=true -check=true"
if (fmtStatus == 0) {
echo "All correct"
} else {
echo "Changes necessary"
}

Related

Jenkins: How to fail stage when test fails?

I have a stage in my pipeline that is running some UI tests currently this is the behaviour I get:
If the tests pass the stage goes green the next stage runs, and at
the end the build goes green.
If a test fails the stage goes green, the next stage runs, and at the
end the build is yellow (unstable)
How can I make it so that instead of moving on to the next stage if a test fails the pipeline is failed?
This is the stage of my pipeline, I've tried adding a post section but even when a test fails it reports success.
stage('UITests') {
steps {
withCredentials([file(credentialsId: 'env_file', variable: 'envFile')]) {
sh '''
cat $envFile > .env.dev
make run_tests
'''
}
}
// Fail build if test fail
post{
success {
echo "UI Tests passed moving to Build stage"
}
failure {
error "UI Tests Failed, stopping the build"
}}
}
In the Jenkins log for the stage I can see when a test fails I get
error Command failed with exit code 1.
This doesn't happen when a test passes so is there a reason the post block is always going to success?
The sh step returns the same status code that your actual sh command: https://www.jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
You can get this status code, assign its value to a variable and then fail with a custom message:
def statusCode = sh script:"cat $envFile > .env.dev && make run_tests", returnStatus:true
if (statusCode != 0) {
error 'UI Tests Failed, stopping the build'
}

Jenkins scripted pipeline - sh return nonzero exit code but stage SUCCEEDS

In my Jenkins scripted pipeline, I have a build stage that has the following sh command:
def buildcmd = "./scriptname.sh"+ <paramters>
def status = sh returnStatus: true, script:"""cd /to/some/dir
eval ${buildcmd}
"""
if(status != 0)
{
error("Failure")
}
After execution, scriptname exits with status 2 and status variable also contains 2 and the job fails. But however the stage result is shown as SUCCESS. I expected both the stage result and build result to be FAILURE.
Can anybody please clarify this.
returnStatus (optional)
Normally, a script which exits with a nonzero
status code will cause the step to fail with an exception. If this
option is checked, the return value of the step will instead be the
status code. You may then compare it to zero, for example.
Source
If your goal is to simply let the stage fail use returnStatus: false. Unfortunately I can't tell you the difference between a status code and exit code (like mentioned above). The documentation only tells that if you set returnStatus: true the pipeline won't fail on an exit code unequal 0.
You can set the result of the pipeline by yourself (Source):
if(status != 0)
{
currentBuild.result = 'FAILURE'
}

setting status of a build in jenkins

I have a jenkins job.
It is pretty simple: pull from git, and run the build.
The build is just one step:
Execute window command batch
In my use case, I will need to run some python scripts.
Some will fail, some others will not.
python a.py
python b.py
What does determine the final status of the build?
It seems I can edit that by:
echo #STABLE > build.proprieties
but how are the STABLE/UNSTABLE status assigned if not specified by the user?
What happens if b.py raise an error and fails?
Jenkins interprets a pipeline as failed if a command returns an exit code unequal zero.
Internally the build status is set with currentBuild.currentResult which can have three values: SUCCESS, UNSTABLE, or FAILURE.
If you want to control the failure / success of your pipeline yourself you can catch exceptions / exit codes and manually set the value for currentBuild.currentResult. Plugins also use this attribute to change the result of the pipeline.
For example:
stage {
steps {
script {
try {
sh "exit 1" // will fail the pipeline
sh "exit 0" // would be marked as passed
currentBuild.currentResult = 'SUCCESS'
} catch (Exception e) {
currentBuild.currentResult = 'FAILURE'
// or currentBuild.currentResult = 'UNSTABLE'
}
}
}}

How to not mark Jenkins job as FAILURE when pytest tests fail

I have a Jenkins setup with a pipeline that uses pytest to run some test suites. Sometimes a test fails and sometimes the test environment crashes (random HTTP timeout, external lib error, etc.). The job parses the XML test result but the build is marked as FAILURE as long as pytest returns non-zero.
I want Jenkins to get exit code zero from pytest even if there are failed tests but I also want other errors to be marked as failures. Are there any pytest options that can fix this? I found pytest-custom_exit_code but it can only suppress the empty test suite error. Maybe some Jenkins option or bash snippet?
A simplified version of my groovy pipeline:
pipeline {
stages {
stage ('Building application') {
steps {
sh "./build.sh"
}
}
stage ('Testing application') {
steps {
print('Running pytest')
sh "cd tests && python -m pytest"
}
post {
always {
archiveArtifacts artifacts: 'tests/output/'
junit 'tests/output/report.xml'
}
}
}
}
}
I have tried to catch exit code 1 (meaning some tests failed) but Jenkins still received exit code 1 and marks the build as FAILURE:
sh "cd tests && (python -m pytest; rc=\$?; if [ \$rc -eq 1 ]; then exit 0; else exit \$rc; fi)"
Your attempt does not work because Jenkins runs the shell with the errexit (-e) option enabled and that causes the shell to exit right after the pytest command before it reaches your if statement. There is a one-liner however that will work because it is executed as one statement: https://stackoverflow.com/a/31114992/1070890
So your build step would look like this:
sh 'cd tests && python -m pytest || [[ $? -eq 1 ]]'
My solution was to implement the support myself in pytest-custom-exit-code and create a pull request.
From version 0.3.0 of the plugin I can use pytest --suppress-tests-failed-exit-code to get the desired behavior.

Jenkins build gets failed, when unit test cases are failed

Jenkins build gets failed, when unit test cases are failed,
Here am using pipeline script in jenkins, Need to generate HTML report using mocha-awesome, I can get the HTML report only when all test cases are passed, Build fails if any functions failed in my testcases.Here you can see the screenshot
The call to the unit test run returns with exit status 1.
What you can do is use the returnStatus option for the sh or bat step which will then not fail the build itself but leaves that up to you:
def exitStatus = sh returnStatus: true, script: 'unittests'
or:
def exitStatus = bat returnStatus: true, script: 'unittests.exe'
Having this you can selectively fail the build, i.e. if exitStatus == 1 then ignore as it signals a test fail, if it is anything but 0 or 1 then fail the build using the error step.

Resources