Skip to content

ci(release): build release notes from CHANGELOG; auto-populate PSData.ReleaseNotes; harden version expansion#31

Merged
tablackburn merged 4 commits into
mainfrom
ci/release-tooling-from-changelog
May 20, 2026
Merged

ci(release): build release notes from CHANGELOG; auto-populate PSData.ReleaseNotes; harden version expansion#31
tablackburn merged 4 commits into
mainfrom
ci/release-tooling-from-changelog

Conversation

@tablackburn
Copy link
Copy Markdown
Owner

@tablackburn tablackburn commented May 20, 2026

Summary

Ports the release-tooling improvements developed in ScheduledTasksManager into the template, so every module scaffolded from it inherits them. Three changes, all in the bundled build/publish files (no module/source changes).

1. GitHub release notes from CHANGELOG.md (replaces --generate-notes)

Create GitHub Release now extracts the published version's section from CHANGELOG.md and passes it via --notes-file (in pwsh). --generate-notes lists every merged PR since the last release tag — between version bumps that's dominated by dependabot/pre-commit/CI/chore PRs and buries the actual user-facing changes. Includes a Full Changelog compare link and falls back to --generate-notes if a version has no changelog section (a release is never blocked).

2. Auto-populate PSData.ReleaseNotes at publish (PowerShell Gallery)

  • build.depend.psd1: add ChangelogManagement 3.1.0.
  • build.psake.ps1: new UpdateReleaseNotes task (-Depends 'Build') that reads the entry matching the module version via Get-ChangelogData and sets the built manifest's PrivateData.PSData.ReleaseNotes via Update-ModuleManifest. Wired in through $PSBPublishDependency = @('Test', 'UpdateReleaseNotes') so it runs before Publish-PSBuildModule. Non-fatal if the changelog can't be read or lacks an entry for the version.

So a scaffolded module's Gallery release-notes panel shows the same curated notes as its GitHub release, both sourced from CHANGELOG.md.

3. Harden version expansion in the publish workflow

Pass ${{ steps.version.outputs.version }} via env: (VERSION) in the Check if Release Exists, Check if PSGallery Version Exists, and Create GitHub Release steps instead of inlining it into run: scripts. Inline template expansion is substituted into the script text before the shell runs (the template-injection class zizmor/CodeRabbit flag); env vars are read at runtime. This removed all six inline expansions.

