Как пометить нестабильную сборку в 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
Сконфигурируйте сборку 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>
Завершить сборку скрипта со статусом 0
... exit 0;
Добавить действие после сборки. Опубликовать отчет с результатами теста JUnit для XML отчета о тестировании. Этот плагин изменит стабильную сборку на нестабильную, если тест не пройден.
**/build/junit.xml
Добавлен плагин 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
Это, кажется, работает довольно хорошо.
Я наткнулся на решение здесь
Я считаю, что наиболее гибкий способ сделать это - прочитать файл в плагине 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
}