Как / когда выполнение оболочки помечает сборку как сбой в Jenkins?


ужасные истории, которые я нашел во время поиска ответа на этот вопрос...

хорошо, у меня есть скрипт .sh, который в значительной степени делает все, что должен делать Дженкинс:

  • проверяет источники из SVN
  • построить проект
  • развертывает проект
  • убирает за собой

поэтому в Jenkins мне нужно только "построить" проект, запустив скрипт в команде Execute Shell. Скрипт запущен (the источники загружаются, проект строится/развертывается), но затем он помечает сборку как сбой: Шаг сборки "выполнить оболочку" помечен как ошибка сборки Даже если скрипт был успешно запущен! Я попытался закрыть скрипт:

  • выход 0 (по-прежнему помечает его как сбой)
  • выход 1 (помечает его как сбой, как и ожидалось)
  • нет команды выхода вообще (отмечает это как сбой)

когда, как и почему выполнение оболочки помечает мою сборку как A провал?

6 98

6 ответов:

во-первых, наведите курсор мыши на серую область ниже. Не часть ответа, но абсолютно необходимо сказать:

если у вас есть сценарий оболочки, который делает "checkout, build, deploy" сам по себе, то почему вы используете Jenkins? Вы пренебрегаете всеми чертами Дженкинса, которые делают его тем, что он есть. у вас также может быть cron или SVN post-commit hook, вызывающий скрипт напрямую. Дженкинс, выполняющий саму проверку SVN, имеет решающее значение. Оно позволяет запускать сборки только при наличии изменений (или по таймеру, или вручную, если вы предпочитаете). Он отслеживает изменения между сборками. Он показывает эти изменения, поэтому вы можете увидеть, какая сборка была для какого набора изменений. Он отправляет сообщения коммиттерам, когда их изменения вызвали успешную или неудачную сборку (опять же, как вы предпочитаете). Он будет отправлять по электронной почте коммиттеры, когда их исправления исправили неудачную сборку. И все больше и больше. Архивирование артефактов Дженкинсом также делает их доступными для каждой сборки, прямо с Дженкинса. Хотя это не так важно, как проверка SVN, это еще раз неотъемлемая часть того, что делает его Дженкинсом. То же самое с развертыванием. Если у вас нет одной среды, развертывание обычно происходит в нескольких средах. Дженкинс может отслеживать, в какой среде развернута конкретная сборка (с определенным набором изменений SVN), с помощью рекламных акций. Вы отказываетесь от всего этого. Похоже, вам говорят: "Вы должны использовать Дженкинса", но вы действительно не хотите, и вы делаете это только для того, чтобы ваши боссы отстали от вас, просто поставить галочку "да, я использовал Дженкинса"

короткий ответ: код завершения последние команда Дженкина Выполнить Консоли шаг сборки-это то, что определяет успех / неудачу Этап Построения. 0 успехов, anything else - провал. Обратите внимание, что это определяет успех / неудачу этап построения не все работа беги. На успех / неудачу всего выполнения задания могут дополнительно влиять несколько шагов сборки, а также действия и плагины после сборки.

Вы упомянули Build step 'Execute shell' marked build as failure, поэтому мы сосредоточимся только на одном шаге сборки. Если ваш выполнить консоли шаг сборки имеет только одну строку, которая вызывает ваш сценарий оболочки, а затем код выхода вашего сценария оболочки будет определять успех / неудачу шага сборки. Если у вас больше строк после ваш скрипт выполнение, а затем тщательно рассмотреть их, так как они являются те, которые могут быть причиной сбоя.

наконец, есть читать здесь сценарий сборки Дженкинса выходит после выполнения теста Google. Это не имеет прямого отношения к вашему вопросу, но обратите внимание, что часть о Дженкинсе запускает Выполнить Консоли шаг сборки, как сценарий оболочки с /bin/sh -xe

The -e означает, что скрипт будет выход с отказом, даже если только 1 команда не выполняется, даже если вы выполняете проверку ошибок для этой команды (потому что скрипт завершает работу до того, как он доберется до вашей проверки ошибок). Это противоречит нормальному выполнению сценариев оболочки, которые обычно печатают сообщение об ошибке для неудачной команды (или перенаправляют его на null и обрабатывают его другими средствами) и продолжают.

чтобы обойти это, добавьте set +e в верхней части вашего скрипта.

поскольку вы говорите, что ваш скрипт делает все это предполагается сделать, скорее всего, неудачная команда находится где-то в конце сценария. Может быть, последнее Эхо? Или копия артефактов где-то? Не видя полного вывода консоли, мы просто предполагаем.

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

простой и короткий ответ на ваш вопрос

пожалуйста, добавьте следующую строку в свой шаг сборки "Execute shell".

#!/bin/sh

теперь позвольте мне объяснить вам причину, по которой нам требуется эта строка для задания сборки "Execute Shell".

по умолчанию Дженкинс взять /bin/sh -xe а это значит -x будет печатать каждую команду.И другой вариант -e, что заставляет shell немедленно прекратить выполнение сценария, когда любая команда завершает работу с ненулевым (когда любой команда не выполняется) код выхода.

добавить в #!/bin/sh позволит вам выполнить не вариант.

легко и просто:

Если Дженкинс видит, что шаг сборки (который также является скриптом) завершается с ненулевым кодом, сборка помечается красным шаром (=failed).

Почему именно это происходит, зависит от вашего сценария сборки.

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

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

если у вас есть строка в вашем скрипте, где ожидается сбой, например grep или найти, а затем просто добавить || true до конца этой линии. Это гарантирует, что линия всегда будет возвращать успех.

Если вам нужно использовать этот код выхода, вы можете либо поднять команду в свой оператор if:

grep foo bar; if [ $? == 0 ]; then ...    -->   if grep foo bar; then ...

или вы можете захватить код возврата в свой || статья:

grep foo bar || ret=$?

добавить в #!/bin/sh позволит вам выполнить не вариант.

Это также помогло мне в устранении проблемы, когда я выполнял сценарий bash от Jenkins master на моем Linux slave. Просто добавив #!/bin/bash над моим фактическим скриптом в блоке "Execute Shell" он исправил мою проблему, так как в противном случае он выполнял windows git, предоставленную версию оболочки bash, которая давала ошибку.

In Jenkins ver. 1.635, невозможно показать собственную переменную среды следующим образом:

$BUILD_NUMBER или ${BUILD_NUMBER}

в этом случае, вы должны установить его в другой переменной.

set BUILDNO = $BUILD_NUMBER $BUILDNO