How/When Execute Shell отмечают сборку как неудачу в Jenkins? - программирование
Подтвердить что ты не робот

How/When Execute Shell отмечают сборку как неудачу в Jenkins?

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

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

  • проверяет источники из SVN
  • создать проект
  • развертывает проект
  • очищает после себя

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

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

Когда, как и почему Execute Shell помечает мою сборку как сбой?

4b9b3361

Ответ 1

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

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

Короткий ответ: код завершения команды last команды сборки Jenkin Execute Shell - это то, что определяет успех/сбой Build Step. 0 - успех, anything else - сбой. Обратите внимание, что это определение успеха/неудачи этапа сборки, а не всей работы. Успех/сбой всего запуска работы могут быть затронуты несколькими шагами сборки, а также действиями и плагинами после сборки.

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

Наконец, прочитайте здесь Jenkins Build script завершает выполнение Google Test. Это не связано напрямую с вашим вопросом, но обратите внимание, что часть о том, как Jenkins запускает шаг сборки Выполнять Shell, в качестве оболочки script с /bin/sh -xe

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

Чтобы обойти это, добавьте set +e в начало вашей оболочки script.

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

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

Ответ 2

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

Пожалуйста, добавьте следующую строку в шаге "Выполнение оболочки".

#!/bin/sh

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

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

Итак, добавив #!/bin/sh, вы можете выполнить без опции.

Ответ 3

Обычный и простой:

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

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

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

Ответ 4

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

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

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

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

Или вы можете записать код возврата в предложение ||:

grep foo bar || ret=$?

Ответ 5

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

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