78 votes

Pourquoi mes codes de sortie Powershell sont-ils toujours "0"?

J'ai un script powershell comme suit

##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. Unfortunatly .NET 4.0 doesn't appear to be installed on this machine."
    ##teamcity[buildStatus status='FAILURE' ]
}


##teamcity[progressMessage 'Setting up variables']
# Set up varriables for 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']

De ce que je suis porté à croire, d'une uncaught Throw entraînera un code de sortie 1, mais, malheureusement, TeamCity est en train de dire le contraire.

[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

Il pourrait également être important de noter que mes Execution Mode est définie à l' Execute .ps1 script with "-File" arguement.

J'ai essayé de la modifier afin de l' Put script into PowerShell stdin with "-Command -" arguements , mais ensuite il a échoué avec le code de sortie 1 , même avec le passage des tests. Je suis sûr qu'en l'exécutant en tant -File va être la bonne façon.

Si j'ouvre le script situé à l' C:\BuildAgent\work\e903de7564e599c8\build.ps1 et de l'exécuter manuellement dans CMD, il fait la même chose... c'est à dire: l'échec des tests échouent, et l' %errorlevel% encore 0.

POURTANT, si je le lance en powershell et appelez - $LASTEXITCODE il renvoie le bon code à chaque fois.

98voto

Kevin Richardson Points 1696

C'est un problème connu avec PowerShell. L'exécution d'un script avec -file renvoie un code de sortie 0 quand il ne devrait pas.

Depuis l'utilisation de -command n'a pas de travail pour vous, vous pourriez essayer d'ajouter un piège en haut du script:

trap
{
    write-output $_
    ##teamcity[buildStatus status='FAILURE' ]
    exit 1
}

Le ci-dessus devrait en résulter un bon code de sortie lorsqu'une exception est levée.

25voto

Jay S Points 3988

J'avais exactement ce problème lorsque je travaillais avec le fichier -file, mais pour une raison quelconque, la syntaxe d'interruption ou la syntaxe de sortie fournie par Kevin ne fonctionnait pas dans mon scénario. Je ne sais pas pourquoi, mais juste au cas où quelqu'un d'autre rencontrerait le même problème, j'ai utilisé la syntaxe ci-dessous et cela a fonctionné pour moi:

 try{
    #DO SOMETHING HERE
}
catch
{
    Write-Error $_
    ##teamcity[buildStatus status='FAILURE']
    [System.Environment]::Exit(1)
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X