You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A workflow_dispatch run on the default branch resolves no associated pull request, so the merged pull request's version label is discarded and the version silently falls back to a Patch bump. Recovering a failed release by manual dispatch therefore publishes the wrong version, and PowerShell Gallery versions cannot be reclaimed once taken.
Impact
Manual dispatch on the default branch is the documented recovery route when a release run fails or is cancelled. In that exact scenario, the label that determines the version bump is ignored:
A merged pull request labelled minor should release 1.4.0 from 1.3.0.
A manual dispatch resolves no pull request, finds no version label, and applies AutoPatching.
The run publishes 1.3.1.
1.3.1 then permanently occupies the Gallery. The intended 1.4.0 can still be released afterwards, but the incorrect version cannot be removed, and consumers who installed in between receive a release that was never intended to exist.
This is silent. The run succeeds, and the only signal is a log line stating a patch bump was assumed.
PSWEE PR 🚀 [Feature]: Enter the Matrix #12, labelled Minor, merged as f8c59e6. Latest GitHub release and Gallery version were both 1.3.0.
The push run for f8c59e6 (run 33551501626) was cancelled one second after starting, because that caller still used cancel-in-progress: true with a github.ref-only concurrency key.
Recovery was attempted as a workflow_dispatch on main. The Plan job logged "Using direct default-branch release context with the default patch bump" and resolved 1.3.1.
The cancelled push is a separate caller-configuration problem. This issue is only about step 3: once a recovery dispatch happens, the version resolves incorrectly.
Cause
.github/actions/Get-PSModuleSettings/src/main.ps1 gates pull request association on $isPush:
$commitSha is populated for a manual dispatch (from GITHUB_SHA), and $isManualDispatchToDefaultBranch is computed on the line above, so the event is already recognised. Only the lookup is skipped.
With $pullRequest left null, Resolve-ReleaseDecision sees no labels. $majorRelease and $minorRelease are both false, so the $patchRelease fallback applies via AutoPatching or $isDirectStableRelease, and the run resolves a patch bump.
Expected behaviour
A workflow_dispatch on the default branch should resolve the pull request associated with the dispatched commit and honour its version label, exactly as the equivalent push does. The same Select-PullRequestForPush selection logic applies — the commit is a merge commit on the default branch in both cases.
If no pull request can be resolved, the run should fail loudly rather than silently assuming Patch. Publishing a wrong version to the Gallery is unrecoverable, so an explicit failure is strictly better than a silent downgrade.
Suggested approach
Widen the gate to cover a manual dispatch targeting the default branch, so the same association and selection path runs:
if (($isPush-or$isManualDispatchToDefaultBranch) -and$commitSha) {
Then decide the no-pull-request case deliberately. For a manual dispatch on the default branch, resolving no pull request most likely means the commit was pushed directly, so the existing direct-release path is legitimate. The distinction worth encoding is "no pull request exists" (proceed) versus "a pull request exists but was not consulted" (the current defect).
Validation plan
MariusStorhaug/MariusTestModule will be used as the consuming repository, following the approach that validated #528 and #529:
Reproduce the defect on the test module against the current v8, showing a labelled merged pull request whose label is discarded by a manual dispatch.
Capture the resolved-version evidence from the Plan job.
Fix in Process-PSModule with unit coverage in Get-PSModuleSettings and Resolve-PSModuleVersion tests.
Retarget the test module's caller at the fix branch and confirm the label is honoured.
Revert the caller to @v8 once the fix ships in a tag.
Note that step 1 must avoid publishing an incorrect stable version to the Gallery, since that cannot be undone. The reproduction will use the prerelease label or WhatIf so the wrong resolved version is observable without being published.
Related
Analysis originally recorded on 🪲[Bug]: Publish Module is failing #528 (that issue tracked and fixed the Gallery existence probe; this defect was found alongside it and is separate).
A
workflow_dispatchrun on the default branch resolves no associated pull request, so the merged pull request's version label is discarded and the version silently falls back to a Patch bump. Recovering a failed release by manual dispatch therefore publishes the wrong version, and PowerShell Gallery versions cannot be reclaimed once taken.Impact
Manual dispatch on the default branch is the documented recovery route when a release run fails or is cancelled. In that exact scenario, the label that determines the version bump is ignored:
minorshould release1.4.0from1.3.0.1.3.1.1.3.1then permanently occupies the Gallery. The intended1.4.0can still be released afterwards, but the incorrect version cannot be removed, and consumers who installed in between receive a release that was never intended to exist.This is silent. The run succeeds, and the only signal is a log line stating a patch bump was assumed.
Reproduction
Observed in
PSModule/PSWEEwhile diagnosing #528:Minor, merged asf8c59e6. Latest GitHub release and Gallery version were both1.3.0.pushrun forf8c59e6(run33551501626) was cancelled one second after starting, because that caller still usedcancel-in-progress: truewith agithub.ref-only concurrency key.workflow_dispatchonmain. The Plan job logged "Using direct default-branch release context with the default patch bump" and resolved1.3.1.The cancelled push is a separate caller-configuration problem. This issue is only about step 3: once a recovery dispatch happens, the version resolves incorrectly.
Cause
.github/actions/Get-PSModuleSettings/src/main.ps1gates pull request association on$isPush:$commitShais populated for a manual dispatch (fromGITHUB_SHA), and$isManualDispatchToDefaultBranchis computed on the line above, so the event is already recognised. Only the lookup is skipped.With
$pullRequestleft null,Resolve-ReleaseDecisionsees no labels.$majorReleaseand$minorReleaseare both false, so the$patchReleasefallback applies viaAutoPatchingor$isDirectStableRelease, and the run resolves a patch bump.Expected behaviour
A
workflow_dispatchon the default branch should resolve the pull request associated with the dispatched commit and honour its version label, exactly as the equivalentpushdoes. The sameSelect-PullRequestForPushselection logic applies — the commit is a merge commit on the default branch in both cases.If no pull request can be resolved, the run should fail loudly rather than silently assuming Patch. Publishing a wrong version to the Gallery is unrecoverable, so an explicit failure is strictly better than a silent downgrade.
Suggested approach
Widen the gate to cover a manual dispatch targeting the default branch, so the same association and selection path runs:
Then decide the no-pull-request case deliberately. For a manual dispatch on the default branch, resolving no pull request most likely means the commit was pushed directly, so the existing direct-release path is legitimate. The distinction worth encoding is "no pull request exists" (proceed) versus "a pull request exists but was not consulted" (the current defect).
Validation plan
MariusStorhaug/MariusTestModulewill be used as the consuming repository, following the approach that validated #528 and #529:v8, showing a labelled merged pull request whose label is discarded by a manual dispatch.Process-PSModulewith unit coverage inGet-PSModuleSettingsandResolve-PSModuleVersiontests.@v8once the fix ships in a tag.Note that step 1 must avoid publishing an incorrect stable version to the Gallery, since that cannot be undone. The reproduction will use the
prereleaselabel orWhatIfso the wrong resolved version is observable without being published.Related
Find-PSResourceprobe made a first-time publication fatal. That is the failure which forced the manual recovery dispatch in the PSWEE case, and therefore exposed this defect.