Skip to content

add automated changelog generation#236

Merged
Tzvonimir merged 5 commits intomainfrom
PC-472-alt
Jan 23, 2026
Merged

add automated changelog generation#236
Tzvonimir merged 5 commits intomainfrom
PC-472-alt

Conversation

@f-leu
Copy link
Contributor

@f-leu f-leu commented Jan 9, 2026

[Title]

📚 Description of Changes

Provide an overview of your changes and why they’re needed. Link to any related issues (e.g., "Fixes #123"). If your PR fixes a bug, resolves a feature request, or updates documentation, please explain how.

  • What Changed:
    (Describe the modifications, additions, or removals.)

  • Why This Change:
    (Explain the problem this PR addresses or the improvement it provides.)

  • Affected Components:
    (Which component does this change affect? - put x for all components)

  • Compose

  • K8s

  • Other (please specify)

❓ Motivation and Context

Why is this change required? What problem does it solve?

  • Context:
    (Provide background information or link to related discussions/issues.)

  • Relevant Tasks/Issues:
    (e.g., Fixes: #GitHub Issue)

🔍 Types of Changes

Indicate which type of changes your code introduces (check all that apply):

  • BUGFIX: Non-breaking fix for an issue.
  • NEW FEATURE: Non-breaking addition of functionality.
  • BREAKING CHANGE: Fix or feature that causes existing functionality to not work as expected.
  • ENHANCEMENT: Improvement to existing functionality.
  • CHORE: Changes that do not affect production (e.g., documentation, build tooling, CI).

🔬 QA / Verification Steps

Describe the steps a reviewer should take to verify your changes:

  1. (Step one: e.g., "Run make test to verify all tests pass.")
  2. (Step two: e.g., "Deploy to a Kind cluster with make create-kind && make deploy.")
  3. (Additional steps as needed.)

✅ Global Checklist

Please check all boxes that apply:

  • I have read and followed the CONTRIBUTING guidelines.
  • My code follows the code style of this project.
  • I have updated the documentation as needed.
  • I have added tests that cover my changes.
  • All new and existing tests have passed locally.
  • I have run this code in a local environment to verify functionality.
  • I have considered the security implications of this change.

Summary by CodeRabbit

  • Documentation

    • Added contributing guidance for changelog and release labeling, plus instructions for creating releases.
    • Added a CHANGELOG with "Keep a Changelog" boilerplate and auto-update guidance.
  • Chores

    • Enabled automated release notes generation with categorized sections (Added, Changed, Fixed, Removed, Security, Other).
    • Updated release workflow to determine tags, create releases with auto-generated notes, and auto-update/commit the changelog.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 9, 2026

Warning

Rate limit exceeded

@f-leu has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 22 minutes and 14 seconds before requesting another review.

⌛ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between fd4a083 and 9eb8ef5.

📒 Files selected for processing (1)
  • .github/workflows/create-tag-and-exit.yml
📝 Walkthrough

Walkthrough

Adds automated release and changelog management: new GitHub release configuration, updated release workflow to create Releases and auto-generate notes, changelog auto-update and commit steps, CONTRIBUTING guidance for changelog labels, and a new Keep a Changelog-style CHANGELOG.md. (50 words)

Changes

Cohort / File(s) Summary
Documentation
​.github/CONTRIBUTING.md, CHANGELOG.md
Added "Changelog and Release Labels" guidance in CONTRIBUTING.md and committed a Keep a Changelog boilerplate CHANGELOG.md with an auto-update note.
Release Configuration
​.github/release.yml
New release notes configuration mapping PR labels to changelog categories and excluding specific labels/authors for automated release note generation.
Release Workflow
​.github/workflows/create-tag-and-exit.yml
Workflow refactor: determine tag, create GitHub Release with auto-generated notes, assemble CHANGELOG.md from releases, and commit/push changelog back to main (with retry and git user setup).

Sequence Diagram(s)

sequenceDiagram
    participant WF as GitHub Workflow
    participant GH as GitHub Releases API
    participant FS as Repo (CHANGELOG.md)
    participant Git as Git remote

    WF->>WF: Determine NEW_TAG (input or computed)
    WF->>GH: Create Release with NEW_TAG & auto-generated notes
    GH-->>WF: Release created (tag, date, body)
    WF->>GH: Fetch releases list
    GH-->>WF: Return releases data
    WF->>FS: Build/Update CHANGELOG.md from releases data
    WF->>Git: Configure user & commit CHANGELOG.md if changed
    Git-->>WF: Commit successful
    WF->>Git: Push commit to main (with retry)
    Git-->>WF: Push complete
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • dray92

Poem

🐰 I nibble tags and stitch the log,

Notes hop out from label fog,
Releases sing in tidy rows,
CHANGELOG blooms as history grows,
A little hop — the pipeline flows.

🚥 Pre-merge checks | ✅ 4 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The linked issue #123 'cluster snapshot enum name fix' is unrelated to the changelog generation changes. The PR appears to address a different feature without proper linking to supporting issues. Link this PR to the relevant issue for automated changelog generation (e.g., PC-472) instead of or in addition to the unrelated cluster snapshot fix issue.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'add automated changelog generation' accurately reflects the main changes in the PR, which include automated changelog and release note generation through new workflow steps and configuration files.
Out of Scope Changes check ✅ Passed All changes are cohesively focused on automated changelog generation: documentation, release config, workflow updates, and CHANGELOG.md initialization. No extraneous modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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


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

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/create-tag-and-exit.yml (1)

27-28: Fix the fallback behavior in the tag pipeline.

The || echo "v0.0.0" fallback is ineffective because the exit code of the pipeline is determined by head -n1, which returns 0 (success) when receiving empty input from grep. Even though grep exits 1 when finding no matches, head succeeds, causing the pipeline to return 0 and leaving LAST_TAG empty instead of defaulting to v0.0.0.

Either add set -o pipefail to ensure the pipeline fails if any command fails, or use conditional logic to explicitly handle the no-tags case.

🤖 Fix all issues with AI agents
In @.github/workflows/create-tag-and-exit.yml:
- Around line 66-72: The push step "Commit and push CHANGELOG.md" can fail if
main advanced after checkout; update that step to pull and rebase before pushing
(e.g., run a git fetch && git pull --rebase origin main) and then attempt the
push, or add a retry/fallback that handles non-fast-forward errors by
fetching/rebasing and retrying the git push; ensure the step still only commits
when git diff --staged --quiet indicates changes and that any failed push
attempts surface a clear error if retries also fail.
- Around line 59-64: The loop parsing gh release list is fragile because it
relies on space-separated fields (tag title date status); replace it with gh
release list --limit 100 --json (e.g., tagName,name,publishedAt) and iterate the
JSON array so you can reliably extract tagName and publishedAt (use publishedAt
for date formatting) and then call gh release view --json body -q '.body' for
the body; update the loop to read these JSON fields (instead of using read tag
title date status) and append the formatted header and body to CHANGELOG.md to
avoid misaligned parsing when titles contain spaces.
- Around line 49-56: The heredoc used by the block starting with "cat >
CHANGELOG.md << 'HEADER'" is indented by the YAML and will inject leading spaces
into CHANGELOG.md; fix it by emitting the heredoc without indentation—either
place the "cat > CHANGELOG.md << 'HEADER'" token and the following content at
column 1 so the content lines have no leading spaces, or replace the heredoc
with a non-indented alternative (e.g., use a left-aligned here-doc or generate
the file via printf/echo with explicit newlines) so the generated CHANGELOG.md
preserves correct Markdown formatting.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b62a6f3 and d50d65e.

📒 Files selected for processing (4)
  • .github/CONTRIBUTING.md
  • .github/release.yml
  • .github/workflows/create-tag-and-exit.yml
  • CHANGELOG.md
🧰 Additional context used
🪛 LanguageTool
CHANGELOG.md

[style] ~6-~6: ‘prior to’ might be wordy. Consider a shorter alternative.
Context: ...s://keepachangelog.com/). For releases prior to automated changelog generation, please ...

(EN_WORDINESS_PREMIUM_PRIOR_TO)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Docker Image
  • GitHub Check: Build Docker Image
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
.github/CONTRIBUTING.md (1)

67-92: Clear and well-structured documentation for the release process.

The changelog labels table and release workflow steps are documented clearly. The label naming convention (changelog:*) is consistent with the configuration in .github/release.yml.

CHANGELOG.md (1)

1-9: Good initial changelog structure.

The boilerplate follows Keep a Changelog conventions and appropriately directs users to GitHub Releases for historical versions. The auto-update comment clearly indicates this file is managed by automation.

.github/release.yml (1)

1-31: Well-structured release notes configuration.

The label-to-category mappings align with the CONTRIBUTING.md documentation. Excluding dependabot and github-actions authors prevents automated PR noise in release notes. The catch-all "Other Changes" with * ensures unlabeled PRs still appear.

@f-leu f-leu added the changelog:added New features label Jan 9, 2026
Copy link

@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: 2

🤖 Fix all issues with AI agents
In @.github/workflows/create-tag-and-exit.yml:
- Line 65: The pipeline step that runs gh release view "$tag" --json body -q
'.body' | sed 's/^## /### /' assumes release notes use "## " headings; update
this to be robust by either (a) adding validation that checks the release body
contains expected headings before transforming, or (b) making the sed transform
idempotent/safer (e.g., match both "## " and "### " or only change the first
heading occurrence), and add a comment documenting the dependency on
release-note format; locate the command string (gh release view "$tag" --json
body -q '.body' | sed 's/^## /### /') in the workflow and implement the chosen
validation/safer transform and a short inline comment documenting the
assumption.
- Line 61: The workflow uses "gh release list --limit 100" which can omit older
releases when there are more than 100; update the command invocation (the line
containing gh release list --limit 100 --json tagName,publishedAt) to remove the
"--limit 100" argument so gh will paginate through all releases (or
alternatively set a larger limit if desired), ensuring the loop reads every
release for the changelog generation.
🧹 Nitpick comments (2)
.github/workflows/create-tag-and-exit.yml (2)

45-67: CHANGELOG.md regeneration overwrites manual edits.

The workflow regenerates CHANGELOG.md from scratch on every release, which means any manual edits, corrections, or additional context added to the changelog will be lost on the next release.

If manual edits are expected, consider a different approach such as:

  • Prepending only the new release to an existing CHANGELOG.md
  • Using a separate "automated" section vs "curated" section
  • Documenting that CHANGELOG.md should not be manually edited

81-87: Retry logic may not handle concurrent workflow runs.

While the retry mechanism with rebase helps handle transient issues, it doesn't fully protect against race conditions if multiple releases are created simultaneously (e.g., if two maintainers trigger the workflow at the same time).

Both runs would create their releases successfully (different tags), but when committing the changelog, the second run might incorporate the first run's changelog update during rebase, leading to unexpected changelog state or push conflicts.

Consider adding a concurrency group to prevent simultaneous executions:

concurrency:
  group: release-workflow
  cancel-in-progress: false
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d50d65e and a291635.

📒 Files selected for processing (1)
  • .github/workflows/create-tag-and-exit.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Docker Image
  • GitHub Check: Build Docker Image
  • GitHub Check: Analyze (go)
🔇 Additional comments (4)
.github/workflows/create-tag-and-exit.yml (4)

22-35: LGTM! Tag determination logic is solid.

The step correctly handles both user-provided tags and automatic patch version bumping. The semver parsing and fallback to v0.0.0 are appropriate.


37-89: Changelog update occurs after release publication.

The workflow order is:

  1. Create release (with tag)
  2. Update CHANGELOG.md
  3. Commit changelog to main

This means the CHANGELOG.md is updated after the release is already published. The newly created release won't contain or reference the updated changelog. This may be intentional (the changelog documents history after the fact), but it's worth confirming this is the desired behavior.

Alternative approaches:

  • Generate changelog before creating the release
  • Include changelog in release assets
  • Document that changelog is updated post-release

69-89: No branch protection rules are configured on main branch.

The branch protection API returned a 404 error, confirming that no protection rules exist. Therefore, the direct push to main is not bypassing any branch protection or PR requirements—it's the repository's current intended configuration.

The workflow's contents: write permission and direct push strategy are appropriate for this manually-triggered administrative workflow that creates releases and updates the changelog.

Likely an incorrect or invalid review comment.


37-43: Idempotency concern is not applicable to this workflow's design.

The workflow uses auto-incrementing patch versions for tag generation (lines 28–32), which naturally prevents duplicate tags from being created automatically. While a user could manually specify an identical tag via the tag input (lines 25–26), gh release create will reuse the existing release rather than fail. An idempotency check is unnecessary given the auto-increment logic handles the common case, and manual tag conflicts are user input errors rather than workflow design issues.

Copy link

@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: 3

🤖 Fix all issues with AI agents
In @.github/workflows/create-tag-and-exit.yml:
- Around line 37-43: The release creation step ("Create GitHub Release with
auto-generated notes") can fail if the tag/release already exists; modify the
step to first check for an existing release for steps.version.outputs.tag (e.g.,
call the GH CLI to view the release) and only run the gh release create command
if it does not exist, or alternatively make the operation idempotent by using a
conditional/flag to skip creation when a release is present; reference the
GH_TOKEN env and the tokenized variable ${{ steps.version.outputs.tag }} when
implementing the pre-check and conditional to ensure the workflow does not error
on duplicate releases.
- Around line 71-91: The retry loop around the commands git rebase origin/main
&& git push origin main will keep retrying even when the rebase fails due to
conflicts; update the loop to check the exit status of git rebase origin/main,
and if it returns non-zero inspect for conflicts and immediately abort the
rebase (git rebase --abort) and exit with a clear error message instead of
retrying; only retry on transient failures from git push (or fetch) but not on
rebase-conflict failures—use explicit checks after git rebase origin/main (look
for exit code or the word "CONFLICT") to decide whether to abort and fail or
continue retrying the push.
- Around line 45-69: The gh release list invocation in the "Update CHANGELOG.md
from releases" step only fetches the default 30 releases; update the command
that currently uses gh release list --json tagName,publishedAt to either add an
explicit large limit (e.g., --limit 9999) or replace it with a paginated API
call (e.g., gh api --paginate for releases) so that all releases are retrieved
and appended to CHANGELOG.md; adjust the pipeline line where gh release list is
used and keep the subsequent jq and loop logic unchanged.
🧹 Nitpick comments (2)
.github/workflows/create-tag-and-exit.yml (2)

22-35: Consider using --sort=-version:refname for more reliable semantic version sorting.

The current --sort=-creatordate could produce incorrect results if tags are created out of chronological order (e.g., creating a hotfix tag v1.0.1 after v1.1.0 is already released). Using --sort=-version:refname would ensure proper semantic version ordering.

♻️ Proposed fix
-          LAST_TAG=$(git tag --sort=-creatordate | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || echo "v0.0.0")
+          LAST_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | head -n1 || echo "v0.0.0")

66-67: Clarify the sed pattern comment.

The comment mentions "negative lookahead pattern," but the regex s/^##\([^#]\)/###\1/ uses a character class [^#] (match any character except #), not a lookahead. This is simpler and works correctly, but the comment could be misleading.

♻️ Proposed fix
-          # Transform top-level headings (## ) to subheadings (### ) for changelog nesting.
-          # Uses negative lookahead pattern to avoid double-transforming already-nested headings.
+          # Transform top-level headings (## ) to subheadings (### ) for changelog nesting.
+          # The [^#] character class prevents double-transforming already-nested headings (###, ####, etc.).
           gh release view "$tag" --json body -q '.body' | sed 's/^##\([^#]\)/###\1/'
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a291635 and 4b169a7.

📒 Files selected for processing (1)
  • .github/workflows/create-tag-and-exit.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Docker Image
  • GitHub Check: Build Docker Image
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
.github/workflows/create-tag-and-exit.yml (1)

45-69: Verify the impact of regenerating CHANGELOG.md on every release.

The workflow regenerates the entire CHANGELOG.md file from scratch on each release, which means any manual edits or customizations to the changelog would be lost. Confirm this is the intended behavior and consider documenting this limitation.

Copy link

@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

🤖 Fix all issues with AI agents
In @.github/workflows/create-tag-and-exit.yml:
- Line 61: Replace the hardcoded repository path in the markdown link string
"[GitHub Releases](https://github.com/devzero-inc/zxporter/releases) page." with
the repository context variable, i.e., use github.repository instead of
"devzero-inc/zxporter" so the link becomes https://github.com/${{
github.repository }}/releases for consistency with the other usage on line 65.
🧹 Nitpick comments (2)
.github/workflows/create-tag-and-exit.yml (2)

