@@ -132,8 +132,9 @@ function Get-GitHubPullRequest {
132132 returns $null and the caller resolves the current version without a version bump.
133133
134134 . OUTPUTS
135- PSCustomObject with HeadRef and Labels properties for a pull_request event, or
136- $null when the event has no pull request (non-PR events).
135+ PSCustomObject with HeadRef, Labels, and IsOpen properties for a pull_request event, or
136+ $null when the event has no pull request (non-PR events). IsOpen is $true only while the
137+ pull request is open (under review); it is $false once the PR is merged or closed.
137138
138139 . EXAMPLE
139140 $pullRequest = Get-GitHubPullRequest
@@ -160,16 +161,25 @@ function Get-GitHubPullRequest {
160161 $labels = @ ()
161162 $labels += $pr.labels.name
162163
164+ # A pull request is OPEN while it is under review (opened/reopened/synchronize/labeled).
165+ # Once it is merged or closed its state becomes 'closed'. Only an open pull request may
166+ # resolve to a prerelease; a merged/closed PR - like a push to the default branch - never
167+ # does. Default to not-open when state is missing so we never accidentally prerelease.
168+ $isOpen = $pr.state -eq ' open'
169+
163170 Write-Host ' -------------------------------------------------'
164171 Write-Host ([PSCustomObject ]@ {
165172 PRHeadRef = $pr.head.ref
173+ State = $pr.state
174+ IsOpen = $isOpen
166175 Labels = $labels -join ' , '
167176 } | Format-List | Out-String )
168177 Write-Host ' -------------------------------------------------'
169178
170179 [PSCustomObject ]@ {
171180 HeadRef = $pr.head.ref
172181 Labels = $labels
182+ IsOpen = $isOpen
173183 }
174184 }
175185}
@@ -181,7 +191,12 @@ function Resolve-ReleaseDecision {
181191
182192 . DESCRIPTION
183193 Evaluates the PR labels against the configured label categories and release type
184- to produce a complete release decision.
194+ to produce a complete release decision. A prerelease - whether a published prerelease or
195+ a non-published preview - is only ever resolved for an OPEN pull request, so the artifact
196+ built during review can never masquerade as a stable release before the merge decision is
197+ made. Once a PR is merged or closed (and likewise for a push to the default branch, which
198+ the workflow treats the same as a merged PR) the outcome is final: a full release, or the
199+ current version unchanged - never a prerelease.
185200
186201 . OUTPUTS
187202 PSCustomObject with ShouldPublish, CreateRelease, CreatePrerelease, MajorRelease,
@@ -208,6 +223,7 @@ function Resolve-ReleaseDecision {
208223 $prereleaseName = $PullRequest.HeadRef -replace ' [^a-zA-Z0-9]'
209224 $labels = $PullRequest.Labels
210225 $releaseType = $Configuration.ReleaseType
226+ $isOpenPullRequest = [bool ]$PullRequest.IsOpen
211227
212228 $validReleaseTypes = @ (' Release' , ' Prerelease' , ' None' )
213229 if ([string ]::IsNullOrWhiteSpace($releaseType )) {
@@ -217,15 +233,7 @@ function Resolve-ReleaseDecision {
217233 throw " Invalid ReleaseType: [$releaseType ]. Valid values are: $ ( $validReleaseTypes -join ' , ' ) "
218234 }
219235
220- $createRelease = $releaseType -eq ' Release'
221- $createPrerelease = $releaseType -eq ' Prerelease'
222- $shouldPublish = $createRelease -or $createPrerelease
223-
224236 $ignoreRelease = ($labels | Where-Object { $Configuration.IgnoreLabels -contains $_ }).Count -gt 0
225- if ($ignoreRelease -and $shouldPublish ) {
226- Write-Host ' Ignoring release creation due to ignore label.'
227- $shouldPublish = $false
228- }
229237
230238 # Always evaluate the version-bump labels so the resolved version reflects what WOULD be
231239 # created, regardless of whether this run publishes. ReleaseType (and the prerelease label
@@ -235,32 +243,51 @@ function Resolve-ReleaseDecision {
235243 $patchRelease = (
236244 (($labels | Where-Object { $Configuration.PatchLabels -contains $_ }).Count -gt 0 ) -or $Configuration.AutoPatching
237245 ) -and -not $majorRelease -and -not $minorRelease
238-
239246 $hasVersionBump = $majorRelease -or $minorRelease -or $patchRelease
240- if (-not $hasVersionBump ) {
241- # No explicit bump label and no AutoPatching: still resolve a patch version so the run
242- # can preview what it would create, but do not publish a full release for an unlabeled change.
243- Write-Host ' No version bump label and AutoPatching disabled; previewing a patch version without publishing.'
244- $patchRelease = $true
245- $hasVersionBump = $true
246- $shouldPublish = $false
247- }
248247
249- # Anything that is not a published full release is surfaced as a prerelease - either a
250- # published prerelease (ShouldPublish) or a non-published preview.
251- if (-not $shouldPublish ) {
248+ # A prerelease - whether a published prerelease or a non-published preview - only makes
249+ # sense while a pull request is OPEN. It lets the artifact built during review carry a
250+ # prerelease tag so it can never be mistaken for a stable release before the merge decision
251+ # is made. Once the change lands on the default branch the outcome is final: a merged pull
252+ # request publishes a full release (or, when nothing warrants one, nothing at all), and a
253+ # push to the default branch is treated the same as a merged pull request. A merge or push
254+ # therefore never resolves to a prerelease.
255+ if ($isOpenPullRequest ) {
256+ # Open pull request: always carry a prerelease tag. ReleaseType 'Prerelease' (the
257+ # prerelease label) publishes it; otherwise it is a non-published preview. An ignore
258+ # label only suppresses publishing - the reviewed artifact still stays a prerelease.
259+ $createRelease = $false
252260 $createPrerelease = $true
261+ $shouldPublish = ($releaseType -eq ' Prerelease' ) -and -not $ignoreRelease
262+ if (-not $hasVersionBump ) {
263+ Write-Host ' No version bump label and AutoPatching disabled; previewing a patch version.'
264+ $patchRelease = $true
265+ $hasVersionBump = $true
266+ }
267+ } else {
268+ # Merged/closed pull request or a push to the default branch: never a prerelease.
269+ $createPrerelease = $false
270+ $createRelease = ($releaseType -eq ' Release' ) -and -not $ignoreRelease -and $hasVersionBump
271+ $shouldPublish = $createRelease
272+ if (-not $createRelease ) {
273+ Write-Host ' No open pull request and nothing to release; keeping the current version.'
274+ $majorRelease = $false
275+ $minorRelease = $false
276+ $patchRelease = $false
277+ $hasVersionBump = $false
278+ }
253279 }
254280
255281 Write-Host ' -------------------------------------------------'
256282 Write-Host ([PSCustomObject ]@ {
257- ReleaseType = $releaseType
258- ShouldPublish = $shouldPublish
259- CreateRelease = $createRelease
260- CreatePrerelease = $createPrerelease
261- Major = $majorRelease
262- Minor = $minorRelease
263- Patch = $patchRelease
283+ ReleaseType = $releaseType
284+ IsOpenPullRequest = $isOpenPullRequest
285+ ShouldPublish = $shouldPublish
286+ CreateRelease = $createRelease
287+ CreatePrerelease = $createPrerelease
288+ Major = $majorRelease
289+ Minor = $minorRelease
290+ Patch = $patchRelease
264291 } | Format-List | Out-String )
265292 Write-Host ' -------------------------------------------------'
266293
0 commit comments