Как получить ошибки для распространения в бегуне 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 не удалось выполнить сборку, установите для параметра "Вывод ошибки" значение "Ошибка" и добавьте условие сбоя сборки, которое приведет к сбою сборки при любом выводе ошибки.

Ключом к созданию этой работы является изменение двух значений по умолчанию:

  1. На верхнем уровне в Условиях сбоя сборки включите сообщение об ошибке, которое регистрирует сборщик сборок:
  2. На шаге сборки [PowerShell] отобразите дополнительные параметры и установите вывод ошибок: Ошибка

В 9.1 работает следующее (я не удивлюсь, если это будет работать и для более ранних версий):

  1. создать шаг сборки PowerShell с параметрами по умолчанию
  2. измените раскрывающийся список на Script: Source code
  3. Добавьте trap { Write-Error "Exception $_"; exit 98 } trap { Write-Error "Exception $_"; exit 98 } вверху скрипта
  4. (Необязательный, но более правильный IMO для сценариев, подходящих для сценариев сборки TeamCity)

    Показать дополнительные параметры и включить параметры: Добавить аргумент -NoProfile

  5. (Необязательно, но для меня это должно быть по умолчанию, так как оно отображается более четко, как предложено @Jamal Mavadat)

    Показать дополнительные параметры и включить вывод ошибок: Ошибка

    (ASIDE @JetBrains: если бы метка была "Форматировать вывод stderr как", это было бы менее обманчиво)

Это охватывает следующие случаи:

  1. Разбор ошибок [всплывают как исключения и немедленно прекращают выполнение]
  2. Исключения [ throw n прямо или косвенно в вашем шоу кода PS и вызовите код выхода для TC, чтобы остановить сборку]
  3. Явный 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