NuGet upload loop can report success after an earlier package push fails
Release Type: GitHub release automation
Version: master at 1714e21ce4f8706e38100896a3f017ac29ba5026
Platform: PowerShell release step; isolated reproduction with PowerShell 7.6.5 on macOS, using a stub publisher and no registry access.
Describe the bug
In release-deploy.yml, Push NuGet packages, each loop invokes dotnet nuget push without checking its exit status. With the default $PSNativeCommandUseErrorActionPreference = $false, an earlier failed upload can be overwritten by a later successful native command. The step then exits zero and the subsequent tag/release steps can proceed.
To reproduce
- Extract the existing
Push NuGet packagesrun block into a temporary.ps1file. - Create empty fixture files under
bin/packages:Stride.Core.4.4.0-beta6.nupkg,Stride.Engine.4.4.0-beta6.nupkg, andStride.GameStudio.4.4.0-beta6.nupkg. - Put a native executable named
dotnetfirst onPATHthat returns exit 1 for the Core filename and exit 0 for the others. Do not use a real publisher. - Execute with GitHub's documented PowerShell wrapper: prepend
$ErrorActionPreference = 'stop', appendif ((Test-Path -LiteralPath variable:\LASTEXITCODE)) { exit $LASTEXITCODE }.
Observed: the simulated Core upload failed; Engine and GameStudio continued; the script exited 0. Adding an immediate $LASTEXITCODE check after each push made the same fixture exit 1.
Expected behavior
An upload failure must make the step fail, even if independent uploads continue. Check every push and either stop immediately or collect failures and exit nonzero at the end. GameStudio should not publish when required providers failed. --skip-duplicate is useful recovery behavior and should remain where intended.
Additional context
This is an isolated reproduction of the checked-in loop, not a claim that an official release currently has missing packages. GitHub's shell documentation explains the last-exit-code wrapper.
Disclosure: I maintain dispat and found this while reviewing release failure propagation. The fix belongs in the existing workflow.
Source: stride3d/stride