A new module repository created from PSModule/Template-PSModule has no GitHub releases yet. The first pull request opened in such a repository fails in the Plan job before any build, test, or lint stage runs, so a maintainer bootstrapping a module cannot get a green pipeline on the pull request that is supposed to produce the first release.
Request
What happens
The Plan / Resolve-Version step fails with:
Cannot bind argument to parameter 'Releases' because it is null.
Every downstream job is skipped, so the pull request reports a failed pipeline with no way for the contributor to act on it. The failure is not caused by anything in the module being bootstrapped — it happens on a repository whose src/ builds and tests cleanly.
Reproduction steps
- Create a repository from
Template-PSModule and do not publish any release or tag
- Open a pull request against
main
- Observe that
Process-PSModule / Plan / Plan fails and every other job is skipped
What is expected
The pipeline treats "no releases yet" as the normal starting state of a module. Version resolution floors at 0.0.0, applies the pull request's release label on top of it, and the rest of the pipeline runs as it would for any other pull request.
Environment
- Workflow version:
PSModule/Process-PSModule/.github/workflows/workflow.yml@v6.1.13 and @v6.1.14
- Repository state: zero releases, zero tags
- Observed in: PSModule/Lovdata#3
Regression
Not verified against earlier workflow versions. The affected code moved into the workflow repository in #385, so it is reachable in every version that internalizes the actions.
Workaround
Publish a placeholder GitHub release, for example v0.0.0, before opening the first pull request, so the release list is not empty. It has to be cleaned up afterwards and pollutes the release history of a module that has never shipped.
Acceptance criteria
- The first pull request in a repository with no releases completes the
Plan job and runs the rest of the pipeline
- Version resolution starts from
0.0.0 when no release exists, and the pull request's release label bumps from there
- Behaviour for repositories that already have releases is unchanged
Technical decisions
Root cause: Get-GitHubRelease in .github/actions/Resolve-PSModuleVersion/src/Resolve-PSModuleVersion.Helpers.psm1 runs gh release list --json ..., which returns [] for a repository with no releases. '[]' | ConvertFrom-Json emits nothing, so an empty pipeline collapses to $null and the function returns $null rather than an empty array. Get-LatestGitHubVersion and Get-NextModuleVersion both declare [Parameter(Mandatory)] [array] $Releases, and a mandatory parameter rejects $null at binding time.
Fix placement: Guard at both ends rather than only one. The producer (Get-GitHubRelease) is made to return an array consistently, and the consumers accept an empty one. Fixing only the producer leaves the same trap for any future caller that passes an empty collection.
Producer change: Get-GitHubRelease declares [OutputType([array])] already; wrap its result so an empty release list is returned as an empty array instead of nothing, and wrap the call site in main.ps1 with @(...) so the array is preserved across the assignment.
Consumer change: Add [AllowEmptyCollection()] to the Releases parameter of Get-LatestGitHubVersion and Get-NextModuleVersion. Both already handle an empty list correctly — Get-LatestGitHubVersion warns and falls back to 0.0.0, and the incremental prerelease lookup finds no matching tags — so only the binding needs to change.
Breaking changes: None. Repositories that already have releases bind a non-empty array exactly as before.
Test approach: The helper module has no test coverage today, and adding a test harness for it is a larger change than this fix. The change is verified against a real bootstrapping repository with zero releases.
Implementation plan
Core changes
Verification
A new module repository created from
PSModule/Template-PSModulehas no GitHub releases yet. The first pull request opened in such a repository fails in the Plan job before any build, test, or lint stage runs, so a maintainer bootstrapping a module cannot get a green pipeline on the pull request that is supposed to produce the first release.Request
What happens
The
Plan / Resolve-Versionstep fails with:Every downstream job is skipped, so the pull request reports a failed pipeline with no way for the contributor to act on it. The failure is not caused by anything in the module being bootstrapped — it happens on a repository whose
src/builds and tests cleanly.Reproduction steps
Template-PSModuleand do not publish any release or tagmainProcess-PSModule / Plan / Planfails and every other job is skippedWhat is expected
The pipeline treats "no releases yet" as the normal starting state of a module. Version resolution floors at
0.0.0, applies the pull request's release label on top of it, and the rest of the pipeline runs as it would for any other pull request.Environment
PSModule/Process-PSModule/.github/workflows/workflow.yml@v6.1.13and@v6.1.14Regression
Not verified against earlier workflow versions. The affected code moved into the workflow repository in #385, so it is reachable in every version that internalizes the actions.
Workaround
Publish a placeholder GitHub release, for example
v0.0.0, before opening the first pull request, so the release list is not empty. It has to be cleaned up afterwards and pollutes the release history of a module that has never shipped.Acceptance criteria
Planjob and runs the rest of the pipeline0.0.0when no release exists, and the pull request's release label bumps from thereTechnical decisions
Root cause:
Get-GitHubReleasein.github/actions/Resolve-PSModuleVersion/src/Resolve-PSModuleVersion.Helpers.psm1runsgh release list --json ..., which returns[]for a repository with no releases.'[]' | ConvertFrom-Jsonemits nothing, so an empty pipeline collapses to$nulland the function returns$nullrather than an empty array.Get-LatestGitHubVersionandGet-NextModuleVersionboth declare[Parameter(Mandatory)] [array] $Releases, and a mandatory parameter rejects$nullat binding time.Fix placement: Guard at both ends rather than only one. The producer (
Get-GitHubRelease) is made to return an array consistently, and the consumers accept an empty one. Fixing only the producer leaves the same trap for any future caller that passes an empty collection.Producer change:
Get-GitHubReleasedeclares[OutputType([array])]already; wrap its result so an empty release list is returned as an empty array instead of nothing, and wrap the call site inmain.ps1with@(...)so the array is preserved across the assignment.Consumer change: Add
[AllowEmptyCollection()]to theReleasesparameter ofGet-LatestGitHubVersionandGet-NextModuleVersion. Both already handle an empty list correctly —Get-LatestGitHubVersionwarns and falls back to0.0.0, and the incremental prerelease lookup finds no matching tags — so only the binding needs to change.Breaking changes: None. Repositories that already have releases bind a non-empty array exactly as before.
Test approach: The helper module has no test coverage today, and adding a test harness for it is a larger change than this fix. The change is verified against a real bootstrapping repository with zero releases.
Implementation plan
Core changes
Get-GitHubReleasewhen the repository has no releasesGet-GitHubReleasecall inmain.ps1so the empty array survives assignment[AllowEmptyCollection()]to theReleasesparameter ofGet-LatestGitHubVersion[AllowEmptyCollection()]to theReleasesparameter ofGet-NextModuleVersionVerification
Planjob completes on a pull request in a repository with no releases