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
65 changes: 57 additions & 8 deletions .github/workflows/PublishModuleToPowerShellGallery.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,24 @@ jobs:
shell: bash
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VERSION: ${{ steps.version.outputs.version }}
run: |
if gh release view "v${{ steps.version.outputs.version }}" > /dev/null 2>&1; then
if gh release view "v$VERSION" > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "GitHub release v${{ steps.version.outputs.version }} already exists"
echo "GitHub release v$VERSION already exists"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "GitHub release v${{ steps.version.outputs.version }} does not exist"
echo "GitHub release v$VERSION does not exist"
fi

- name: Check if PSGallery Version Exists
id: check_psgallery
if: steps.check_release.outputs.exists == 'false'
shell: pwsh
env:
VERSION: ${{ steps.version.outputs.version }}
run: |
$version = "${{ steps.version.outputs.version }}"
$version = $env:VERSION
$published = Find-Module -Name ReScenePS -RequiredVersion $version -Repository PSGallery -ErrorAction SilentlyContinue
if ($published) {
Write-Host "PSGallery version $version already exists"
Expand All @@ -66,13 +69,59 @@ jobs:

- name: Create GitHub Release
if: steps.check_release.outputs.exists == 'false'
shell: bash
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REPOSITORY: ${{ github.repository }}
VERSION: ${{ steps.version.outputs.version }}
run: |
gh release create "v${{ steps.version.outputs.version }}" \
--title "v${{ steps.version.outputs.version }}" \
--generate-notes
$version = $env:VERSION

# Build release notes from this version's CHANGELOG.md section so the release
# body carries only the curated, user-facing entries (not the full PR list that
# --generate-notes produces, which is dominated by bot/CI/chore PRs).
# Read defensively: a missing/unreadable CHANGELOG.md must fall back to
# --generate-notes (below), never fail the publish.
$changelogLines = $null
if (Test-Path -LiteralPath './CHANGELOG.md') {
try {
$changelogLines = Get-Content -LiteralPath './CHANGELOG.md' -ErrorAction Stop
}
catch {
Write-Host "::warning::Could not read CHANGELOG.md ($($_.Exception.Message)); falling back to auto-generated notes."
}
}
$captured = [System.Collections.Generic.List[string]]::new()
if ($changelogLines) {
$headerPattern = '^##\s+\[' + [regex]::Escape($version) + '\]'
$capturing = $false
foreach ($line in $changelogLines) {
if (-not $capturing) {
if ($line -match $headerPattern) { $capturing = $true }
continue
}
if ($line -match '^##\s+\[') { break } # next version header ends the section
$captured.Add($line)
}
}
$body = ($captured -join "`n").Trim()

if ([string]::IsNullOrWhiteSpace($body)) {
Write-Host "::warning::No CHANGELOG.md section found for $version; falling back to auto-generated notes."
gh release create "v$version" --title "v$version" --generate-notes
}
else {
# Append a compare link against the most recent existing tag, excluding the
# current version's tag (which may already exist on a re-run).
$previousTag = git tag --list 'v*' --sort=-version:refname |
Where-Object { $_ -ne "v$version" } |
Select-Object -First 1
if ($previousTag) {
$body += "`n`n**Full Changelog**: https://github.com/$env:REPOSITORY/compare/$previousTag...v$version"
}
Set-Content -LiteralPath './release-notes.md' -Value $body -Encoding utf8
gh release create "v$version" --title "v$version" --notes-file './release-notes.md'
}

- name: Publish to PSGallery
if: steps.check_release.outputs.exists == 'false' && steps.check_psgallery.outputs.exists == 'false'
Expand Down
5 changes: 5 additions & 0 deletions build.depend.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
'PSScriptAnalyzer' = @{
Version = '1.24.0'
}
# Parses CHANGELOG.md (Keep a Changelog format) so the Publish task can populate the
# built manifest's PSData.ReleaseNotes from the matching version's entry.
Comment thread
tablackburn marked this conversation as resolved.
'ChangelogManagement' = @{
Version = '3.1.0'
}
'PlexAutomationToolkit' = @{
Version = '0.6.3'
}
Expand Down
55 changes: 55 additions & 0 deletions build.psake.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,60 @@ Task -Name 'DownloadTestTools' -Description 'Download test dependencies (UnRAR)'
}
}

# Populate the built manifest's ReleaseNotes from the matching CHANGELOG.md entry so the
# PowerShell Gallery release-notes panel shows the curated, user-facing notes (the same
# content used for the GitHub release) instead of just a link. Depends on Build so the
# staged manifest in ModuleOutDir exists; runs before Publish (see $PSBPublishDependency
# below). Non-fatal at every step so a release is never blocked.
Task -Name 'UpdateReleaseNotes' -Depends 'Build' -Description 'Set built manifest ReleaseNotes from the matching CHANGELOG.md entry' {
$changelogPath = Join-Path -Path $PSScriptRoot -ChildPath 'CHANGELOG.md'
if (-not (Test-Path -Path $changelogPath)) {
Write-Warning 'CHANGELOG.md not found; leaving ReleaseNotes unchanged.'
return
}

$moduleVersion = $PSBPreference.General.ModuleVersion
try {
Import-Module -Name 'ChangelogManagement' -ErrorAction Stop
$changelogData = Get-ChangelogData -Path $changelogPath -ErrorAction Stop
}
catch {
Write-Warning "Could not read CHANGELOG.md ($($_.Exception.Message)); leaving ReleaseNotes unchanged."
return
}

$releaseEntry = $changelogData.Released |
Where-Object { [string]$_.Version -eq [string]$moduleVersion } |
Select-Object -First 1
if (-not $releaseEntry) {
Write-Warning "No CHANGELOG.md entry found for version $moduleVersion; leaving ReleaseNotes unchanged."
return
}

$releaseNotes = $releaseEntry.RawData.Trim()
if ([string]::IsNullOrWhiteSpace($releaseNotes)) {
Write-Warning "CHANGELOG.md entry for version $moduleVersion is empty; leaving ReleaseNotes unchanged."
return
}
$builtManifest = Join-Path -Path $PSBPreference.Build.ModuleOutDir -ChildPath "$($PSBPreference.General.ModuleName).psd1"
if (-not (Test-Path -Path $builtManifest)) {
Write-Warning "Built manifest not found at '$builtManifest'; leaving ReleaseNotes unchanged."
return
}
try {
Update-ModuleManifest -Path $builtManifest -ReleaseNotes $releaseNotes -ErrorAction Stop
Write-Host " Set ReleaseNotes on built manifest from CHANGELOG [$($releaseEntry.Version)] ($($releaseNotes.Length) chars)" -ForegroundColor Gray
}
catch {
# Keep publishing unblocked: a failure here just leaves the manifest's existing
# ReleaseNotes in place rather than aborting the release.
Write-Warning "Failed to set ReleaseNotes on the built manifest '$builtManifest' ($($_.Exception.Message)); leaving it unchanged."
}
}

# Inject ReleaseNotes into the built manifest before publishing (PowerShellBuild's Publish
# defaults to depending only on 'Test').
$PSBPublishDependency = @('Test', 'UpdateReleaseNotes')

# Import the Test task from PowerShellBuild (uses $PSBTestDependency which includes Pester and Analyze)
Task -Name 'Test' -FromModule 'PowerShellBuild' -MinimumVersion '0.7.3'
Loading