Как пометить нестабильную сборку в Jenkins при запуске сценариев оболочки

В проекте, над которым я работаю, мы используем сценарии оболочки для выполнения различных задач. Некоторые сценарии - это SH/Bash, который запускает Rsync, а некоторые - сценарии PHP. Один из сценариев PHP запускает несколько интеграционных тестов, которые выводят в JUnit XML, отчеты о покрытии кода и тому подобное.

Дженкинс может помечать задания как успешные / неудачные в зависимости от состояния выхода. В PHP скрипт завершается с 1, если он обнаружил, что во время выполнения не удалось выполнить тесты. The other shell scripts runs commands and uses the exit codes from those to mark a build as failed.

// :: End of PHP script:
// If any tests have failed, fail the build
if ($build_error) exit(1);

In the Jenkins Terminology a unstable build is defined as

A build is unstable if it was built successfully and one or more publishers report it unstable. For example if the JUnit publisher is configured and a test fails then the build will be marked unstable.

How can I get Jenkins to mark a build as unstable instead of only success / failed when running shell scripts?

17 ответов

Решение

Используйте плагин Text-finder.

Вместо выхода со статусом 1 (что приведет к сбою сборки), выполните:

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

После того, как в действиях после сборки включите Text Finder, установите регулярное выражение в соответствии с напечатанным сообщением (TESTS FAILED!) и установите флажок "Нестабильный, если найден" под этой записью.

Современные версии Jenkins (начиная с 2.26, октябрь 2016 г.) решили эту проблему: это просто расширенный вариант для шага сборки оболочки Execute!

код выхода для сборки

Вы можете просто выбрать и установить произвольное значение выхода; если он совпадает, сборка будет нестабильной. Просто выберите значение, которое вряд ли будет запущено реальным процессом в вашей сборке.

Это можно сделать, не печатая волшебные строки и не используя TextFinder. Вот немного информации об этом.

В основном вам нужен файл.jar с http: // yourserver.com / cli, доступный в сценариях оболочки, затем вы можете использовать следующую команду, чтобы отметить нестабильную сборку:

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

Чтобы пометить сборку как нестабильную при ошибке, вы можете использовать:

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

Проблема в том, что jenkins-cli.jar должен быть доступен из сценария оболочки. Вы можете указать его в виде легкодоступного пути или загрузить через скрипт оболочки задания:

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

Вы должны использовать Jenkinsfile, чтобы обернуть ваш скрипт сборки и просто пометить текущую сборку как UNSTABLE, используя currentBuild.result = "UNSTABLE",

   этап {
      status = /* ваша команда сборки идет сюда */
      if (status === "MARK-AS-UNSTABLE") {
        currentBuild.result = "НЕСТАБИЛЬНО"
      }
   }

Вы также должны быть в состоянии использовать groovy и делать то, что сделал textfinder

пометка сборки как нестабильной с помощью отличного плагина пост-сборки

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()
}

Также см. Groovy Postbuild Plugin

В моем сценарии работы у меня есть следующие операторы (эта работа выполняется только на мастере Jenkins):

# 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

Вы можете увидеть это и многое другое о настройке статусов сборки на вики Jenkins: https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+CLI

  1. Сконфигурируйте сборку PHP для создания отчета xml junit

    <phpunit bootstrap="tests/bootstrap.php" colors="true" >
       <logging>
           <log type="junit" target="build/junit.xml" 
               logIncompleteSkipped="false" title="Test Results"/>
       </logging>
    
       ....
    
     </phpunit>
    
  2. Завершить сборку скрипта со статусом 0

    ...
    exit 0;
    
  3. Добавить действие после сборки. Опубликовать отчет с результатами теста JUnit для XML отчета о тестировании. Этот плагин изменит стабильную сборку на нестабильную, если тест не пройден.

    **/build/junit.xml
    
  4. Добавлен плагин Jenkins Text Finder с возможностью сканирования вывода на консоль и непроверенными параметрами. Этот плагин потерпел неудачу во всей сборке по фатальной ошибке.

    PHP Fatal error:
    

Дублирую мой ответ отсюда, потому что я потратил некоторое время на поиск этого:

Теперь это возможно в новых версиях Jenkins, вы можете сделать что-то вроде этого:

#!/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}")
    }
  }
}

Генератор синтаксиса конвейера показывает это на вкладке "Дополнительно":

Пример синтаксиса конвейера

Я думал, что выложу другой ответ для людей, которые могут искать что-то подобное.

