This document describes how to publish the ColorScripts-Enhanced PowerShell module to different package galleries.
- PowerShell 5.1 or later (PowerShell 7.4 recommended)
- PowerShellGet 2.2+ or PSResourceGet 1.0+
- A GitHub personal access token (PAT) if pushing to GitHub Packages (use Package
read:packages/write:packagesscopes) - API keys for public repositories (PowerShell Gallery / NuGet.org)
- The module manifest uses a date-based version (
yyyy.MM.dd.HHmm). - When publishing a public build, ensure the manifest
ModuleVersionmatches the release tag. - Update the version automatically using
build.ps1 -Version <value>or viaUpdate-ModuleManifest.
The .github/workflows/publish.yml workflow automates the entire publish process:
- Build & Test - Runs ScriptAnalyzer and Pester tests
- Package - Creates the
.nupkgfile - Normalize Metadata - Embeds README, LICENSE, and icon; sets licenseUrl
- Generate Release Notes - Uses git-cliff to create changelog from commits
- Create GitHub Release - Publishes release with:
- git-cliff generated changelog in release body
.nupkgfile attached as release asset- Automatic version tagging
- Publish to Galleries - Pushes to PowerShell Gallery, NuGet.org, and GitHub Packages
The workflow can be triggered:
- Manually via
workflow_dispatchwith customizable options - Automatically when tests pass on the main branch
When manually triggering the publish workflow, you can control:
publishToNuGet- Publish to NuGet.org (default: true)publishToGitHub- Publish to GitHub Packages (default: true)versionOverride- Override the manifest versioncreateRelease- Create a GitHub release (default: true)
The workflow installs git-cliff automatically and generates release notes for the current version, which are then displayed in the GitHub release.
The PowerShell Gallery is built on top of NuGet feeds. Publishing to the Gallery or to NuGet.org uses the same API key.
# Publish to the PowerShell Gallery (NuGet.org)
Publish-Module -Path ./ColorScripts-Enhanced -NuGetApiKey $env:PSGALLERY_API_KEY -VerbosePowerShellGet versions prior to 2.2.6 do not embed README or license assets automatically. When you stage the package locally with Publish-Module (for example by targeting a temporary repository), run the metadata normalizer before pushing:
pwsh -NoProfile -File ./scripts/Update-NuGetPackageMetadata.ps1 -PackagePath 'C:\path\to\ColorScripts-Enhanced.<version>.nupkg'
dotnet nuget push 'C:\path\to\ColorScripts-Enhanced.<version>.nupkg' --api-key $env:PSGALLERY_API_KEY --source https://www.powershellgallery.com/api/v2/packageThe GitHub publish workflow runs this script automatically.
Note: NuGet.org expects packages that declare the
Unlicenselicense expression to also exposehttps://licenses.nuget.org/UnlicensevialicenseUrl. The normalization script sets this automatically so older NuGet clients render the license correctly.
- Create an account at https://www.powershellgallery.com.
- Generate an API key from your profile.
- Store the key securely (e.g., GitHub secret
PSGALLERY_API_KEY). - Ensure
README.mdis present in the module root (ColorScripts-Enhanced/README.md). The metadata normalization script bundles this file (along withLICENSEand the icon) into the staged.nupkgprior to publishing.
# Verify manifest
Test-ModuleManifest .\ColorScripts-Enhanced\ColorScripts-Enhanced.psd1
# Run automated tests
pwsh -NoProfile -Command "Invoke-Pester -Path ./Tests"
# Run lint (treat warnings as errors)
pwsh -NoProfile -Command "& .\scripts\Lint-Module.ps1" -IncludeTests -TreatWarningsAsErrors
# Apply auto-fixable ScriptAnalyzer rules (optional)
pwsh -NoProfile -Command "& .\scripts\Lint-Module.ps1" -Fix
# Verify Nerd Font glyphs render correctly
Show-ColorScript -Name nerd-font-test| Purpose | Local Var | GitHub Secret |
|---|---|---|
| PowerShell Gallery / NuGet.org API key | $env:PSGALLERY_API_KEY or $env:NUGET_API_KEY |
PSGALLERY_API_KEY / NUGET_API_KEY |
| GitHub Packages PAT | $env:PACKAGES_TOKEN |
PACKAGES_TOKEN |
GitHub Packages provides a private or public NuGet feed.
$owner = 'Nick2bad4u'
$source = "https://nuget.pkg.github.com/$owner/index.json"
Register-PSRepository -Name GitHub -SourceLocation $source -PublishLocation $source -InstallationPolicy Trusted -PackageManagementProvider NuGet
Publish-Module -Path ./ColorScripts-Enhanced -NuGetApiKey $env:PACKAGES_TOKEN -Repository GitHub
> **Tip:** When you stage the package locally before pushing to GitHub Packages, run `Update-NuGetPackageMetadata.ps1` against the resulting `.nupkg` so the README, license, and icon are embedded.$source = "https://nuget.pkg.github.com/Nick2bad4u/index.json"
Register-PSRepository -Name ColorScriptsEnhanced-GitHub -SourceLocation $source -InstallationPolicy Trusted -PackageManagementProvider NuGet
Install-Module -Name ColorScripts-Enhanced -Repository ColorScriptsEnhanced-GitHubFor enterprise environments you can host the module in Azure Artifacts or any NuGet-compatible feed:
Register-PSRepository -Name MyCompanyFeed -SourceLocation 'https://pkgs.dev.azure.com/<org>/<project>/_packaging/<feed>/nuget/v2' -InstallationPolicy Trusted -Credential (Get-Credential)
Publish-Module -Path ./ColorScripts-Enhanced -Repository MyCompanyFeed
> **Tip:** Normalize staged packages with `Update-NuGetPackageMetadata.ps1` before pushing them to your private feed to ensure gallery-friendly metadata.- Refresh release notes with
npm run release:notes(PowerShell Gallery snippet) and sync the changelog withnpm run release:verify(requiresgit-cliff). - Update the changelog (
CHANGELOG.md) and release notes (RELEASENOTES.md) if additional polish is needed. - Run
Test-Module.ps1locally (includes lint step). - Run
Lint-Module.ps1 -IncludeTests -TreatWarningsAsErrorsif not already covered. - Commit and push changes.
- Create a GitHub release with tag matching the manifest version (e.g.,
v2025.10.09.1700). - Trigger the Publish GitHub Actions workflow via release or manual dispatch.
- Confirm module availability in the target gallery.
- Version conflict: Increment
ModuleVersionif a package with the same version exists. - Authentication failure: Regenerate API token and check secrets configuration.
- Missing dependencies: Ensure PowerShellGet/PSResourceGet is updated on host machine.
- Changelog mismatch: Always update documentation before publishing.
- All tests pass (
npm run verify) - Linting clean (
npm run lint) - Documentation updated
- Version bumped (
.psd1manifest) - CHANGELOG.md updated
- Release notes generated
- Tested locally on Windows/Mac/Linux
# Test manifest
Test-ModuleManifest -Path ColorScripts-Enhanced/ColorScripts-Enhanced.psd1
# Verify module loads
Remove-Module ColorScripts-Enhanced -Force -ErrorAction SilentlyContinue
Import-Module ./ColorScripts-Enhanced/ColorScripts-Enhanced.psd1 -Verbose
# Check all commands export
Get-Command -Module ColorScripts-Enhanced | Select-Object Name# Using automatic publish workflow (recommended)
# Trigger via GitHub Actions interface or:
gh workflow run publish.yml --ref main
# Manual packaging (optional)
Compress-Archive -Path "./ColorScripts-Enhanced" -DestinationPath "./dist/ColorScripts-Enhanced-v1.0.0.zip"# PowerShell Gallery (simulate)
Save-Module -Name ColorScripts-Enhanced -Path "./test-install"
# Test load
Import-Module "./test-install/ColorScripts-Enhanced"
# Verify functionality
Show-ColorScript -Name bars
Get-ColorScriptList# Publish via GitHub Actions (automatic)
# OR manually if needed:
$nugetApiKey = Read-Host "Enter NuGet API key" -AsSecureString
$nugetApiKeyPlain = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto(
[System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($nugetApiKey)
)
Publish-Module -Path "./ColorScripts-Enhanced" `
-NuGetApiKey $nugetApiKeyPlain `
-Repository PSGallery# Should appear in PowerShell Gallery after 5-10 minutes
Find-Module -Name ColorScripts-Enhanced# Publish directly to NuGet
dotnet nuget push "./dist/ColorScripts-Enhanced.*.nupkg" `
-k $nugetApiKey `
-s https://api.nuget.org/v3/index.json# Register GitHub package source
$owner = 'Nick2bad4u'
$source = "https://nuget.pkg.github.com/$owner/index.json"
Register-PSRepository -Name ColorScriptsEnhanced-GitHub `
-SourceLocation $source `
-PublishLocation $source `
-InstallationPolicy Trusted
# Publish
Publish-Module -Path "./ColorScripts-Enhanced" `
-Repository ColorScriptsEnhanced-GitHub `
-NuGetApiKey $githubTokenThe .github/workflows/publish.yml workflow:
- Validates - Runs smoke tests and linting
- Builds - Creates .nupkg package
- Normalizes - Embeds README, LICENSE, icon
- Generates - Creates changelog using git-cliff
- Releases - Creates GitHub release with changelog
- Publishes - Pushes to configured galleries
# Via GitHub CLI
gh workflow run publish.yml
# With options
gh workflow run publish.yml `
-f publishToNuGet=true `
-f publishToGitHub=true `
-f createRelease=true `
-f versionOverride="2025.10.30.1200"
# Check status
gh run list --workflow=publish.ymlFormat: yyyy.MM.dd.HHmm
Example: 2025.10.30.1247
# Generate version automatically
$version = (Get-Date -Format "yyyy.MM.dd.HHmm")
Write-Host "Version: $version"# Method 1: Direct update
$manifestPath = "./ColorScripts-Enhanced/ColorScripts-Enhanced.psd1"
$version = "2025.10.30.1247"
Update-ModuleManifest -Path $manifestPath -ModuleVersion $version
# Method 2: Via build script
.\scripts\build.ps1 -Version $version# Generate release notes for latest version
npx git-cliff --unreleased
# Generate for specific version
npx git-cliff --tag v2025.10.30
# Generate full changelog
npx git-cliff --latest > CHANGELOG.md
# Validate changelog
npm run release:verify# Wait 5-10 minutes for gallery sync
# Check PowerShell Gallery
Find-Module -Name ColorScripts-Enhanced | Select-Object Version
# Test installation
Install-Module -Name ColorScripts-Enhanced -Force -Verbose
# Verify functionality
Import-Module ColorScripts-Enhanced
Show-ColorScript- Update GitHub releases page
- Post to PowerShell community forums
- Update project website
- Announce on social media (optional)
- Update documentation links
Issue: Module won't publish to gallery
# Check manifest syntax
Test-ModuleManifest -Path ./ColorScripts-Enhanced/ColorScripts-Enhanced.psd1
# Validate version format
# Should be: Major.Minor.Patch or date-based (2025.10.30)
# NOT: year.month.day.minute with too many parts
# Correct format if needed
Update-ModuleManifest -Path ./ColorScripts-Enhanced/ColorScripts-Enhanced.psd1 `
-ModuleVersion "2025.10.30"Issue: "Already published" error
# Increment version and retry
Update-ModuleManifest -Path ./ColorScripts-Enhanced/ColorScripts-Enhanced.psd1 `
-ModuleVersion "2025.10.31"# Check PowerShell Gallery stats
# https://www.powershellgallery.com/packages/ColorScripts-Enhanced
# Track downloads programmatically
$info = Invoke-RestMethod -Uri "https://www.powershellgallery.com/api/v2/Packages?`$filter=Id eq 'ColorScripts-Enhanced'" -ErrorAction SilentlyContinue
$info.Entry | Select-Object Title, Version, @{N='Downloads'; E={$_.Properties.DownloadCount}}# Monitor GitHub issues for post-release problems
gh issue list --label "v2025.10.30" --state open
# Track bug reports
gh issue list --label "bug" --state open- PowerShell Gallery Publishing Docs: https://learn.microsoft.com/en-us/powershell/gallery/how-to/publishing-packages/publishing-a-package?view=powershellget-3.x
- PSResourceGet Guide: https://learn.microsoft.com/en-us/powershell/gallery/overview?view=powershellget-3.x
- GitHub Packages with PowerShell: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-nuget-registry