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


93

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

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

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

В терминологии Jenkins нестабильная сборка определяется как:

Сборка считается нестабильной, если она была успешно построена и один или несколько издателей сообщают о ее нестабильности. Например, если издатель JUnit настроен и тест не проходит, сборка будет помечена как нестабильная.

Как я могу заставить Дженкинса отмечать сборку как нестабильную, а не только успешную / неудачную при запуске сценариев оболочки?


Я добился этого, выполнив разные этапы задания и используя плагины jenkins stackoverflow.com/questions/25442343/…
— fantastory

Ответы:


58

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

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

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

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


2
См. Ответ ниже, где описан вариант без установки плагина, поскольку версия jenkins 2.26: stackoverflow.com/a/49676269/1347649
— JSoet

63

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

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

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


Мне нравится этот вариант, так как он не требует установки каких-либо дополнительных плагинов
— mattherman

2
Поскольку это реализовано в последней
— версии

3
«Современные версии Jenkins» означает Jenkins 2.26 или новее. См. Issues.jenkins-ci.org/browse/JENKINS-23786 .
— Blue

5
Можно ли указать это с помощью кода при использовании команды shstep в a Jenkinsfile? Где находится настройка в графическом интерфейсе? Я не могу найти это.
— bluenote10

1
Мне пришлось нажать кнопку «Дополнительно ...» под этапом сборки, чтобы раскрыть это. Не очень полезно скрывать одну (и не особо продвинутую) опцию за коллапсером «щелкните здесь, чтобы сделать что-нибудь», но так оно и есть.
— Tripleee 01

57

Это можно сделать без печати волшебных строк и с помощью 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

2
Мне очень нравится это решение, я реализовал для этого класс ruby, чтобы его можно было повторно использовать в моих rakefiles. :)
— Shire

3
+1 - это лучшее решение, чем принятый ответ, потому что Text Finder может искать только одну строку для каждого задания, поэтому вы можете установить статус сборки только на одно из двух значений.
— gareth_bowles

4
Интересное решение. Но если ваш Jenkins требует аутентификации, вам нужно будет настроить аутентификацию с открытым ключом в его конфигурации, иначе любая команда jenkins-cli завершится с ошибкой AccessDeniedException.
— Том Де Леу

2
Это не сработает, если вы используете ведомое устройство, у которого нет веб-доступа к мастеру. Например, если ведомое устройство Jenkins не может создать соединение HTTP или HTTPS обратно с сервером.
— Steve HHH

3
Я хотел использовать это решение, но set-build-resultоно устарело в jenkins-cli.
— DrLime2k10

28

Вы должны использовать Jenkinsfile, чтобы обернуть ваш сценарий сборки и просто пометить текущую сборку как НЕСТАБИЛЬНУЮ с помощью currentBuild.result = "UNSTABLE".

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

3
Почему этот ответ не набрал больше голосов? Что-то не так (кроме использования "волшебной" строки UNSTABLE)? Это кажется более простым, чем другие ответы.
— Кевин

2
Вопрос касался работы в стиле фристайл, а этот ответ - о работе на конвейере. Ответ «
— Марк Уэйт

Как это вообще работает? Я получаю сообщение об ошибке: Expected one of "steps", "stages", or "parallel" for stageкогда пытаюсь установить currentBuild.result прямо внутри сцены.
— dokaspar

11

вы также должны уметь использовать Groovy и делать то, что делал textfinder

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

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


6

В моем сценарии задания у меня есть следующие инструкции (это задание выполняется только на мастере 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


4
  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:
    

3

Я считаю, что наиболее гибкий способ сделать это - прочитать файл в плагине 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()
}

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


Я предполагаю, что это действительно говорит о том, что «если в рабочей области есть файл с именем build.properties», пометьте его как нестабильный. это правильно? Я новичок в Groovy. Не могли бы вы подробнее рассказать об этом объяснении?
— uchuugaka

@uchuugaka да, если есть файл и его содержимое. Имя файла и его содержимое произвольно. Используйте то, что подходит вам.
— jeremyjjbrown

Благодарность! очень полезно. Groovy Postbuild довольно косвенный, а Groovy втягивает такое огромное количество вещей из Java и добавляет еще ... это новый прием для меня.
— uchuugaka 01

@uchuugaka Я не думаю, что это проблема с Groovy :)
— jeremyjjbrown 01

Без проблем. Просто вызов!
— uchuugaka 01

2

TextFinder работает только в том случае, если статус задания не был изменен с УСПЕШНО на ОТКАЗ или ПРЕРЫВАН. В таких случаях используйте отличный скрипт на этапе 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/


2

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

Теперь это возможно в новых версиях 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}")
    }
  }
}

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

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


2

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

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

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

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

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

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

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


1

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

    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.

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

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

0

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


-3

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

function safemake {
  make "$@"
  if [ "$?" -ne 0 ]; then
    echo "ERROR: BUILD FAILED"
    exit 1
  else
    echo "BUILD SUCCEEDED"
  fi
}

11
exit 1, насколько я знаю, приведет только к сбою сборки. Я не хочу, чтобы сборка давала сбой, я хочу, чтобы она была помечена как нестабильная.
— HNygard 08

1
См. Также stackoverflow.com/questions/36313216/… - простое решение простоif make "$@"; then echo "BUILD SUCCEEDED"; else rc=$?; echo "BUILD FAILED"; exit $rc; fi
— tripleee
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.