Как получить ошибки для распространения в бегуне TeamCity PowerShell
У меня есть TeamCity 7 Build Configuration, которая в значительной степени является только вызовом .ps1
script с использованием различных параметров TeamCity.
Я надеялся, что это может быть простой вопрос:
-
Script
Файл
-
Script Файл
% system.teamcity.build.workingDir%/ Script.ps1
-
Script режим выполнения
Выполнить .ps1 script с аргументом "-File"
-
Script аргументы
% system.teamcity.build.workingDir% -OptionB% BuildConfigArgument%% BuildConfigArg2%
И тогда я бы ожидал:
- Если я испортил свои аргументы, а script не запустится, сборка завершится неудачно.
- если мой Script.ps1 script выдает, сбой сборки
- Если script
exit
с уровнем ошибки не 0
Я хочу, чтобы сборка не сработала (может быть, это не идиоматическое управление ошибками PS - должен ли .ps1 только сообщать об успехе из-за отсутствия исключений?)
Вопрос: Он просто не работает. Как это должно работать? Есть ли что-то, что я делаю крайне неправильно, что могу исправить, выбрав разные варианты?
Ответы
Ответ 1
Как написано в дружественном руководстве TeamCity:
Установка вывода ошибок в Error
и добавление условия сбоя сборки
Если присутствуют синтаксические ошибки и исключения, PowerShell записывает их в stderr. Чтобы TeamCity не удалось выполнить сборку, установите для параметра "Вывод ошибки" значение "Ошибка" и добавьте условие сбоя сборки, которое приведет к сбою сборки при любом выводе ошибки.
Ключом к созданию этой работы является изменение двух значений по умолчанию:
- На верхнем уровне в Условиях сбоя сборки включите сообщение об ошибке, которое регистрирует сборщик сборок:
- На шаге сборки [PowerShell] отобразите дополнительные параметры и установите вывод ошибок: Ошибка
В 9.1 работает следующее (я не удивлюсь, если это будет работать и для более ранних версий):
- создать шаг сборки PowerShell с параметрами по умолчанию
- измените раскрывающийся список на Script: Source code
- Добавьте
trap { Write-Error "Exception $_"; exit 98 }
trap { Write-Error "Exception $_"; exit 98 }
вверху скрипта -
(Необязательный, но более правильный IMO для сценариев, подходящих для сценариев сборки TeamCity)
Показать дополнительные параметры и включить параметры: Добавить аргумент -NoProfile
-
(Необязательно, но для меня это должно быть по умолчанию, так как оно отображается более четко, как предложено @Jamal Mavadat)
Показать дополнительные параметры и включить вывод ошибок: Ошибка
(ASIDE @JetBrains: если бы метка была "Форматировать вывод stderr как", это было бы менее обманчиво)
Это охватывает следующие случаи:
- Разбор ошибок [всплывают как исключения и немедленно прекращают выполнение]
- Исключения [
throw
n прямо или косвенно в вашем шоу кода PS и вызовите код выхода для TC, чтобы остановить сборку] - Явный
exit n
в сценарии распространяется на сборку (и завершается неудачей, если не равен нулю)
Ответ 2
В TeamCity существует известная ошибка, которая вызывает поведение, которое заметил оригинальный плакат.
Легко работать, однако.
В конце PowerShell script добавьте вывод, указывающий, что достигнут конец script:
Echo "Packaging complete (end of script reached)"
Затем настройте новое условие сбоя сборки на вашей сборке, чтобы выполнить сбой, если текст, который вы эхом, НЕ присутствует в выводе.
Ответ 3
Ты слишком задумываешься. Попробуйте следующее:
-
Script
File
-
Script Файл
Script.ps1
Вам не нужно указывать этот путь - по умолчанию, это относительно каталога выписки.
-
Script режим выполнения
Put script into PowerShell stdin with "-Command -" arguments
Это именно то, что я использую для запуска кучи скриптов powershell в Teamcity.
Update
Я пропустил бит в исходном сообщении о сбоях в powershell script сбой сборки. Извиняюсь!
Я решил эту часть головоломки двумя разными способами.
Для обычных скриптов powershell
Обмотайте основной блок кода в try...catch
; если возникает исключение, верните ненулевое целое значение. Для успешного выполнения верните 0.
Это соглашение о возврате нуля для успеха датируется очень долгим в истории - оно используется системами Unix/Linux, DOS, CP/M и т.д.
Для PSake сценариев сборки
Используйте оболочку powershell для оболочки script для вызова psake и напрямую установите результат сборки teamcity с помощью записи ответного сообщения в стандартный вывод.
В начале script определите сообщение о состоянии, которое представляет ошибку:
$global:buildResult = "#teamcity[buildStatus status='FAILURE' text='It died.']
Внутри psake script обновите $global:buildResult
, чтобы указать успех в отдельной задаче, которая выполняется в последнюю очередь.
$global:buildResult = "#teamcity[buildStatus status='SUCCESS' text='It lives.']
В конце оболочки script введите сообщение о состоянии
write-host $global:buildResult
Если что-либо в сборке script не выполняется, эта последняя задача не будет запущена, и будет выведено сообщение по умолчанию (с указанием отказа).
В любом случае Teamcity заберет сообщение и правильно установит статус сборки.
Ответ 4
Если новые версии TeamCity находятся в пределах вашей досягаемости, стоит проверить некоторые улучшения PowerShell.
В частности, может вас заинтересовать изменение Error Output
по умолчанию от warning
до error
.
Ответ 5
Просто похвалите закон, который вам не нужно работать с Дженкинсом. Невозможно использовать шаг PowerShell для подобных проблем. Вместо этого нам нужно использовать шаг "cmd", который вызывает следующую магическую оболочку, которая приведет к отказу от кода исключения и выхода:
%SystemRoot%\sysnative\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -Command "& { $ErrorActionPreference = 'Stop'; & 'path\to\script.ps1 -arg1 -arg2; EXIT $LASTEXITCODE }"
Ответ 6
Альтернатива принятому ответу, который работает для меня. На TeamCity 9 (мне не нравится изменять параметр "Сбой сборки", поскольку он влияет на все шаги сборки): -
Я хотел, чтобы ошибки PowerShell вышли из строя, но с хорошим сообщением.
Поэтому я хотел выпустить сообщение об ошибке И вернуть код ошибки.... try/catch/finally на помощь.
Моя демонстрация script:
Try {
Write-Host "Demoing the finally bit"
# Make sure if anything goes wrong in the script we get an exception
$ErrorActionPreference = "Stop"
# This will fail and throw an exception (unless you add the file)
Get-Content IDontExist.txt
}
Catch
{
# Throwing like this gives a pretty error message in the build log
throw $_
# These give less pretty/helpful error messages
# Write-Host $_
# Write-Host $_.Exception.Message
}
Finally
{
# 69 because it more funny than 1
exit(69)
}
Ответ 7
Это было заменено опциями, предоставленными в 9.x, но я оставлю его здесь, поскольку в то время он определенно был пуленепробиваемым, и я не мог найти любое другое решение, которое мне понравилось лучше.
Вы могли бы просто сделать что-то, что сработает. Следующее было протестировано с помощью
- ошибки в script бит
- отсутствующие файлы
- script выход с не
0
ERRORLEVEL
В параметрах Runerhell для командной строки TeamCity установите его следующим образом:
-
script Файл
Исходный код
-
script источник
$ErrorActionPreference='Stop'
powershell -NoProfile "Invoke-Command -ScriptBlock { `$errorActionPreference='Stop'; %system.teamcity.build.workingDir%/Script.ps1 %system.teamcity.build.workingDir% --OptionB %BuildConfigArgument% %BuildConfigArg2%; exit `$LastExitCode }"
(развернутая версия: powershell -NoProfile "Invoke-Command -ScriptBlock { $errorActionPreference='Stop'; %system.teamcity.build.workingDir%/Script.ps1 %system.teamcity.build.workingDir% --OptionB %BuildConfigArgument% %BuildConfigArg2%; exit
$LastExitCode} "
-
script режим выполнения
Поместите script в stdin PowerShell с аргументами "-Command -"
-
Дополнительные параметры командной строки
-NoProfile
Я надеюсь, что это не лучший ответ!
Ответ 8
Пожалуйста, делайте следующее после каждой команды, которую вы выполняете. Это проверяет последний код ошибки и завершает работу, если не равно 0.
If ($LASTEXITCODE -ne 0) {
Write-Host "The result was of the previous script was " $LASTEXITCODE
Exit $LASTEXITCODE
}
Ответ 9
У Powershell v2 atleast возникла проблема с параметром -File, который испортил код ошибки. Есть некоторые подробности о том, как это беспорядок и прочее.
Ответ либо переключается на параметр -Command, либо/или переносит его с помощью файла bat, который проверяет LastErrorCode и возвращает 1+, если он должен сбой.
http://zduck.com/2012/powershell-batch-files-exit-codes/
Ответ 10
Используйте что-то вроде этого:
echo "##teamcity[buildStatus status='FAILURE' text='Something went wrong while executing the script...']";
Для справки, посмотрите Отчет о статусе сборки от Teamcity