Как отметить нестабильную сборку в 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.