I've got a PowerShell script as follows
##teamcity[progressMessage 'Beginning build'] # If the build computer is not running the appropriate version of .NET, then the build will not run. Throw an error immediately. if( (ls "$env:windir\Microsoft.NET\Framework\v4.0*") -eq $null ) { throw "This project requires .NET 4.0 to compile. Unfortunately .NET 4.0 doesn't appear to be installed on this machine." ##teamcity[buildStatus status='FAILURE' ] } ##teamcity[progressMessage 'Setting up variables'] # Set up variables for the build script $invocation = (Get-Variable MyInvocation).Value $directorypath = Split-Path $invocation.MyCommand.Path $v4_net_version = (ls "$env:windir\Microsoft.NET\Framework\v4.0*").Name $nl = [Environment]::NewLine Copy-Item -LiteralPath "$directorypath\packages\NUnit.2.6.2\lib\nunit.framework.dll" "$directorypath\Pandell.Tests\bin\debug" -Force ##teamcity[progressMessage 'Using msbuild.exe to build the project'] # Build the project using msbuild.exe. # Note we've already determined that .NET is already installed on this computer. cmd /c C:\Windows\Microsoft.NET\Framework\$v4_net_version\msbuild.exe "$directorypath\Pandell.sln" /p:Configuration=Release cmd /c C:\Windows\Microsoft.NET\Framework\$v4_net_version\msbuild.exe "$directorypath\Pandell.sln" /p:Configuration=Debug # Break if the build throws an error. if(! $?) { throw "Fatal error, project build failed" ##teamcity[buildStatus status='FAILURE' ] } ##teamcity[progressMessage 'Build Passed'] # Good, the build passed Write-Host "$nl project build passed." -ForegroundColor Green ##teamcity[progressMessage 'running tests'] # Run the tests. cmd /c $directorypath\build_tools\nunit\nunit-console.exe $directorypath\Pandell.Tests\bin\debug\Pandell.Tests.dll # Break if the tests throw an error. if(! $?) { throw "Test run failed." ##teamcity[buildStatus status='FAILURE' ] } ##teamcity[progressMessage 'Tests passed']
From what I'm lead to believe, an uncaught Throw
will result in an exit code of 1
, but unfortunately TeamCity is saying otherwise.
[19:32:20]Test run failed. [19:32:20]At C:\BuildAgent\work\e903de7564e599c8\build.ps1:44 char:2 [19:32:20]+ throw "Test run failed." [19:32:20]+ ~~~~~~~~~~~~~~~~~~~~~~~~ [19:32:20] + CategoryInfo : OperationStopped: (Test run failed.:String) [], [19:32:20] RuntimeException [19:32:20] + FullyQualifiedErrorId : Test run failed. [19:32:20] [19:32:20]Process exited with code 0 [19:32:20]Publishing internal artifacts [19:32:20][Publishing internal artifacts] Sending build.finish.properties.gz file [19:32:20]Build finished
It might also be important to note that my Execution Mode
is set to Execute .ps1 script with "-File" argument
.
I tried changing it to Put script into PowerShell stdin with "-Command -" arguments
, but then it failed with an exit code of 1
even with passing tests. I'm sure that running it as -File
is going to be the right way.
If I open up the script located at C:\BuildAgent\work\e903de7564e599c8\build.ps1
and run it manually in CMD, it does the same thing... I.e., the failing tests fail, and the %errorlevel%
is still 0
.
Yet, if I run it in PowerShell and call $LASTEXITCODE
, it returns the right code every time.
Note that the index always begins with a number starting from 0 and it corresponds to the items in the list of objects. Therefore, an item using parameter specifier 0 corresponds to the first object in the list of objects. In examples 1 and 2, the object list is simply the variable $name.
PowerShell NoExit switch prevents the PowerShell console window from closing after running the script. When you double click on the PowerShell script file, or run with the PowerShell option, the script will execute quickly and then disappear.
Exit Keyword If the Exit keyword is used in the functions and the main script, it closes everything and you may not get a chance to see the output in the console if not stored before the Exit Keyword is used.
This is a known issue with PowerShell. Executing a script with -file
returns an exit code of 0 when it shouldn't.
(Update: The links below no longer work. Please look for, or report, this problem on PowerShell: Hot (1454 ideas) – Windows Server)
https://connect.microsoft.com/PowerShell/feedback/details/777375/powershell-exe-does-not-set-an-exit-code-when-file-is-used
https://connect.microsoft.com/PowerShell/feedback/details/750653/powershell-exe-doesn-t-return-correct-exit-codes-when-using-the-file-option
Since using -command
wasn't working for you, you could try adding a trap at the top of the script:
trap { write-output $_ ##teamcity[buildStatus status='FAILURE' ] exit 1 }
The above should result in a proper exit code when an exception is thrown.
I was having this exact issue while running with the -file
, but for some reason the trap syntax or the 'exit' syntax provided by Kevin wasn't working in my scenario.
I am not sure why, but just in case somebody else hits the same problem, I used the below syntax and it worked for me:
try{ #DO SOMETHING HERE } catch { Write-Error $_ ##teamcity[buildStatus status='FAILURE'] [System.Environment]::Exit(1) }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With