-
Notifications
You must be signed in to change notification settings - Fork 0
🚀 [Feature]: Add ReleaseType input and rename AutoCleanup to CleanupPrereleases #59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
ReleaseType input for explicit release control
ReleaseType input for explicit release controlThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a new ReleaseType input parameter that provides explicit control over release creation, replacing the previous automatic detection based on pull request state and branch information. The feature enables callers (typically Get-PSModuleSettings) to specify whether to create a Release, Prerelease, Cleanup, or None.
Changes:
- Added
ReleaseTypeinput parameter to action.yml with default value 'Release' - Removed automatic detection logic for release types based on PR state, merge status, and target branch
- Added validation for the ReleaseType parameter with support for four values: Release, Prerelease, Cleanup, None
- Updated logging to display ReleaseType instead of PR state details
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| action.yml | Adds ReleaseType input parameter definition and environment variable mapping |
| scripts/helpers/Publish-PSModule.ps1 | Replaces automatic release type detection with explicit ReleaseType input handling and validation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…ng related variables for clarity
…le/Publish-PSModule into feature/releasetype-input
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
scripts/helpers/Publish-PSModule.ps1
Outdated
| } | ||
|
|
||
| if ((($closedPullRequest -or $createRelease) -and $autoCleanup) -or $whatIf) { | ||
| if ((($isCleanupMode -or $createRelease) -and $autoCleanup) -or $whatIf) { |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition for cleanup includes 'or $whatIf' which means cleanup will always execute in WhatIf mode regardless of ReleaseType or autoCleanup settings. This seems inconsistent - if ReleaseType is 'None' and WhatIf is true, should cleanup still be shown? Consider whether the WhatIf check should be inside the condition rather than ORed with it, or document this behavior explicitly.
| if ((($isCleanupMode -or $createRelease) -and $autoCleanup) -or $whatIf) { | |
| if (($isCleanupMode -or $createRelease) -and $autoCleanup) { |
- Remove main.ps1 and split functionality into init.ps1, publish.ps1, and cleanup.ps1 for better organization. - Implement init.ps1 to handle dependency installation, input loading, and configuration setup. - Create publish.ps1 to manage module publishing to PSGallery and GitHub releases, including versioning and release notes handling. - Add cleanup.ps1 to remove old prereleases based on specified tags.
| PSMODULE_PUBLISH_PSMODULE_INPUT_PatchLabels: ${{ inputs.PatchLabels }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_VersionPrefix: ${{ inputs.VersionPrefix }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }} | ||
| run: ${{ github.action_path }}/scripts/init.ps1 |
Check warning
Code scanning / CodeQL
Code injection Medium
${ github.action_path }
Copilot Autofix
AI 1 minute ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
| PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRTitleAsReleaseName: ${{ inputs.UsePRTitleAsReleaseName }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRTitleAsNotesHeading: ${{ inputs.UsePRTitleAsNotesHeading }} | ||
| run: ${{ github.action_path }}/scripts/main.ps1 | ||
| run: ${{ github.action_path }}/scripts/publish.ps1 |
Check warning
Code scanning / CodeQL
Code injection Medium
${ github.action_path }
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI less than a minute ago
In general, to fix code injection issues in GitHub Actions run: steps, avoid embedding expressions like ${{ ... }} directly into the command string. Instead, assign any expression values (even those that are expected to be safe) to environment variables using the workflow syntax, and then reference those variables via the shell’s native variable expansion ($VAR in pwsh/Bash). This separates the expression evaluation phase from the command parsing phase and prevents user-controlled data from being interpreted as code.
For this specific case, the best fix is to add an environment variable (for example, ACTION_PATH) whose value is ${{ github.action_path }}, and then change the run: line to use $env:ACTION_PATH (PowerShell syntax) to build the script path. We will apply this change consistently to all three PowerShell steps that currently use run: ${{ github.action_path }}/scripts/...ps1:
- “Initialize Publish Context” (line 105)
- “Publish Module” (line 126)
- “Cleanup Prereleases” (line 134)
For each step:
- Add
ACTION_PATH: ${{ github.action_path }}underenv:. - Replace
run: ${{ github.action_path }}/scripts/<script>.ps1withrun: $env:ACTION_PATH/scripts/<script>.ps1.
This requires no new imports or external libraries and does not alter the logic of the scripts; it only changes how the script path is passed to PowerShell.
-
Copy modified line R93 -
Copy modified line R106 -
Copy modified line R120 -
Copy modified line R128 -
Copy modified line R135 -
Copy modified line R137
| @@ -90,6 +90,7 @@ | ||
| shell: pwsh | ||
| working-directory: ${{ inputs.WorkingDirectory }} | ||
| env: | ||
| ACTION_PATH: ${{ github.action_path }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_Name: ${{ inputs.Name }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_CleanupPrereleases: ${{ inputs.CleanupPrereleases }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_AutoPatching: ${{ inputs.AutoPatching }} | ||
| @@ -102,7 +103,7 @@ | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_PatchLabels: ${{ inputs.PatchLabels }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_VersionPrefix: ${{ inputs.VersionPrefix }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }} | ||
| run: ${{ github.action_path }}/scripts/init.ps1 | ||
| run: $env:ACTION_PATH/scripts/init.ps1 | ||
|
|
||
| - name: Download module artifact | ||
| if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true' | ||
| @@ -116,6 +117,7 @@ | ||
| shell: pwsh | ||
| working-directory: ${{ inputs.WorkingDirectory }} | ||
| env: | ||
| ACTION_PATH: ${{ github.action_path }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_Name: ${{ inputs.Name }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_ModulePath: ${{ inputs.ModulePath }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_APIKey: ${{ inputs.APIKey }} | ||
| @@ -123,12 +125,13 @@ | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRBodyAsReleaseNotes: ${{ inputs.UsePRBodyAsReleaseNotes }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRTitleAsReleaseName: ${{ inputs.UsePRTitleAsReleaseName }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRTitleAsNotesHeading: ${{ inputs.UsePRTitleAsNotesHeading }} | ||
| run: ${{ github.action_path }}/scripts/publish.ps1 | ||
| run: $env:ACTION_PATH/scripts/publish.ps1 | ||
|
|
||
| - name: Cleanup Prereleases | ||
| if: env.PUBLISH_CONTEXT_ShouldCleanup == 'true' || inputs.WhatIf == 'true' | ||
| shell: pwsh | ||
| working-directory: ${{ inputs.WorkingDirectory }} | ||
| env: | ||
| ACTION_PATH: ${{ github.action_path }} | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }} | ||
| run: ${{ github.action_path }}/scripts/cleanup.ps1 | ||
| run: $env:ACTION_PATH/scripts/cleanup.ps1 |
| working-directory: ${{ inputs.WorkingDirectory }} | ||
| env: | ||
| PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }} | ||
| run: ${{ github.action_path }}/scripts/cleanup.ps1 |
Check warning
Code scanning / CodeQL
Code injection Medium
${ github.action_path }
Copilot Autofix
AI 1 minute ago
Copilot could not generate an autofix suggestion
Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Set-GitHubLogGroup 'Calculate new version' { | ||
| # - Increment based on label on PR | ||
| $newVersion = New-PSSemVer -Version $latestVersion | ||
| $newVersion.Prefix = $versionPrefix | ||
| if ($majorRelease) { | ||
| Write-Output 'Incrementing major version.' | ||
| $newVersion.BumpMajor() | ||
| } elseif ($minorRelease) { | ||
| Write-Output 'Incrementing minor version.' | ||
| $newVersion.BumpMinor() | ||
| } elseif ($patchRelease) { | ||
| Write-Output 'Incrementing patch version.' | ||
| $newVersion.BumpPatch() | ||
| } else { | ||
| Write-Output 'No version bump required.' | ||
| } |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When ReleaseType is 'None' and no version bump is found, the code still attempts to calculate a new version (lines 225-238) even though shouldPublish is false. This could lead to an incomplete or invalid version being stored in environment variables. The version calculation logic should be skipped entirely when shouldPublish is false, or the code should handle this case explicitly to avoid storing invalid version information.
| if ($createPrerelease -and $hasVersionBump) { | ||
| Write-Output "Adding a prerelease tag to the version using the branch name [$prereleaseName]." | ||
| Write-Output ($releases | Where-Object { $_.tagName -like "*$prereleaseName*" } | | ||
| Select-Object -Property name, isPrerelease, isLatest, publishedAt | Format-Table -AutoSize | Out-String) | ||
|
|
||
| $newVersion.Prerelease = $prereleaseName | ||
| Write-Output "Partial new version: [$newVersion]" | ||
|
|
||
| if (-not [string]::IsNullOrEmpty($datePrereleaseFormat)) { | ||
| Write-Output "Using date-based prerelease: [$datePrereleaseFormat]." | ||
| $newVersion.Prerelease += "$(Get-Date -Format $datePrereleaseFormat)" | ||
| Write-Output "Partial new version: [$newVersion]" | ||
| } | ||
|
|
||
| if ($incrementalPrerelease) { | ||
| # Find the latest prerelease version | ||
| $newVersionString = "$($newVersion.Major).$($newVersion.Minor).$($newVersion.Patch)" | ||
|
|
||
| # PowerShell Gallery | ||
| $params = @{ | ||
| Name = $name | ||
| Version = '*' | ||
| Prerelease = $true | ||
| Repository = 'PSGallery' | ||
| Verbose = $false | ||
| ErrorAction = 'SilentlyContinue' | ||
| } | ||
| Write-Output 'Finding the latest prerelease version in the PowerShell Gallery.' | ||
| Write-Output ($params | Format-Table | Out-String) | ||
| $psGalleryPrereleases = Find-PSResource @params | ||
| $psGalleryPrereleases = $psGalleryPrereleases | Where-Object { $_.Version -like "$newVersionString" } | ||
| $psGalleryPrereleases = $psGalleryPrereleases | Where-Object { $_.Prerelease -like "$prereleaseName*" } | ||
| $latestPSGalleryPrerelease = $psGalleryPrereleases.Prerelease | ForEach-Object { | ||
| [int]($_ -replace $prereleaseName) | ||
| } | Sort-Object | Select-Object -Last 1 | ||
| Write-Output "PSGallery prerelease: [$latestPSGalleryPrerelease]" | ||
|
|
||
| # GitHub | ||
| $ghPrereleases = $releases | Where-Object { $_.tagName -like "*$newVersionString*" } | ||
| $ghPrereleases = $ghPrereleases | Where-Object { $_.tagName -like "*$prereleaseName*" } | ||
| $latestGHPrereleases = $ghPrereleases.tagName | ForEach-Object { | ||
| $number = $_ | ||
| $number = $number -replace '\.' | ||
| $number = ($number -split $prereleaseName, 2)[-1] | ||
| [int]$number | ||
| } | Sort-Object | Select-Object -Last 1 | ||
| Write-Output "GitHub prerelease: [$latestGHPrereleases]" | ||
|
|
||
| $latestPrereleaseNumber = [Math]::Max($latestPSGalleryPrerelease, $latestGHPrereleases) | ||
| $latestPrereleaseNumber++ | ||
| $latestPrereleaseNumber = ([string]$latestPrereleaseNumber).PadLeft(3, '0') | ||
| $newVersion.Prerelease += $latestPrereleaseNumber | ||
| } | ||
| } |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition $createPrerelease -and $hasVersionBump on line 242 means prerelease information is only added when there's a version bump. However, when ReleaseType is 'None', createPrerelease is false and hasVersionBump might also be false. The entire prerelease calculation block (lines 242-295) could be executed unnecessarily or with incomplete data. This should be guarded by checking shouldPublish first to avoid unnecessary computation.
| $whatIf = $env:PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf -eq 'true' | ||
|
|
||
| if ([string]::IsNullOrWhiteSpace($prereleaseName)) { | ||
| Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run main.ps1 first.' |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message incorrectly refers to 'main.ps1' when it should refer to 'init.ps1'. The cleanup.ps1 script requires context from init.ps1, not main.ps1 (which has been removed in this PR).
| Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run main.ps1 first.' | |
| Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run init.ps1 first.' |
| $usePRTitleAsNotesHeading = $env:PSMODULE_PUBLISH_PSMODULE_INPUT_UsePRTitleAsNotesHeading -eq 'true' | ||
|
|
||
| if ([string]::IsNullOrWhiteSpace($newVersionString)) { | ||
| Write-Error 'PUBLISH_CONTEXT_NewVersion is not set. Run main.ps1 first.' |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message incorrectly refers to 'main.ps1' when it should refer to 'init.ps1'. The publish.ps1 script requires context from init.ps1, not main.ps1 (which has been removed in this PR).
| Write-Error 'PUBLISH_CONTEXT_NewVersion is not set. Run main.ps1 first.' | |
| Write-Error 'PUBLISH_CONTEXT_NewVersion is not set. Run init.ps1 first.' |
| AutoCleanup: | ||
| description: Control wether to automatically delete the prerelease tags after the stable release is created. | ||
| CleanupPrereleases: | ||
| description: When enabled, only performs cleanup of old prerelease tags without creating a new release or publishing to PSGallery. |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The description for CleanupPrereleases is misleading. According to the PR description and the code logic, CleanupPrereleases controls whether to delete old prerelease tags, not whether to "only perform cleanup without creating a new release". The cleanup can happen alongside publishing (when ReleaseType is Release) or independently (when ReleaseType is None). The description should be updated to clarify that it controls whether old prerelease tags are cleaned up.
| description: When enabled, only performs cleanup of old prerelease tags without creating a new release or publishing to PSGallery. | |
| description: When enabled, cleans up old prerelease tags after processing. This cleanup can run together with publishing a release (when ReleaseType is 'Release') or on its own when ReleaseType is 'None'. |
| default: 'true' | ||
| default: 'false' | ||
| AutoPatching: | ||
| description: Control wether to automatically handle patches. If disabled, the action will only create a patch release if the pull request has a 'patch' label. |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Spelling error: "wether" should be "whether" in the description.
|
|
||
| # Check if any version bump applies | ||
| $hasVersionBump = $majorRelease -or $minorRelease -or $patchRelease | ||
| if (-not $hasVersionBump) { |
Copilot
AI
Jan 18, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a potential bug when ReleaseType is 'None'. The code sets shouldPublish to false when there's no version bump (line 139), but it doesn't check whether ReleaseType is 'None' before checking for version bumps. However, when ReleaseType is 'None', no version bump is needed since no release is being created. The logic should skip the version bump check entirely when ReleaseType is 'None', or handle it differently to avoid misleading output.
| if (-not $hasVersionBump) { | |
| if ($shouldPublish -and -not $hasVersionBump) { |
…load-artifact action version
The action now supports explicit control over the release type through the new
ReleaseTypeinput parameter. TheAutoCleanupinput has been renamed toCleanupPrereleasesand cleanup is now handled independently from the release type.New ReleaseType input parameter
The
ReleaseTypeinput accepts the following values:ReleasePrereleaseNoneNote: The
Cleanupvalue has been removed. Cleanup is now controlled separately viaCleanupPrereleases.Renamed AutoCleanup to CleanupPrereleases
The
AutoCleanupinput has been renamed toCleanupPrereleasesfor clarity. This parameter now directly controls whether old prerelease tags should be cleaned up, independent of the release type.When
CleanupPrereleasesistrue, old prereleases will be deleted:Release)Nonebut cleanup is needed)Usage
The inputs work together with
Get-PSModuleSettingswhich pre-calculates both values:Backward compatibility
The
ReleaseTypeparameter defaults toRelease, maintaining current behavior for merged PRs targeting the default branch. TheCleanupPrereleasesparameter defaults tofalse(the caller is expected to provide the pre-calculated value).