Make Windows build-and-upload steps fail fast on native command errors - #334
Merged
Conversation
SeanTAllen
force-pushed
the
windows-build-fail-fast
branch
from
June 12, 2026 03:28
96fac0e to
79fff3f
Compare
In a pwsh step a non-zero exit from a native command is not fatal by
default, so a failure in an early command (the pip install, the build,
the tests) did not stop the step. It ran on and the real error got
buried, only surfacing at the late $LASTEXITCODE guard after the
Cloudsmith push.
Two complementary changes make Windows CI fail at the point of failure:
- The four Build and upload blocks set $ErrorActionPreference = 'Stop'
and $PSNativeCommandUseErrorActionPreference = $true, turning native
non-zero exits into terminating errors. This catches the pip install
and the Cloudsmith push directly, so the manual $LASTEXITCODE guard
is removed.
- make.ps1 guards every native call (ponyc, the test binary) with an
explicit $LastExitCode check, mirroring ponyup's make.ps1. This fails
the build and test steps, including in pr.yml and the Windows breakage
workflow, which call make.ps1 without the block-level preferences, and
when run locally.
Failing fast exposed two latent failures make.ps1 had been masking:
- The version line used 'git rev-parse --short --verify HEAD^', whose
parent ref does not resolve in the shallow CI checkout. Switch to
HEAD, matching the Makefile.
- It passed $configFlag as a positional argument to ponyc. In Release
builds $configFlag is empty, and pwsh 7 passes the variable through
to native commands as a literal empty string whether or not it is
quoted. ponyc treated it as a second package path, built the real
package, then exited non-zero ('no source files in package'). Build
the ponyc argument list as an array and only append $configFlag when
non-empty, so the empty argument is genuinely absent.
Closes #331
SeanTAllen
force-pushed
the
windows-build-fail-fast
branch
from
June 12, 2026 03:35
79fff3f to
2361856
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Windows
Build and uploadsteps innightlies.ymlandrelease.ymlrun a chain of native commands in a single pwsh block —pip install, the ponyc download, themake.ps1build/test/install/package commands, then the Cloudsmith push — with a$LASTEXITCODEguard only after the push. In pwsh a non-zero exit from a native command is not fatal by default, so a failure in an earlier command did not stop the step; it ran on and the real error got buried until the guard fired much later.Two complementary changes make Windows CI fail at the point of failure:
The four Build and upload blocks set
$ErrorActionPreference = 'Stop'and$PSNativeCommandUseErrorActionPreference = $trueat the top, turning native non-zero exits into terminating errors. This catches thepip install(the original failure) and the Cloudsmith push directly, so the manual$LASTEXITCODEguard is removed.make.ps1now guards every native call (ponycand the test binary) with an explicit$LastExitCodecheck, mirroring ponyup'smake.ps1. This is what fails the build and test steps — and crucially it also coverspr.ymland the Windows breakage workflow, which callmake.ps1without the block-level preferences, plus local.\make.ps1runs. (The explicit check is robust to those workflows'2>&1redirect, since$LastExitCodeis unaffected by stream merging.) The block-level preference and the in-script guards are independent mechanisms — correctness does not depend on preference inheritance into the called script.While making the build fail fast,
make.ps1's version line usedgit rev-parse --short --verify HEAD^, whose parent ref does not resolve in the shallowactions/checkoutclone (verified against a CI log:fatal: Needed a single revision,Version: 0.9.2-). The failure was silently swallowed before, but would become a hard build break once make.ps1 fails fast. Switched toHEAD, which always resolves and matches the canonical Makefile.Note: the fix relies on the runners executing
run:steps under pwsh >= 7.4, where$PSNativeCommandUseErrorActionPreferenceis a settable preference. Modern Windows runner images ship this; worth eyeballing the first post-mergewindows-11-armrun.Follow-up filed as #333: the Windows build embeds a
-<sha>-suffixed version string the Makefile doesn't (pre-existing; surfaced more clearly by theHEADfix).Closes #331