Commit 68696b6
🪲 [Fix]: New module versions publish to the PowerShell Gallery (#529)
A module version that has never been published to the PowerShell Gallery
can now be published. Any first release, and every subsequent new
version, previously failed the Publish-Module stage before the upload
was attempted.
## Fixed: New module versions publish to the PowerShell Gallery
Publishing a version that is not yet on the PowerShell Gallery now
succeeds. The stage checks whether the version already exists so an
interrupted run can resume, and treats an absent version as the expected
result for a new release rather than an error.
Before this change the Publish-Module job failed with the following, and
no module was ever uploaded:
```text
Find-PSResource: Package with name 'MyModule', version '1.3.1' could not be found in repository 'PSGallery'.
Error: Process completed with exit code 1.
```
No repository configuration changes are needed. A workflow run that
previously failed at this point succeeds on re-run.
Resuming an interrupted publication is unchanged: when the version is
already on the Gallery, the run skips the upload and continues to GitHub
release creation.
---
<details>
<summary>Technical details</summary>
- `.github/actions/Publish-PSModule/src/publish.ps1` — the Gallery
existence probe in the `Publish to PSGallery` region ran
`Find-PSResource` with `-ErrorAction Stop`.
`Microsoft.PowerShell.PSResourceGet` raises
`PackageNotFound,Microsoft.PowerShell.PSResourceGet.Cmdlets.FindPSResource`
when the requested version does not exist, which `-ErrorAction Stop`
turns into a throw, so the probe made a missing version fatal instead of
returning `$null`. The probe now keeps `-ErrorAction Stop` and catches
only `PackageNotFound`, treating that one error as 'not yet published'
and letting the `if ($publishedPackage)` branch decide the outcome.
Every other error stays fatal, so a transient Gallery failure cannot be
misread as 'version absent' and cause a re-upload of a version that
already exists.
- The probe was introduced in #512 to make
Gallery publication idempotent for the default-branch push release path.
That path replaced a `try`/`catch` around `Publish-PSResource`, which is
why the regression reached `main` without an existing test catching it.
-
`.github/actions/Publish-PSModule/tests/Publish-PSModule.Recovery.Tests.ps1`
— the harness could not observe whether publication happened, so its
assertions were vacuous: `Publish-PSResource` was shimmed to set
`$script:publishInvoked`, but `publish.ps1` runs in its own scope via
`&`, so the flag never propagated and stayed `$false` regardless.
Replaced with a hashtable captured by `GetNewClosure()`, which is shared
by reference. A second variant wrote a marker file under
`$env:GITHUB_WORKSPACE`; that is process-wide and races between parallel
Pester runspaces, so the marker could land in another test file's
`TestDrive`. The not-found shim also used
`$PSCmdlet.ThrowTerminatingError(...)`, which ignores `-ErrorAction` and
therefore threw under both `Stop` and `SilentlyContinue` — unable to
distinguish the fix from the defect. It now uses `Write-Error` with the
real `PackageNotFound` error ID, matching how the cmdlet actually
behaves. Added a case asserting a non-`PackageNotFound` lookup failure
stays fatal and does not publish. Each test was verified to fail against
the specific defect it guards.
-
`.github/actions/Release-PSModule/tests/Release-PSModule.WhatIf.Tests.ps1`
and `Publish-PSModule.Recovery.Tests.ps1` — shim teardown used
`Remove-Item -Path function:global:X`. `Set-Item` accepts that path and
creates `X` in the global scope, but `Remove-Item` and `Get-Item` do not
resolve it back, and fail silently rather than erroring, so the cleanup
was a no-op. The shims survived `AfterAll` and shadowed the real
commands for later test files, which is what made `Test-Actions` fail
with `A parameter cannot be found that matches parameter name
'Prerelease'` in `Get-NextPrereleaseNumber`. Teardown now removes by
name.
- Validated end to end in `MariusStorhaug/MariusTestModule` ([PR
#63](MariusStorhaug/MariusTestModule#63)) with
the caller pointed at this branch. A new version published successfully
([run
33597824748](https://github.com/MariusStorhaug/MariusTestModule/actions/runs/33597824748/job/100145585604)),
and re-running the same job with the version present skipped the upload
via the resume path
([re-run](https://github.com/MariusStorhaug/MariusTestModule/actions/runs/33597824748/job/100146802704)).
Both branches of the probe are confirmed against the live Gallery.
- Out of scope, found while reproducing: a `workflow_dispatch` on the
default branch resolves no associated pull request, because pull request
association in `.github/actions/Get-PSModuleSettings/src/main.ps1` is
gated on `$isPush`. A manual recovery run therefore discards the merged
pull request's version label and silently resolves a Patch bump. This is
a separate defect in version resolution and is recorded in the analysis
on #528; it is not addressed here.
- Also out of scope: `.github/workflows/Test-Actions.yml` builds a
Pester configuration with `Run.Parallel` and `Run.Shuffle`, asserts the
options applied, then discards it and creates a fresh
`New-PesterConfiguration` for the actual run. Parallel and shuffle are
validated but never used, which is why the `GITHUB_WORKSPACE` race above
could not surface in CI. The suite now passes both sequentially and
under the intended parallel configuration, so enabling it should be
safe.
| Changed surface | Standards checked | Framework docs checked | Result
|
| --- | --- | --- | --- |
| `.github/actions/Publish-PSModule/src/**` (PowerShell) | Coding
standards, error handling | Publish stage contract | Aligned |
| `.github/actions/Publish-PSModule/tests/**` (Pester) | Pester test
standards | Action test layout | Aligned |
| `.github/actions/Release-PSModule/tests/**` (Pester) | Pester test
standards | Action test layout | Aligned |
</details>
<details>
<summary>Relevant issues (or links)</summary>
- Resolves #528
### Related work
- References #512
</details>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: MariusStorhaug <17722253+MariusStorhaug@users.noreply.github.com>
Co-authored-by: Marius Storhaug <Marius.Storhaug@dnb.no>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>1 parent 59e056c commit 68696b6
3 files changed
Lines changed: 73 additions & 10 deletions
File tree
- .github/actions
- Publish-PSModule
- src
- tests
- Release-PSModule/tests
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
145 | 145 | | |
146 | 146 | | |
147 | 147 | | |
148 | | - | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
149 | 160 | | |
150 | 161 | | |
151 | 162 | | |
| |||
Lines changed: 55 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
33 | | - | |
34 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
35 | 39 | | |
36 | 40 | | |
37 | 41 | | |
| |||
68 | 72 | | |
69 | 73 | | |
70 | 74 | | |
71 | | - | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
72 | 80 | | |
73 | 81 | | |
74 | 82 | | |
75 | 83 | | |
76 | 84 | | |
77 | 85 | | |
78 | | - | |
79 | | - | |
| 86 | + | |
| 87 | + | |
80 | 88 | | |
81 | 89 | | |
82 | 90 | | |
83 | 91 | | |
84 | 92 | | |
85 | | - | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
86 | 134 | | |
87 | 135 | | |
Lines changed: 6 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
39 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
40 | 44 | | |
41 | 45 | | |
42 | 46 | | |
| |||
0 commit comments