How to mark a build unstable in Jenkins when running shell scripts

╄→гoц情女王★ 提交于 2019-11-26 19:36:38

Use the Text-finder plugin.

Instead of exiting with status 1 (which would fail the build), do:

if ($build_error) print("TESTS FAILED!");

Than in the post-build actions enable the Text Finder, set the regular expression to match the message you printed (TESTS FAILED!) and check the "Unstable if found" checkbox under that entry.

It can be done without printing magic strings and using TextFinder. Here's some info on it.

Basically you need a .jar file from http://yourserver.com/cli available in shell scripts, then you can use the following command to mark a build unstable:

java -jar jenkins-cli.jar set-build-result unstable

To mark build unstable on error, you can use:

failing_cmd cmd_args || java -jar jenkins-cli.jar set-build-result unstable

The problem is that jenkins-cli.jar has to be available from shell script. You can either put it in easy-to-access path, or download in via job's shell script:

wget ${JENKINS_URL}jnlpJars/jenkins-cli.jar

Modern Jenkins versions (since 2.26, October 2016) solved this: it's just an advanced option for the Execute shell build step!

You can just choose and set an arbitrary exit value; if it matches, the build will be unstable. Just pick a value which is unlikely to be launched by a real process in your build.

You should use Jenkinsfile to wrap your build script and simply mark the current build as UNSTABLE by using currentBuild.result = "UNSTABLE".

   stage {
      status = /* your build command goes here */
      if (status === "MARK-AS-UNSTABLE") {
        currentBuild.result = "UNSTABLE"
      }
   }

you should also be able to use groovy and do what textfinder did

marking a build as un-stable with groovy post-build plugin

if(manager.logContains("Could not login to FTP server")) {
    manager.addWarningBadge("FTP Login Failure")
    manager.createSummary("warning.gif").appendText("<h1>Failed to login to remote FTP Server!</h1>", false, false, false, "red")
    manager.buildUnstable()
}

Also see Groovy Postbuild Plugin

Steve HHH

In my job script, I have the following statements (this job only runs on the Jenkins master):

# This is the condition test I use to set the build status as UNSTABLE
if [ ${PERCENTAGE} -gt 80 -a ${PERCENTAGE} -lt 90 ]; then
  echo WARNING: disc usage percentage above 80%

  # Download the Jenkins CLI JAR:
  curl -o jenkins-cli.jar ${JENKINS_URL}/jnlpJars/jenkins-cli.jar

  # Set build status to unstable
  java -jar jenkins-cli.jar -s ${JENKINS_URL}/ set-build-result unstable

fi

You can see this and a lot more information about setting build statuses on the Jenkins wiki: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI

  1. Configure PHP build to produce xml junit report

    <phpunit bootstrap="tests/bootstrap.php" colors="true" >
       <logging>
           <log type="junit" target="build/junit.xml" 
               logIncompleteSkipped="false" title="Test Results"/>
       </logging>
    
       ....
    
     </phpunit>
    
  2. Finish build script with status 0

    ...
    exit 0;
    
  3. Add post-build action Publish JUnit test result report for Test report XMLs. This plugin will change Stable build to Unstable when test are failing.

    **/build/junit.xml
    
  4. Add Jenkins Text Finder plugin with console output scanning and unchecked options. This plugin fail whole build on fatal error.

    PHP Fatal error:
    

I find the most flexible way to do this is by reading a file in the groovy post build plugin.

import hudson.FilePath
import java.io.InputStream

def build = Thread.currentThread().executable

String unstable = null
if(build.workspace.isRemote()) {
    channel = build.workspace.channel;
    fp = new FilePath(channel, build.workspace.toString() + "/build.properties")
    InputStream is = fp.read()
    unstable = is.text.trim()
} else {
    fp = new FilePath(new File(build.workspace.toString() + "/build.properties"))
    InputStream is = fp.read()
    unstable = is.text.trim()
}

manager.listener.logger.println("Build status file: " + unstable)
if (unstable.equalsIgnoreCase('true')) {
    manager.listener.logger.println('setting build to unstable')
    manager.buildUnstable()
}

If the file contents are 'true' the build will be set to unstable. This will work on the local master and on any slaves you run the job on, and for any kind of scripts that can write to disk.

The TextFinder is good only if the job status hasn't been changed from SUCCESS to FAILED or ABORTED. For such cases, use a groovy script in the PostBuild step:

errpattern = ~/TEXT-TO-LOOK-FOR-IN-JENKINS-BUILD-OUTPUT.*/;
manager.build.logFile.eachLine{ line ->
    errmatcher=errpattern.matcher(line)
    if (errmatcher.find()) {
        manager.build.@result = hudson.model.Result.NEW-STATUS-TO-SET
    }
 }

See more details in a post I've wrote about it: http://www.tikalk.com/devops/JenkinsJobStatusChange/

I thought I would post another answer for people that might be looking for something similar.

In our build job we have cases where we would want the build to continue, but be marked as unstable. For ours it's relating to version numbers.

So, I wanted to set a condition on the build and set the build to unstable if that condition is met.

I used the Conditional step (single) option as a build step.

Then I used Execute system Groovy script as the build step that would run when that condition is met.

I used Groovy Command and set the script the following

import hudson.model.*

def build = Thread.currentThread().executable
build.@result = hudson.model.Result.UNSTABLE

return

That seems to work quite well.

I stumbled upon the solution here

http://tech.akom.net/archives/112-Marking-Jenkins-build-UNSTABLE-from-environment-inject-groovy-script.html

Duplicating my answer from here because I spent some time looking for this:

This is now possible in newer versions of Jenkins, you can do something like this:

#!/usr/bin/env groovy

properties([
  parameters([string(name: 'foo', defaultValue: 'bar', description: 'Fails job if not bar (unstable if bar)')]),
])


stage('Stage 1') {
  node('parent'){
    def ret = sh(
      returnStatus: true, // This is the key bit!
      script: '''if [ "$foo" = bar ]; then exit 2; else exit 1; fi'''
    )
    // ret can be any number/range, does not have to be 2.
    if (ret == 2) {
      currentBuild.result = 'UNSTABLE'
    } else if (ret != 0) {
      currentBuild.result = 'FAILURE'
      // If you do not manually error the status will be set to "failed", but the
      // pipeline will still run the next stage.
      error("Stage 1 failed with exit code ${ret}")
    }
  }
}

The Pipeline Syntax generator shows you this in the advanced tab:

As a lighter alternative to the existing answers, you can set the build result with a simple HTTP POST to access the Groovy script console REST API:

    curl -X POST \
     --silent \
     --user "$YOUR_CREDENTIALS" \
     --data-urlencode "script=Jenkins.instance.getItemByFullName( '$JOB_NAME' ).getBuildByNumber( $BUILD_NUMBER ).setResult( hudson.model.Result.UNSTABLE )" $JENKINS_URL/scriptText

Advantages:

  • no need to download and run a huge jar file
  • no kludges for setting and reading some global state (console text, files in workspace)
  • no plugins required (besides Groovy)
  • no need to configure an extra build step that is superfluous in the PASSED or FAILURE cases.

For this solution, your environment must meet these conditions:

  • Jenkins REST API can be accessed from slave
  • Slave must have access to credentials that allows to access the Jenkins Groovy script REST API.

You can just call "exit 1", and the build will fail at that point and not continue. I wound up making a passthrough make function to handle it for me, and call safemake instead of make for building:

function safemake {
  make "$@"
  if [ "$?" -ne 0 ]; then
    echo "ERROR: BUILD FAILED"
    exit 1
  else
    echo "BUILD SUCCEEDED"
  fi
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!