Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
description: A comma separated list of labels that do not trigger a release.
required: false
default: NoRelease
ReleaseType:
description: The type of release to create. Values are 'Release' (stable), 'Prerelease', or 'None'.
required: false
default: Release
WhatIf:
description: If specified, the action will only log the changes it would make, but will not actually create or delete any releases or tags.
required: false
Expand Down Expand Up @@ -76,24 +80,55 @@
- name: Install-PSModuleHelpers
uses: PSModule/Install-PSModuleHelpers@d60d63e4be477d1ca0c67c6085101fb109bce8f1 # v1.0.6

- name: Run Publish-PSModule
- name: Update Microsoft.PowerShell.PSResourceGet
shell: pwsh
run: |
Install-PSResource -Name Microsoft.PowerShell.PSResourceGet -Repository PSGallery -TrustRepository

- name: Initialize Publish Context
id: init
shell: pwsh
working-directory: ${{ inputs.WorkingDirectory }}
env:
PSMODULE_PUBLISH_PSMODULE_INPUT_Name: ${{ inputs.Name }}
PSMODULE_PUBLISH_PSMODULE_INPUT_ModulePath: ${{ inputs.ModulePath }}
PSMODULE_PUBLISH_PSMODULE_INPUT_APIKey: ${{ inputs.APIKey }}
PSMODULE_PUBLISH_PSMODULE_INPUT_AutoCleanup: ${{ inputs.AutoCleanup }}
PSMODULE_PUBLISH_PSMODULE_INPUT_AutoPatching: ${{ inputs.AutoPatching }}
PSMODULE_PUBLISH_PSMODULE_INPUT_DatePrereleaseFormat: ${{ inputs.DatePrereleaseFormat }}
PSMODULE_PUBLISH_PSMODULE_INPUT_IgnoreLabels: ${{ inputs.IgnoreLabels }}
PSMODULE_PUBLISH_PSMODULE_INPUT_ReleaseType: ${{ inputs.ReleaseType }}
PSMODULE_PUBLISH_PSMODULE_INPUT_IncrementalPrerelease: ${{ inputs.IncrementalPrerelease }}
PSMODULE_PUBLISH_PSMODULE_INPUT_MajorLabels: ${{ inputs.MajorLabels }}
PSMODULE_PUBLISH_PSMODULE_INPUT_MinorLabels: ${{ inputs.MinorLabels }}
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

Potential code injection in
${ github.action_path }
, which may be controlled by an external user.

Copilot Autofix

AI about 2 hours ago

To fix the issue, avoid expanding ${{ github.action_path }} directly in the run: command. Instead, assign it to an environment variable in the step’s env: block and have PowerShell read that variable using $ENV:VAR (or $VAR if defined as a PowerShell variable). This follows the recommended pattern: expression → env var → shell‑native reference.

Concretely, in the “Initialize Publish Context” step (lines 88–105), we will:

  • Add a new environment variable, e.g. PSMODULE_ACTION_PATH: ${{ github.action_path }}.
  • Change run: ${{ github.action_path }}/scripts/init.ps1 to a script block that invokes the script via that environment variable: run: | followed by & "$ENV:PSMODULE_ACTION_PATH/scripts/init.ps1".

This keeps existing functionality (we still run the same script in the same directory), but removes the expression from the run: line. No new imports or external dependencies are needed.

Suggested changeset 1
action.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/action.yml b/action.yml
--- a/action.yml
+++ b/action.yml
@@ -102,7 +102,9 @@
         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
+        PSMODULE_ACTION_PATH: ${{ github.action_path }}
+      run: |
+        & "$ENV:PSMODULE_ACTION_PATH/scripts/init.ps1"
 
     - name: Download module artifact
       if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
EOF
@@ -102,7 +102,9 @@
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
PSMODULE_ACTION_PATH: ${{ github.action_path }}
run: |
& "$ENV:PSMODULE_ACTION_PATH/scripts/init.ps1"

- name: Download module artifact
if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
Copilot is powered by AI and may make mistakes. Always verify output.

- name: Download module artifact
if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: module
path: ${{ inputs.ModulePath }}
Comment on lines +107 to +112
Copy link

Copilot AI Jan 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential issue: The "Download module artifact" step only runs when PUBLISH_CONTEXT_ShouldPublish is true or WhatIf is true, but this artifact may also be needed for the cleanup step if cleanup happens independently. According to the PR description, cleanup can happen when ReleaseType is 'None' but CleanupPrereleases is true. However, cleanup.ps1 doesn't appear to need the module artifact, so this is likely correct. Consider adding a comment to clarify that the artifact is only needed for publishing operations.

Copilot uses AI. Check for mistakes.