37-47: LGTM! Consider specifying an explicit target commitish.

The release creation logic is sound, with good idempotency handling. By default, gh release create will tag the current HEAD of the default branch. If you want to ensure the release targets a specific commit (e.g., the checked-out commit), consider adding --target ${{ github.sha }}.

✨ Optional: Add explicit target commit
          else
            gh release create ${{ steps.version.outputs.tag }} \
              --generate-notes \
-              --title "${{ steps.version.outputs.tag }}"
+              --title "${{ steps.version.outputs.tag }}" \
+              --target ${{ github.sha }}
          fi

70-72: Clarify the sed pattern comment.

The comment mentions "negative lookahead pattern" but the regex \([^#]\) uses character class negation (match one non-# character), not a lookahead assertion. While the pattern works correctly, the comment is technically misleading.

📝 Suggested comment clarification
-          # Transform top-level headings (## ) to subheadings (### ) for changelog nesting.
-          # Uses negative lookahead pattern to avoid double-transforming already-nested headings.
+          # Transform top-level headings (## ) to subheadings (### ) for changelog nesting.
+          # Matches ## followed by a non-# character to avoid transforming already-nested headings.
          gh release view "$tag" --json body -q '.body' | sed 's/^##\([^#]\)/###\1/'
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4b169a7 and fd4a083.

📒 Files selected for processing (1)
  • .github/workflows/create-tag-and-exit.yml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Docker Image
  • GitHub Check: Build Docker Image
  • GitHub Check: Analyze (go)
🔇 Additional comments (3)
.github/workflows/create-tag-and-exit.yml (3)

22-35: Verify that git tag creation is intentionally removed.

The step now only determines the tag version and outputs it, but no longer creates the actual git tag via git tag and git push. The subsequent "Create GitHub Release" step will create the tag implicitly when creating the release, which is a significant behavior change.

Confirm this is intentional and that implicit tag creation via gh release create aligns with your release process expectations.


76-106: Verify branch protection rules allow direct pushes from GitHub Actions, or confirm the repository intentionally allows this workflow.

The workflow pushes CHANGELOG.md directly to main (line 101) with contents: write permissions. While GitHub Actions with appropriate permissions can bypass certain branch protections, confirm that this setup aligns with the repository's branch protection policy. If branch protection requires pull requests, status checks, or reviews, this direct push will fail regardless of the retry logic. Since similar workflows exist in the repository (push-zxporter-image.yml, push-zxporter-netmon-image.yml), this pattern appears intentional—verify it's documented and approved.


65-74: Pagination is correctly handled; this approach works as intended.

The pipeline output demonstrates that all 183 releases are correctly included with no duplicates. While gh api --paginate does output each page as a separate JSON array, jq handles streaming input—the second jq -r '.[] | ...' processes each array sequentially, extracting objects from every page. This produces the correct merged output without requiring --slurp.

Likely an incorrect or invalid review comment.

@Tzvonimir Tzvonimir merged commit 9d47375 into main Jan 23, 2026
26 checks passed
@Tzvonimir Tzvonimir deleted the PC-472-alt branch January 23, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog:added New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants