Publish-PwshCopilot.ps1
<#!
.SYNOPSIS Helper script to publish PwshCopilot to PowerShell Gallery safely. .DESCRIPTION Stages the module into a temporary versioned folder (ModuleName\<version>) so Publish-Module uses the intended manifest (avoids accidentally publishing an older installed copy when using -Name). Prompts securely for the NuGet API key if not supplied via parameter or environment variable NUGET_API_KEY. Optionally auto-bumps the patch version in the manifest before staging (-BumpPatch). .PARAMETER ApiKey Plain text NuGet API key (not recommended). Prefer environment variable or secure prompt. .PARAMETER BumpPatch Increment patch portion of ModuleVersion in manifest before staging/publishing. .EXAMPLE pwsh ./Publish-PwshCopilot.ps1 -BumpPatch .EXAMPLE $env:NUGET_API_KEY = '...' ; pwsh ./Publish-PwshCopilot.ps1 .NOTES Ensure you committed changes before publishing. After success, create a git tag (v<version>) if desired. #> [CmdletBinding(SupportsShouldProcess=$true)] param( [string] $ApiKey, [switch] $BumpPatch, [switch] $WhatIf ) $ErrorActionPreference = 'Stop' $manifestPath = Join-Path $PSScriptRoot 'PwshCopilot.psd1' if (-not (Test-Path $manifestPath)) { throw "Manifest not found at $manifestPath" } Write-Host "Loading manifest: $manifestPath" -ForegroundColor Cyan $manifest = Test-ModuleManifest -Path $manifestPath $currentVersion = [version]$manifest.ModuleVersion if ($BumpPatch) { $newVersion = [version]::new($currentVersion.Major, $currentVersion.Minor, $currentVersion.Build + 1) Write-Host "Bumping version $currentVersion -> $newVersion" -ForegroundColor Yellow (Get-Content $manifestPath) -replace "ModuleVersion\s*=\s*'${currentVersion}'","ModuleVersion = '$newVersion'" | Set-Content $manifestPath $manifest = Test-ModuleManifest -Path $manifestPath $currentVersion = [version]$manifest.ModuleVersion } Write-Host "Preparing staging folder for version $currentVersion" -ForegroundColor Cyan $stagingRoot = Join-Path ([IO.Path]::GetTempPath()) 'PwshCopilot_Stage' if (Test-Path $stagingRoot) { Remove-Item $stagingRoot -Recurse -Force } $moduleVersionFolder = Join-Path $stagingRoot (Join-Path 'PwshCopilot' $currentVersion.ToString()) New-Item -ItemType Directory -Path $moduleVersionFolder -Force | Out-Null # Files to copy $items = @('PwshCopilot.psd1','PwshCopilot.psm1','README.md','Private') foreach ($i in $items) { $src = Join-Path $PSScriptRoot $i if (Test-Path $src) { Write-Host "Copying $i" -ForegroundColor DarkGray Copy-Item $src -Destination $moduleVersionFolder -Recurse -Force } } # Remove gallery metadata file if present (regenerated automatically after publish) $psGetInfo = Join-Path $moduleVersionFolder 'PSGetModuleInfo.xml' if (Test-Path $psGetInfo) { Remove-Item $psGetInfo -Force } # Acquire API key securely if (-not $ApiKey) { $ApiKey = $env:NUGET_API_KEY } if (-not $ApiKey) { $sec = Read-Host 'Enter NuGet API Key' -AsSecureString $ApiKey = (New-Object System.Net.NetworkCredential('', $sec)).Password } if (-not $ApiKey) { throw 'NuGet API key not provided.' } Write-Host "Staged path: $moduleVersionFolder" -ForegroundColor Green if ($PSCmdlet.ShouldProcess("PwshCopilot $currentVersion","Publish to PowerShell Gallery")) { Publish-Module -Path $moduleVersionFolder -NuGetApiKey $ApiKey -Verbose Write-Host "Publish attempt complete. Verify with: Find-Module PwshCopilot -AllVersions | Sort-Object Version" -ForegroundColor Green } |