- name: Publish Module
if: env.PUBLISH_CONTEXT_ShouldPublish == 'true' || inputs.WhatIf == 'true'
shell: pwsh
working-directory: ${{ inputs.WorkingDirectory }}
env:
PSMODULE_PUBLISH_PSMODULE_INPUT_Name: ${{ inputs.Name }}
PSMODULE_PUBLISH_PSMODULE_INPUT_ModulePath: ${{ inputs.ModulePath }}
PSMODULE_PUBLISH_PSMODULE_INPUT_APIKey: ${{ inputs.APIKey }}
PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf: ${{ inputs.WhatIf }}
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/main.ps1
run: ${{ github.action_path }}/scripts/publish.ps1

Check warning

Code scanning / CodeQL

Code injection Medium

Potential code injection in
${ github.action_path }
, which may be controlled by an external user.

Copilot Autofix

AI about 2 hours 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.


- name: Cleanup Prereleases
if: env.PUBLISH_CONTEXT_ShouldCleanup == 'true' || inputs.WhatIf == 'true'
shell: pwsh
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

Potential code injection in
${ github.action_path }
, which may be controlled by an external user.

Copilot Autofix

AI about 2 hours ago

In general, to fix this class of problem in GitHub Actions, avoid using ${{ ... }} expressions directly inside run: or script: bodies when they might involve untrusted or tool-flagged values. Instead, assign the expression to an environment variable using the env: section, then refer to it using the native syntax of the shell (e.g., $VAR in Bash, $env:VAR in PowerShell). This prevents unintended parsing or injection by making the shell see it as a single argument value.

For this specific case in action.yml, we should (1) introduce an environment variable (e.g., ACTION_PATH) whose value is ${{ github.action_path }}, and (2) update the run: commands of the affected steps to call the PowerShell scripts using $env:ACTION_PATH rather than the expression interpolation. This change preserves the existing functionality (scripts still run from the same directory) while removing the direct use of the GitHub expression in run: which CodeQL is complaining about. We only touch the shown steps: “Publish Module” and “Cleanup Prereleases” (the latter is where CodeQL reported the issue, but for consistency we’ll fix both).

Concretely:

  • In the Publish Module step (lines 114–126), add ACTION_PATH: ${{ github.action_path }} to the env: map, and change run: ${{ github.action_path }}/scripts/publish.ps1 to run: $env:ACTION_PATH/scripts/publish.ps1.
  • In the Cleanup Prereleases step (lines 128–134), similarly add ACTION_PATH: ${{ github.action_path }} to env:, and change run: ${{ github.action_path }}/scripts/cleanup.ps1 to run: $env:ACTION_PATH/scripts/cleanup.ps1.

PowerShell will expand $env:ACTION_PATH to the environment variable, and the script path remains equivalent to what it was previously.

Suggested changeset 1
action.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/action.yml b/action.yml
--- a/action.yml
+++ b/action.yml
@@ -116,6 +116,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 +124,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
EOF
@@ -116,6 +116,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 +124,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
Copilot is powered by AI and may make mistakes. Always verify output.
49 changes: 49 additions & 0 deletions scripts/cleanup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
[CmdletBinding()]
param()

#region Load context from environment
$prereleaseName = $env:PUBLISH_CONTEXT_PrereleaseName
$prereleaseTagsToCleanup = $env:PUBLISH_CONTEXT_PrereleaseTagsToCleanup
$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.'
Copy link

Copilot AI Jan 18, 2026

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).

Suggested change
Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run main.ps1 first.'
Write-Error 'PUBLISH_CONTEXT_PrereleaseName is not set. Run init.ps1 first.'

Copilot uses AI. Check for mistakes.
exit 1
}
#endregion Load context from environment

#region Cleanup prereleases
Set-GitHubLogGroup "Cleanup prereleases for [$prereleaseName]" {
if ([string]::IsNullOrWhiteSpace($prereleaseTagsToCleanup)) {
Write-Output "No prereleases found to cleanup for [$prereleaseName]."
return
}

$tagsToDelete = $prereleaseTagsToCleanup -split ',' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }

if ($tagsToDelete.Count -eq 0) {
Write-Output "No prereleases found to cleanup for [$prereleaseName]."
return
}

Write-Output "Found $($tagsToDelete.Count) prereleases to cleanup:"
$tagsToDelete | ForEach-Object { Write-Output " - $_" }
Write-Output ''

foreach ($tag in $tagsToDelete) {
Write-Output "Deleting prerelease: [$tag]"
if ($whatIf) {
Write-Output "WhatIf: gh release delete $tag --cleanup-tag --yes"
} else {
gh release delete $tag --cleanup-tag --yes
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to delete release [$tag]."
exit $LASTEXITCODE
}
Write-Output "Successfully deleted release [$tag]."
}
}

Write-Host "::notice::Cleaned up $($tagsToDelete.Count) prerelease(s) for [$prereleaseName]."
}
#endregion Cleanup prereleases
Loading
Loading