Skip to content
Merged
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
13 changes: 12 additions & 1 deletion .github/actions/Publish-PSModule/src/publish.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,18 @@ LogGroup 'Publish to PSGallery' {
if ($whatIf) {
Write-Host "Publish-PSResource -Path $modulePath -Repository PSGallery -ApiKey ***"
} else {
$publishedPackage = Find-PSResource -Name $name -Version $publishPSVersion -Repository PSGallery -ErrorAction Stop
# A version that is not on the Gallery is the expected state for a new release, but PSResourceGet
# reports it as a PackageNotFound error, which -ErrorAction Stop turns into a throw. Only that error
# may be treated as 'not published'; any other failure (for example a Gallery outage) must stay fatal,
# otherwise a version that already exists would be re-published and fail the upload with a conflict.
$publishedPackage = $null
try {
$publishedPackage = Find-PSResource -Name $name -Version $publishPSVersion -Repository PSGallery -ErrorAction Stop
} catch {
if ($_.FullyQualifiedErrorId -notlike 'PackageNotFound,*') { throw }
Comment thread
MariusStorhaug marked this conversation as resolved.
Write-Host "$name $publishPSVersion is not on the PowerShell Gallery yet."
}

if ($publishedPackage) {
Write-Host (
"::notice title=♻️ Resuming Gallery-only publication::$name $publishPSVersion is already " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,13 @@ AfterAll {
foreach ($name in $script:environmentVariableNames) {
[System.Environment]::SetEnvironmentVariable($name, $script:originalEnvironment[$name])
}
Remove-Item -Path function:global:Find-PSResource -ErrorAction SilentlyContinue
Remove-Item -Path function:global:Publish-PSResource -ErrorAction SilentlyContinue
Remove-Item -Path function:global:Resolve-PSModuleDependency -ErrorAction SilentlyContinue
# Set-Item accepts 'function:global:X' and creates a function named 'X' in the global scope, but
# Remove-Item and Get-Item do not resolve that same path back to it, and fail silently rather than
# erroring. Removing by name is what actually deletes the shims; leaving them behind would shadow the
# real cmdlets for every test file that runs later in the session.
Remove-Item -Path 'Function:\Find-PSResource' -ErrorAction SilentlyContinue
Remove-Item -Path 'Function:\Publish-PSResource' -ErrorAction SilentlyContinue
Remove-Item -Path 'Function:\Resolve-PSModuleDependency' -ErrorAction SilentlyContinue
}

Describe 'Publish-PSModule recovery' {
Expand Down Expand Up @@ -68,20 +72,64 @@ Describe 'Publish-PSModule recovery' {
$env:PSMODULE_PUBLISH_PSMODULE_INPUT_PSGALLERY_API_KEY = 'test-key'
$env:PSMODULE_PUBLISH_PSMODULE_INPUT_PullRequest = ''
$env:PSMODULE_PUBLISH_PSMODULE_INPUT_WhatIf = 'false'
$script:publishInvoked = $false
# The publish script runs in its own scope, so a $script: flag set inside a shim never reaches the
# test. A hashtable captured by GetNewClosure() is shared by reference and records the call reliably.
# The closure captures local variables only, so $calls must be local here, not $script:-qualified.
$calls = @{ PublishInvoked = $false }
$script:calls = $calls

Set-Item -Path function:global:Resolve-PSModuleDependency -Value {}
Set-Item -Path function:global:Find-PSResource -Value {
[PSCustomObject]@{ Name = 'TestModule'; Version = '1.2.4' }
}
Set-Item -Path function:global:Publish-PSResource -Value {
$script:publishInvoked = $true
}
$calls.PublishInvoked = $true
}.GetNewClosure()
}

It 'skips Gallery publication when the resolved version already exists' {
{ & $script:publishScriptPath } | Should -Not -Throw

$script:publishInvoked | Should -BeFalse
$script:calls.PublishInvoked | Should -BeFalse
}

It 'publishes when the resolved version is not in the Gallery' {
Set-Item -Path function:global:Find-PSResource -Value {
[CmdletBinding()]
param(
[string] $Name,
[string] $Version,
[string] $Repository
)

# Mirrors how PSResourceGet reports an absent version: an error with the PackageNotFound error ID
# that honours -ErrorAction, so the shim reacts to -ErrorAction the same way the real cmdlet does.
Write-Error -Message "Package with name '$Name', version '$Version' could not be found in repository '$Repository'." `
-ErrorId 'PackageNotFound' -Category ObjectNotFound -TargetObject $Name
}

{ & $script:publishScriptPath } | Should -Not -Throw

$script:calls.PublishInvoked | Should -BeTrue
}

It 'fails without publishing when the Gallery lookup errors for another reason' {
Set-Item -Path function:global:Find-PSResource -Value {
[CmdletBinding()]
param(
[string] $Name,
[string] $Version,
[string] $Repository
)

# A transient Gallery failure carries a different error ID and must not be mistaken for
# 'version not published', otherwise an already-published version would be re-uploaded.
Write-Error -Message "Failed to find '$Name' '$Version' in repository '$Repository': Service Unavailable" `
-ErrorId 'HttpRequestCallFailure' -Category ResourceUnavailable -TargetObject $Name
}

{ & $script:publishScriptPath } | Should -Throw

$script:calls.PublishInvoked | Should -BeFalse
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ AfterAll {
foreach ($name in $script:environmentVariableNames) {
[System.Environment]::SetEnvironmentVariable($name, $script:originalEnvironment[$name])
}
Remove-Item -Path function:global:gh -ErrorAction SilentlyContinue
Remove-Item -Path function:global:git -ErrorAction SilentlyContinue
# Set-Item accepts 'function:global:X' and creates a function named 'X' in the global scope, but
# Remove-Item and Get-Item do not resolve that same path back to it, and fail silently rather than
# erroring. Removing by name is what actually deletes the shims; leaving them behind would shadow the
# real commands for every test file that runs later in the session.
Remove-Item -Path 'Function:\gh' -ErrorAction SilentlyContinue
Remove-Item -Path 'Function:\git' -ErrorAction SilentlyContinue
}

Describe 'Release-PSModule WhatIf' {
Expand Down
Loading