Skip to content

Commit fedb9fd

Browse files
BREAKING: remove version calculation; publish pre-stamped artifact and upload module zip to GitHub release (PSModule/Process-PSModule#326)
1 parent 72572ee commit fedb9fd

5 files changed

Lines changed: 175 additions & 551 deletions

File tree

README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,52 @@
11
# Publish-PSModule
22

33
This GitHub Action is a part of the [PSModule framework](https://github.com/PSModule).
4+
5+
It publishes a **pre-versioned** PowerShell module artifact to the PowerShell Gallery and creates a matching GitHub
6+
Release. The compressed module is also uploaded as a release asset so the GitHub Release page exposes the exact bytes
7+
that were tested and pushed to the Gallery.
8+
9+
## Breaking change — v3.0.0
10+
11+
`Publish-PSModule` no longer calculates the next version or mutates the module manifest. The artifact passed in must
12+
already contain the final `ModuleVersion` (and `Prerelease` tag, if any).
13+
14+
The following inputs were **removed**:
15+
16+
- `AutoPatching`
17+
- `IncrementalPrerelease`
18+
- `DatePrereleaseFormat`
19+
- `VersionPrefix`
20+
- `MajorLabels`, `MinorLabels`, `PatchLabels`, `IgnoreLabels`
21+
- `ReleaseType`
22+
23+
To migrate, run [`PSModule/Resolve-PSModuleVersion`](https://github.com/PSModule/Resolve-PSModuleVersion) to compute
24+
the version and pass it to [`PSModule/Build-PSModule`](https://github.com/PSModule/Build-PSModule) so the artifact is
25+
stamped before it is tested. The publish action then ships that artifact without any post-build manipulation.
26+
27+
This makes the tested artifact identical to the published artifact (see
28+
[PSModule/Process-PSModule#326](https://github.com/PSModule/Process-PSModule/issues/326)).
29+
30+
## What it does
31+
32+
1. Downloads the `module` artifact uploaded by `Build-PSModule`.
33+
2. Reads `ModuleVersion` and `PrivateData.PSData.Prerelease` from the downloaded manifest.
34+
3. Installs `RequiredModules` declared by the manifest.
35+
4. Publishes the module to the PowerShell Gallery (`Publish-PSResource`).
36+
5. Creates a GitHub Release with the same tag.
37+
6. Zips the module folder and uploads it as a release asset (`<Name>-<Version>.zip`).
38+
7. Optionally cleans up prerelease tags whose name matches the current PR branch.
39+
40+
## Inputs
41+
42+
| Name | Description | Required | Default |
43+
| -------------------------- | ------------------------------------------------------------------------------------------ | -------- | ---------------- |
44+
| `Name` | Name of the module. Defaults to the repository name. | No | Repository name |
45+
| `ModulePath` | Path to the downloaded module folder. | No | `outputs/module` |
46+
| `APIKey` | PowerShell Gallery API key. | Yes | |
47+
| `AutoCleanup` | Delete prerelease tags matching the PR branch after a stable release. | No | `true` |
48+
| `WhatIf` | Log the changes that would be made without publishing, creating, or deleting anything. | No | `false` |
49+
| `WorkingDirectory` | The working directory where the script will run from. | No | `.` |
50+
| `UsePRTitleAsReleaseName` | Use the PR title as the release name (otherwise the version string is used). | No | `false` |
51+
| `UsePRBodyAsReleaseNotes` | Use the PR body as the release notes (otherwise `--generate-notes` is used). | No | `true` |
52+
| `UsePRTitleAsNotesHeading` | Prefix the release notes with the PR title as an H1 heading linking to the PR. | No | `true` |

action.yml

Lines changed: 9 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
name: Publish-PSModule
2-
description: Publish a PowerShell module to the PowerShell Gallery.
2+
description: Publish a pre-versioned PowerShell module artifact to the PowerShell Gallery and GitHub Releases.
33
author: PSModule
44

5+
# BREAKING CHANGE (v3.0.0):
6+
# This action no longer calculates the next version or mutates the module manifest. The artifact passed in
7+
# must already contain the final ModuleVersion (and Prerelease tag, if any). Use PSModule/Resolve-PSModuleVersion
8+
# to compute the version and PSModule/Build-PSModule (v5+) to stamp it before testing. The version-calculation
9+
# inputs (AutoPatching, IncrementalPrerelease, DatePrereleaseFormat, VersionPrefix, *Labels, ReleaseType, IgnoreLabels)
10+
# have been removed.
11+
512
inputs:
613
Name:
714
description: Name of the module to publish.
@@ -17,42 +24,6 @@ inputs:
1724
description: Control whether to automatically delete the prerelease tags after the stable release is created.
1825
required: false
1926
default: 'true'
20-
AutoPatching:
21-
description: Control whether to automatically handle patches. If disabled, the action will only create a patch release if the pull request has a 'patch' label.
22-
required: false
23-
default: 'true'
24-
IncrementalPrerelease:
25-
description: Control whether to automatically increment the prerelease number. If disabled, the action will ensure only one prerelease exists for a given branch.
26-
required: false
27-
default: 'true'
28-
DatePrereleaseFormat:
29-
description: If specified, uses a date based prerelease scheme. The format should be a valid .NET format string like 'yyyyMMddHHmm'.
30-
required: false
31-
default: ''
32-
VersionPrefix:
33-
description: The prefix to use for the version number.
34-
required: false
35-
default: v
36-
MajorLabels:
37-
description: A comma separated list of labels that trigger a major release.
38-
required: false
39-
default: major, breaking
40-
MinorLabels:
41-
description: A comma separated list of labels that trigger a minor release.
42-
required: false
43-
default: minor, feature
44-
PatchLabels:
45-
description: A comma separated list of labels that trigger a patch release.
46-
required: false
47-
default: patch, fix
48-
IgnoreLabels:
49-
description: A comma separated list of labels that do not trigger a release.
50-
required: false
51-
default: NoRelease
52-
ReleaseType:
53-
description: The type of release to create. Values are 'Release' (stable), 'Prerelease', or 'None'.
54-
required: false
55-
default: Release
5627
WhatIf:
5728
description: If specified, the action will only log the changes it would make, but will not actually create or delete any releases or tags.
5829
required: false
@@ -85,34 +56,13 @@ runs:
8556
run: |
8657
Install-PSResource -Name Microsoft.PowerShell.PSResourceGet -Repository PSGallery -TrustRepository
8758
88-
- name: Initialize Publish Context
89-
id: init
90-
shell: pwsh
91-
working-directory: ${{ inputs.WorkingDirectory }}
92-
env:
93-
PSMODULE_PUBLISH_PSMODULE_INPUT_Name: ${{ inputs.Name }}
94-
PSMODULE_PUBLISH_PSMODULE_INPUT_AutoCleanup: ${{ inputs.AutoCleanup }}
95-
PSMODULE_PUBLISH_PSMODULE_INPUT_AutoPatching: ${{ inputs.AutoPatching }}
96-
PSMODULE_PUBLISH_PSMODULE_INPUT_DatePrereleaseFormat: ${{ inputs.DatePrereleaseFormat }}
97-
PSMODULE_PUBLISH_PSMODULE_INPUT_IgnoreLabels: ${{ inputs.IgnoreLabels }}
98-
PSMODULE_PUBLISH_PSMODULE_INPUT_ReleaseType: ${{ inputs.ReleaseType }}
99-
PSMODULE_PUBLISH_PSMODULE_INPUT_IncrementalPrerelease: ${{ inputs.IncrementalPrerelease }}
100-
PSMODULE_PUBLISH_PSMODULE_INPUT_MajorLabels: ${{ inputs.MajorLabels }}
101-
PSMODULE_PUBLISH_PSMODULE_INPUT_MinorLabels: ${{ inputs.MinorLabels }}
102-
PSMODULE_PUBLISH_PSMODULE_INPUT_PatchLabels: ${{ inputs.PatchLabels }}
103-
PSMODULE_PUBLISH_PSMODULE_INPUT_VersionPrefix: ${{ inputs.VersionPrefix }}
104-
PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }}
105-
run: ${{ github.action_path }}/src/init.ps1
106-
10759
- name: Download module artifact
108-
if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
10960
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
11061
with:
11162
name: module
11263
path: ${{ inputs.ModulePath }}
11364

11465
- name: Publish Module
115-
if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
11666
shell: pwsh
11767
working-directory: ${{ inputs.WorkingDirectory }}
11868
env:
@@ -126,7 +76,7 @@ runs:
12676
run: ${{ github.action_path }}/src/publish.ps1
12777

12878
- name: Cleanup Prereleases
129-
if: env.PUBLISH_CONTEXT_ShouldCleanup == 'true' || inputs.WhatIf == 'true'
79+
if: inputs.AutoCleanup == 'true' || inputs.WhatIf == 'true'
13080
shell: pwsh
13181
working-directory: ${{ inputs.WorkingDirectory }}
13282
env:

src/cleanup.ps1

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,40 @@ $PSStyle.OutputRendering = 'Ansi'
55

66
Import-Module -Name 'Helpers' -Force
77

8-
$prereleaseName = $env:PUBLISH_CONTEXT_PrereleaseName
9-
$prereleaseTagsToCleanup = $env:PUBLISH_CONTEXT_PrereleaseTagsToCleanup
10-
$whatIf = $env:PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf -eq 'true'
8+
#region Load inputs
9+
LogGroup 'Load inputs' {
10+
$whatIf = $env:PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf -eq 'true'
1111

12-
if ([string]::IsNullOrWhiteSpace($prereleaseName)) {
13-
Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run init.ps1 first.'
14-
exit 1
15-
}
12+
$githubEventJson = Get-Content $env:GITHUB_EVENT_PATH
13+
$githubEvent = $githubEventJson | ConvertFrom-Json
14+
$pull_request = $githubEvent.pull_request
15+
if (-not $pull_request) {
16+
throw 'GitHub event does not contain pull_request data. This script must be run from a pull_request event.'
17+
}
18+
$prHeadRef = $pull_request.head.ref
19+
$prereleaseName = $prHeadRef -replace '[^a-zA-Z0-9]'
1620

17-
LogGroup "Cleanup prereleases for [$prereleaseName]" {
18-
if ([string]::IsNullOrWhiteSpace($prereleaseTagsToCleanup)) {
19-
Write-Host "No prereleases found to cleanup for [$prereleaseName]."
21+
if ([string]::IsNullOrWhiteSpace($prereleaseName)) {
22+
Write-Host "No prerelease tag derivable from PR head ref [$prHeadRef]. Nothing to cleanup."
2023
return
2124
}
2225

23-
$tagsToDelete = $prereleaseTagsToCleanup -split ',' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
26+
Write-Host "PR head ref: [$prHeadRef]"
27+
Write-Host "Prerelease name: [$prereleaseName]"
28+
Write-Host "WhatIf: [$whatIf]"
29+
}
30+
#endregion Load inputs
31+
32+
#region Find prereleases to cleanup
33+
LogGroup "Find prereleases to cleanup for [$prereleaseName]" {
34+
$releases = gh release list --json 'createdAt,isDraft,isLatest,isPrerelease,name,publishedAt,tagName' | ConvertFrom-Json
35+
if ($LASTEXITCODE -ne 0) {
36+
Write-Error 'Failed to list releases for the repository.'
37+
exit $LASTEXITCODE
38+
}
39+
40+
$prereleasesToCleanup = $releases | Where-Object { $_.tagName -like "*$prereleaseName*" }
41+
$tagsToDelete = @($prereleasesToCleanup | ForEach-Object { $_.tagName } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
2442

2543
if ($tagsToDelete.Count -eq 0) {
2644
Write-Host "No prereleases found to cleanup for [$prereleaseName]."
@@ -29,8 +47,11 @@ LogGroup "Cleanup prereleases for [$prereleaseName]" {
2947

3048
Write-Host "Found $($tagsToDelete.Count) prereleases to cleanup:"
3149
$tagsToDelete | ForEach-Object { Write-Host " - $_" }
32-
Write-Host ''
50+
}
51+
#endregion Find prereleases to cleanup
3352

53+
#region Delete prereleases
54+
LogGroup "Delete prereleases for [$prereleaseName]" {
3455
foreach ($tag in $tagsToDelete) {
3556
Write-Host "Deleting prerelease: [$tag]"
3657
if ($whatIf) {
@@ -47,3 +68,4 @@ LogGroup "Cleanup prereleases for [$prereleaseName]" {
4768

4869
Write-Host "::notice::Cleaned up $($tagsToDelete.Count) prerelease(s) for [$prereleaseName]."
4970
}
71+
#endregion Delete prereleases

0 commit comments

Comments
 (0)