В нашей работе по сборке есть случаи, когда мы хотели бы, чтобы сборка продолжалась, но была помечена как нестабильная. Для наших это касается номеров версий.

Итак, я хотел установить условие для сборки и установить нестабильную сборку, если это условие выполнено.

Я использовал параметр Условный шаг (одиночный) в качестве шага сборки.

Затем я использовал сценарий "Выполнить системный Groovy" в качестве шага сборки, который будет выполняться при выполнении этого условия.

Я использовал Groovy Command и установил следующий скрипт

import hudson.model.*

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

return

Это, кажется, работает довольно хорошо.

Я наткнулся на решение здесь

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

Я считаю, что наиболее гибкий способ сделать это - прочитать файл в плагине groovy post build. введите описание изображения здесь

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()
}

Если содержимое файла 'true', сборка будет установлена ​​в нестабильное состояние. Это будет работать на локальном ведущем устройстве и на всех ведомых устройствах, на которых вы выполняете задание, и на любых сценариях, которые могут записывать на диск.

В дополнение ко всем остальным ответам, Дженкинс также позволяет использовать метод (который, на мой взгляд, более понятен). Этот метод можно использовать с параметром сообщения, описывающим, почему сборка нестабильна.

Помимо этого, вы можете использовать returnStatusвашего сценария оболочки (bat или sh), чтобы включить это.

Например:

      def status = bat(script: "<your command here>", returnStatus: true)
if (status != 0) {
    unstable("unstable build because script failed")
}

Конечно, вы можете сделать что-то с большей детализацией в зависимости от ваших потребностей и статуса возврата.


Кроме того, для повышения ошибки вы также можете использовать warnError()на месте unstable(). Это укажет, что ваша сборка не удалась, а не нестабильна, но синтаксис тот же.

TextFinder хорош только в том случае, если статус задания не был изменен с УСПЕХА на СБОЙ или ОТМЕНЕН. Для таких случаев используйте groovy скрипт на шаге PostBuild:

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
    }
 }

Подробности смотрите в посте, который я написал об этом: http://www.tikalk.com/devops/JenkinsJobStatusChange/

Если вы хотите использовать декларативный подход, я предлагаю вам использовать такой код.

      pipeline {
    stages {
        // create separate stage only for problematic command
        stage("build") {
            steps {
                sh "command"
            }
            post {
                failure {
                    // set status
                    unstable 'rsync was unsuccessful'
                }
                always {
                    echo "Do something at the end of stage"
                }
            }
        }
    }

    post {
        always {
            echo "Do something at the end of pipeline"
        }
    }
}

Если вы хотите сохранить все в одном этапе, используйтеcatchError

      pipeline {
    stages {
        // create separate stage only for problematic command
        stage("build") {
            steps {
                catchError(stageResult: 'UNSTABLE') {
                    sh "command"
                }
                sh "other command"
            }
        }
    }
}

В качестве более легкой альтернативы существующим ответам вы можете установить результат сборки с помощью простого HTTP POST для доступа к REST API консоли скриптов Groovy:

    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

Преимущества:

  • не нужно скачивать и запускать огромный jar-файл
  • нет ключей для установки и чтения какого-либо глобального состояния (текст консоли, файлы в рабочей области)
  • плагины не требуются (кроме Groovy)
  • нет необходимости настраивать дополнительный шаг сборки, который является излишним в случаях PASSED или FAILURE.

Для этого решения ваша среда должна соответствовать следующим условиям:

  • Доступ к API Jenkins REST возможен из подчиненного
  • У ведомого должен быть доступ к учетным данным, позволяющим получить доступ к API REST скрипта Jenkins Groovy.

Если оболочка завершилась неудачной командой, все в порядке (сборка завершилась неудачно:). В случае неудачной команды внутри сценария оболочки выполните команду проверки после:

 if [ "$?" -ne 0 ]; then
    exit 1
 fi 

Исправление от @zrajm: это можно упростить до

... || exit 1

Один простой способ сделать сборку нестабильной - это запустить в блоке "execute shell" exit 13

Вы можете просто вызвать "выход 1", и сборка завершится неудачей и не будет продолжена. Я закончил делать сквозную функцию make, чтобы обработать ее для меня, и вызвал safemake вместо make для build:

function safemake {
  make "$@"
  if [ "$?" -ne 0 ]; then
    echo "ERROR: BUILD FAILED"
    exit 1
  else
    echo "BUILD SUCCEEDED"
  fi
}
Другие вопросы по тегам