Notes / verification

  • CalVer caveat resolved: scaffolded modules use SemVer (CHANGELOG.template.md## [0.1.0], "adheres to Semantic Versioning"), the exact format validated end-to-end in ScheduledTasksManager. The template's own CalVer CHANGELOG.md is only for the template repo, which never runs the publish path (guarded against the un-initialized placeholder).
  • The build wiring mirrors the proven STM approach; the template can't self-build (placeholder {{ModuleName}} manifest), so the publish-time path was validated in STM rather than here.
  • Workflow YAML parses; no inline ${{ }} remain in any run: block body.

Part of propagating these patterns to the ~6 existing template consumers (separate PRs to follow).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Updated GitHub release workflow to extract version-specific release notes from CHANGELOG.md, with automatic fallback to generated notes for missing entries
    • Enhanced module publishing pipeline to automatically populate the module manifest's release notes from the corresponding changelog entry, improving consistency across platforms

Review Change Stack

tablackburn and others added 2 commits May 20, 2026 18:45
…pansion

Ports the ScheduledTasksManager release-tooling improvements into the template so
every module scaffolded from it inherits them.

- Create GitHub Release: extract the published version's section from CHANGELOG.md
  and pass it via --notes-file (in pwsh), instead of --generate-notes. The latter
  lists every merged PR since the last release tag, which between version bumps is
  dominated by bot/CI/chore PRs and buries the actual user-facing changes. Includes
  a Full Changelog compare link and falls back to --generate-notes if a version has
  no changelog section (so a release is never blocked).
- Pass the version output via env (VERSION) in the 'Check if Release Exists',
  'Check if PSGallery Version Exists', and 'Create GitHub Release' steps instead of
  inlining ${{ steps.version.outputs.version }} into the run scripts. Inline
  template expansion is substituted into the script text before the shell runs (a
  template-injection vector zizmor/CodeRabbit flag); env vars are read at runtime.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
So a scaffolded module's PowerShell Gallery release-notes panel shows the curated,
user-facing notes for each version (matching the GitHub release body) instead of a
static CHANGELOG link.

- build.depend.psd1: add ChangelogManagement 3.1.0 (Keep a Changelog parser).
- build.psake.ps1: new UpdateReleaseNotes task (Depends Build) that reads the entry
  matching the module version via Get-ChangelogData and sets the built manifest's
  PrivateData.PSData.ReleaseNotes via Update-ModuleManifest. Wired in via
  $PSBPublishDependency so it runs before Publish-PSBuildModule. Non-fatal if the
  changelog can't be read or has no entry for the version.

Mirrors the DSC Community Sampler pattern. Scaffolded modules use SemVer Keep a
Changelog (CHANGELOG.template.md), the format this was validated against in
ScheduledTasksManager. The template repo itself never runs this path (its publish
is guarded against the un-initialized placeholder).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 20, 2026 22:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 20, 2026

Warning

Rate limit exceeded

@tablackburn has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 56 minutes and 38 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: aed536bd-4cc6-4b80-9852-86da8e5d183c

📥 Commits

Reviewing files that changed from the base of the PR and between f4607e8 and 1ba3532.

📒 Files selected for processing (1)
  • .github/workflows/PublishModuleToPowerShellGallery.yaml
📝 Walkthrough

Walkthrough

The PR integrates changelog-driven release notes into the module publishing pipeline. A new ChangelogManagement module dependency is added to support parsing CHANGELOG.md. A new UpdateReleaseNotes psake task extracts the matching version section and injects it into the built module manifest, executed during the build phase before publishing. The GitHub Actions workflow is updated to check release existence using an explicit VERSION variable and to generate release notes by parsing CHANGELOG.md, with fallback to automatic note generation if no matching section exists.

Changes

Changelog-Driven Release Notes

Layer / File(s) Summary
Changelog Module and Build Task
build.depend.psd1, build.psake.ps1
ChangelogManagement v3.1.0 dependency is added. UpdateReleaseNotes task reads CHANGELOG.md, extracts the current version's release notes, and updates the built manifest; warnings are logged if the changelog is missing, unreadable, or has no matching entry. Publish task is configured to depend on UpdateReleaseNotes to ensure notes are injected before publishing.
GitHub Release Workflow
.github/workflows/PublishModuleToPowerShellGallery.yaml
Release existence is checked using an explicit VERSION environment variable. Release creation now parses CHANGELOG.md for the matching version section; when found and non-empty, notes are curated (with optional "Full Changelog" compare link) and written to release-notes.md. Release is created using --notes-file or falls back to --generate-notes if the changelog section is absent or empty.

🎯 3 (Moderate) | ⏱️ ~20 minutes

🐰 A changelog now guides the way,
From local builds to GitHub display,
Release notes flow with the version's release,
Each publish brings documented peace! 📝✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes all three main changes: building release notes from CHANGELOG, auto-populating PSData.ReleaseNotes, and hardening version expansion.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/release-tooling-from-changelog

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR ports release/publish tooling improvements into the template so scaffolded modules can (1) generate GitHub release bodies from the matching CHANGELOG.md section and (2) inject changelog-derived release notes into the built module manifest prior to publishing, while (3) avoiding inline ${{ }} expansions in workflow run: blocks by passing the version via environment variables.

Changes:

  • Add a psake task to derive ReleaseNotes from CHANGELOG.md and update the built manifest before publishing.
  • Add ChangelogManagement as a build dependency to parse Keep a Changelog formatted entries.
  • Update the publish workflow to build GitHub release notes from CHANGELOG.md (with fallback) and harden version usage via env:.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
build.psake.ps1 Adds UpdateReleaseNotes task and wires it into publish dependencies.
build.depend.psd1 Adds ChangelogManagement dependency used to parse CHANGELOG.md.
.github/workflows/PublishModuleToPowerShellGallery.yaml Uses env-provided VERSION and builds GitHub release notes from CHANGELOG.md with fallback behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread build.depend.psd1
Comment thread build.psake.ps1
Comment thread .github/workflows/PublishModuleToPowerShellGallery.yaml Outdated
…view)

Addresses Copilot review on #31:
- UpdateReleaseNotes: if the matched CHANGELOG entry is empty/whitespace, warn and
  leave ReleaseNotes unchanged rather than overwriting the built manifest with an
  empty string.
- Create GitHub Release: read CHANGELOG.md defensively (Test-Path + try/catch). A
  missing or unreadable file now falls back to --generate-notes instead of failing
  the publish (GitHub's pwsh runs with $ErrorActionPreference = 'Stop').

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/PublishModuleToPowerShellGallery.yaml:
- Around line 136-138: The $previousTag selection can return the current tag
causing the compare link to point to itself; update the assignment that sets
$previousTag (currently using git tag --list 'v*' --sort=-version:refname) to
exclude the current tag name "v$version" from the results (e.g., filter out
entries equal to "v$version" before Select-Object) so $previousTag always points
to the last other tag used when constructing the compare URL that uses
$previousTag and $version.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d67d8c23-e95d-4fe0-99fe-9bf28645936e

📥 Commits

Reviewing files that changed from the base of the PR and between ec17dd4 and f4607e8.

📒 Files selected for processing (3)
  • .github/workflows/PublishModuleToPowerShellGallery.yaml
  • build.depend.psd1
  • build.psake.ps1

Comment thread .github/workflows/PublishModuleToPowerShellGallery.yaml Outdated
Addresses CodeRabbit review on #31: if a v$version tag already exists (e.g. a
re-run, or a tag pushed without a release), the previous-tag selection could pick
it and produce a self-referential Full Changelog compare link. Filter out
"v$version" before selecting the most recent tag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants