Skip to content

Conversation

@bashandbone
Copy link
Contributor

@bashandbone bashandbone commented Dec 2, 2025

This pull request introduces automated changelog generation using git-cliff, replacing the previous changesets-based approach. It adds configuration, workflow, and documentation changes to support PR-focused, categorized changelogs, and integrates changelog generation into both local development and GitHub release workflows.

Changelog Automation & Configuration

  • Added cliff.toml to configure git-cliff for PR-based changelog generation, with custom grouping and formatting based on branch naming conventions.
  • Added a new .github/workflows/changelog.yml workflow to allow manual changelog generation via GitHub Actions, supporting both unreleased changes and specific tags, with optional auto-commit.
  • Updated mise.toml tasks to provide local commands for generating, updating, and viewing changelogs using git-cliff, including support for unreleased changes and specific tags.

Release Workflow Integration

  • Modified .github/workflows/release.yml to use git-cliff for generating release notes, ensuring categorized PR descriptions and consistent formatting in GitHub releases.

Documentation & Changelog File

  • Added a new CHANGELOG.md file, generated and formatted by git-cliff, with categorized sections for unreleased changes.
  • Updated docs/versioning.md to document the new changelog management process, explaining how changelogs are generated, categorized, and integrated into workflows.

Summary by Sourcery

Replace the previous changesets-based changelog process with git-cliff–driven, PR-focused changelog generation integrated into local tooling and release workflows.

Enhancements:

  • Add git-cliff configuration to generate categorized, PR-based changelogs and extract PR descriptions cleanly.
  • Expose local mise tasks to generate, preview, and update changelogs, including support for unreleased changes and specific tags.

Build:

  • Adjust release workflow to install and use git-cliff for generating tagged release notes and changelog sections.

CI:

  • Introduce a dedicated GitHub Actions workflow to generate CHANGELOG.md on demand, with optional auto-commit and artifact upload.

Documentation:

  • Replace changesets documentation with git-cliff–based changelog management guidance, including branch naming conventions, usage best practices, and workflow integration.
  • Add an initial CHANGELOG.md seeded with unreleased, categorized entries and update package installation examples to use the correct project name.

Set up git-cliff for PR-based changelog generation with manual triggers.
This implementation focuses on merge commits only to avoid noise from
individual commits, as requested.

**Added:**
- cliff.toml: git-cliff configuration
  - Filters to only include PR merge commits
  - Categorizes by branch name patterns (feat/, fix/, optimize/, etc.)
  - Extracts PR descriptions from commit bodies
  - Generates clean, readable changelogs

- .github/workflows/changelog.yml: Manual workflow for changelog generation
  - Can generate changelog for specific tags or unreleased changes
  - Optional commit and push of CHANGELOG.md
  - Uploads changelog as artifact

- CHANGELOG.md: Initial changelog file
  - Follows Keep a Changelog format
  - Generated from PR merge commits only

**Modified:**
- .github/workflows/release.yml:
  - Updated to use git-cliff for release notes instead of bash script
  - Maintains installation instructions and verification sections
  - Generates cleaner release notes from PR descriptions

**Features:**
- PR-based changelog: Focuses on merge commits, filters out noise
- Categorized changes: Features, Bug Fixes, Performance, etc.
- Manual trigger: Uses workflow_dispatch for control
- Dual output: Both CHANGELOG.md and GitHub release notes
- Works with existing uv-dynamic-versioning setup
- Replace old changeset-based changelog task with git-cliff tasks
- Add mise tasks: changelog, changelog-unreleased, changelog-update, changelog-tag
- All tasks support both Linux and Windows
- Update docs/versioning.md to replace changesets section with git-cliff documentation
- Add usage examples and best practices for changelog management
Copilot AI review requested due to automatic review settings December 2, 2025 00:50
@bashandbone bashandbone added documentation Improvements or additions to documentation configuration ci-cd Issues affecting ci/cd labels Dec 2, 2025
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Dec 2, 2025

Reviewer's Guide

Introduces git-cliff–based automated, PR-focused changelog generation, wires it into local mise tasks and GitHub workflows (including releases), replaces the previous changesets flow, and updates docs and the new CHANGELOG.md accordingly.

Sequence diagram for release workflow using git-cliff

sequenceDiagram
    actor Maintainer
    participant GitHub
    participant release_workflow
    participant git_cliff
    participant Repo
    participant GitHubRelease

    Maintainer->>GitHub: Push tag vX.Y.Z
    GitHub->>release_workflow: Trigger release workflow

    release_workflow->>Repo: Checkout repository (fetch-depth 0)
    release_workflow->>release_workflow: Determine VERSION and CURRENT_TAG
    release_workflow->>Repo: git tag --sort to find PREVIOUS_TAG

    release_workflow->>git_cliff: Install via taiki_e_install_action

    alt Previous tag exists and differs from CURRENT_TAG
        release_workflow->>git_cliff: git-cliff --strip header --tag CURRENT_TAG PREVIOUS_TAG..CURRENT_TAG
        git_cliff-->>release_workflow: changelog_section.md
    else First release or no previous tag
        release_workflow->>git_cliff: git-cliff --strip header --tag CURRENT_TAG
        git_cliff-->>release_workflow: changelog_section.md
    end

    release_workflow->>release_workflow: Build release_notes.md
    release_workflow->>release_workflow: Append changelog_section.md
    alt Pre-release version (alpha, beta, rc)
        release_workflow->>release_workflow: Add pip install --pre code-weaver instructions
    else Stable version
        release_workflow->>release_workflow: Add pip install code-weaver instructions
    end
    release_workflow->>release_workflow: Append verification info and Full Changelog link

    release_workflow->>GitHubRelease: Create release with release_notes.md
    GitHubRelease-->>Maintainer: Published release with categorized PR-based notes
Loading

Sequence diagram for manual Generate Changelog workflow

sequenceDiagram
    actor Maintainer
    participant GitHubUI
    participant changelog_workflow
    participant git_cliff
    participant Repo
    participant ArtifactStore

    Maintainer->>GitHubUI: Open Actions / Generate Changelog
    Maintainer->>GitHubUI: Run workflow (tag, commit options)

    GitHubUI->>changelog_workflow: workflow_dispatch event

    changelog_workflow->>Repo: Checkout repository (fetch-depth 0)
    changelog_workflow->>git_cliff: Install via taiki_e_install_action

    alt Tag input provided
        changelog_workflow->>git_cliff: git-cliff --tag tag --output CHANGELOG.md --prepend
    else No tag (unreleased changes)
        changelog_workflow->>git_cliff: git-cliff --unreleased --prepend --output CHANGELOG.md
    end

    git_cliff-->>changelog_workflow: Updated CHANGELOG.md

    changelog_workflow->>changelog_workflow: Display CHANGELOG.md in logs

    alt Commit option true
        changelog_workflow->>Repo: git add CHANGELOG.md
        changelog_workflow->>Repo: git diff --staged --quiet
        alt Has staged changes
            changelog_workflow->>Repo: git commit with docs message
            changelog_workflow->>Repo: git push
        else No staged changes
            changelog_workflow->>Maintainer: Log "No changes to commit"
        end
    end

    changelog_workflow->>ArtifactStore: Upload CHANGELOG.md artifact
    ArtifactStore-->>Maintainer: Downloadable changelog artifact
Loading

Flow diagram for local changelog mise tasks

flowchart TD
    Start([Developer wants changelog])
    Start --> Choice{What do you want to do?}

    Choice --> FullStdout["Run task changelog\n- git-cliff\n- Full history to stdout"]
    Choice --> UnreleasedStdout["Run task changelog-unreleased\n- git-cliff --unreleased\n- Unreleased only to stdout"]
    Choice --> UpdateFile["Run task changelog-update\n- git-cliff --unreleased --prepend --output CHANGELOG.md\n- Updates top of changelog"]
    Choice --> TagUpdate["Run task changelog-tag <tag>\n- git-cliff --tag <tag> --prepend --output CHANGELOG.md\n- Adds tag section at top"]

    FullStdout --> ViewOutput([View changelog in terminal])
    UnreleasedStdout --> ViewOutput

    UpdateFile --> InspectFile["Inspect CHANGELOG.md changes"]
    TagUpdate --> InspectFile

    InspectFile --> CommitChanges{Commit changes?}
    CommitChanges -->|Yes| GitCommit["git add CHANGELOG.md\ngit commit"]
    CommitChanges -->|No| End([Keep local-only changes])
    GitCommit --> End
Loading

File-Level Changes

Change Details Files
Replace changesets-based changelog/versioning flow with git-cliff configuration and PR-focused grouping logic.
  • Add cliff.toml with git-cliff configuration for PR-based changelogs, including commit preprocessors and parsers for squash/merge commits and branch-based category grouping.
  • Configure changelog templates (header/body/footer) to render versions or an Unreleased section, group commits, and format PR links and breaking changes.
  • Limit included commits using filter_commits, tag_pattern, and other git settings to focus on tagged releases and PR merges.
cliff.toml
Integrate git-cliff into CI via a new dedicated changelog workflow and by updating the release workflow to generate release notes from git-cliff output.
  • Add .github/workflows/changelog.yml workflow with workflow_dispatch inputs (tag, commit) to generate CHANGELOG.md using git-cliff --unreleased or --tag plus --prepend, optionally committing and pushing changes, and uploading the file as an artifact.
  • Update .github/workflows/release.yml to install git-cliff, compute PREVIOUS_TAG with an extended semver-ish regex, and generate a changelog_section.md via git-cliff for the appropriate tag range, then compose release_notes.md that embeds the git-cliff section and retains installation and verification sections.
  • Adjust pre-release installation snippet in the release notes to use the hyphenated package name code-weaver and reuse the computed VERSION when inserting exact-version pip commands.
.github/workflows/changelog.yml
.github/workflows/release.yml
Expose git-cliff-based changelog operations as mise tasks for local development, replacing the prior changeset invocation.
  • Replace the previous changeset-based tasks.changelog command with a bash-based git-cliff invocation and attach a cargo:git-cliff tool requirement.
  • Add tasks.changelog-unreleased to render unreleased changelog content to stdout with git-cliff --unreleased.
  • Add tasks.changelog-update to prepend unreleased changes into CHANGELOG.md using git-cliff --unreleased --prepend --output CHANGELOG.md.
  • Add tasks.changelog-tag that accepts a tag argument and generates/prepends that tag’s changelog into CHANGELOG.md via git-cliff --tag --prepend.
mise.toml
Introduce and seed a generated CHANGELOG.md managed by git-cliff.
  • Add CHANGELOG.md with Keep a Changelog header and Unreleased section.
  • Populate initial Unreleased entries grouped under Bug Fixes, Features, and Other Changes with PR-linked items, matching the git-cliff template output.
  • Mark the file as generated by git-cliff in the footer to signal its generated nature.
CHANGELOG.md
Update documentation to describe the new git-cliff–based changelog process and fix package name references.
  • Change pre-release installation examples in docs/versioning.md from codeweaver to code-weaver, including pip install --pre and upgrade commands.
  • Replace the previous “Integration with Changesets” section with a new “Changelog Management” section that explains PR-focused git-cliff usage, automatic categorization rules based on branch naming, and how descriptions are extracted.
  • Document local mise tasks for changelog generation, the semantics and caveats of using --prepend (duplication risk, conflicts, best practices), and the GitHub “Generate Changelog” workflow options.
  • Describe how the release workflow uses git-cliff to build release notes and list best practices for writing PR descriptions and using branch naming conventions to get good changelog output.
docs/versioning.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The tag_pattern = "v[0-9].*" in cliff.toml will match any tag starting with v and a single digit (including non-SemVer tags like v1beta); if you only want real release tags, consider tightening this to something like ^v[0-9]+\.[0-9]+\.[0-9]+.*$ to avoid pulling in unexpected tags.
  • The commit_preprocessors pattern in cliff.toml assumes a single-line PR description and a specific merge commit format (Merge pull request #... from ...\n\nPR Description); if your PR bodies often have multiple lines or blank leading lines, you may want to adjust this regex to be more tolerant so descriptions are still captured reliably.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The `tag_pattern = "v[0-9].*"` in `cliff.toml` will match any tag starting with `v` and a single digit (including non-SemVer tags like `v1beta`); if you only want real release tags, consider tightening this to something like `^v[0-9]+\.[0-9]+\.[0-9]+.*$` to avoid pulling in unexpected tags.
- The `commit_preprocessors` pattern in `cliff.toml` assumes a single-line PR description and a specific merge commit format (`Merge pull request #... from ...\n\nPR Description`); if your PR bodies often have multiple lines or blank leading lines, you may want to adjust this regex to be more tolerant so descriptions are still captured reliably.

## Individual Comments

### Comment 1
<location> `cliff.toml:77` </location>
<code_context>
+  # Extract PR description and append to subject for template use
+  # Input: "Merge pull request #123 from org/branch\n\nPR Description"
+  # Output: "Merge pull request #123 from org/branch | PR Description"
+  { pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+(.+)', replace = "Merge pull request ${1} from ${2} | ${3}" },
+]
+# Parse merge commits to extract PR info
</code_context>

<issue_to_address>
**issue:** The commit preprocessor and parsers assume merge-commit format and will drop other merge strategies due to `filter_commits = true`.

Because `filter_commits = true` and the current `commit_parsers` only match `Merge pull request ...`, any squash/rebase merges or custom merge messages will be excluded from the changelog. If you expect other merge strategies, consider adding parsers for those patterns or turning off `filter_commits` and using grouping/skipping instead, so future changes in merge strategy don’t produce empty or incomplete changelog sections.
</issue_to_address>

### Comment 2
<location> `mise.toml:354` </location>
<code_context>
+run = '''
+#!/usr/bin/env zsh
+print -P "%F{209}[codeweaver]%f Generating changelog for tag ${usage_tag}..."
+git-cliff --tag "${usage_tag}" --output CHANGELOG.md &&
+print -P "%F{209}[codeweaver]%f ✅ CHANGELOG.md generated for ${usage_tag}!"
+'''
</code_context>

<issue_to_address>
**suggestion (bug_risk):** Generating a changelog for a tag overwrites the entire CHANGELOG.md, which may unexpectedly drop existing history.

Here `git-cliff --tag "${usage_tag}" --output CHANGELOG.md` fully replaces the file. If `CHANGELOG.md` is meant to be cumulative, this will erase older entries each time the task runs. To preserve history, consider either using `--prepend --output CHANGELOG.md` or writing per-tag output to a separate file (e.g., `CHANGELOG-${usage_tag}.md`).

Suggested implementation:

```
run = '''
#!/usr/bin/env zsh
set -e
print -P "%F{209}[codeweaver]%f Generating changelog for tag ${usage_tag}..."
git-cliff --tag "${usage_tag}" --prepend --output CHANGELOG.md &&
print -P "%F{209}[codeweaver]%f ✅ CHANGELOG.md updated for ${usage_tag}!"
'''

[tasks.changelog]

```

If you prefer per-tag files instead of a cumulative `CHANGELOG.md`, replace the `git-cliff` line with something like:
`git-cliff --tag "${usage_tag}" --output "CHANGELOG-${usage_tag}.md"` and adjust the success message accordingly.
</issue_to_address>

### Comment 3
<location> `.github/workflows/changelog.yml:42-48` </location>
<code_context>
+        run: |
+          if [ -n "${{ github.event.inputs.tag }}" ]; then
+            echo "Generating changelog for tag ${{ github.event.inputs.tag }}"
+            git-cliff --tag "${{ github.event.inputs.tag }}" --output CHANGELOG.md
+          else
+            echo "Generating changelog for unreleased changes"
</code_context>

<issue_to_address>
**suggestion (bug_risk):** The workflow path for a specific tag also fully overwrites CHANGELOG.md, which might conflict with the unreleased/prepend mode.

With `tag` set, this step replaces `CHANGELOG.md` entirely, unlike the `--unreleased` path which prepends. With `commit=true`, the repo ends up with a changelog containing only that tag’s entries, dropping previous history. If that’s not intentional, consider matching the prepend behavior here or writing tagged output to a separate file (e.g., `CHANGELOG-${tag}.md`) to avoid truncating the main changelog.

```suggestion
          if [ -n "${{ github.event.inputs.tag }}" ]; then
            echo "Generating changelog for tag ${{ github.event.inputs.tag }}"
            git-cliff --tag "${{ github.event.inputs.tag }}" --output CHANGELOG.md --prepend
          else
            echo "Generating changelog for unreleased changes"
            git-cliff --unreleased --output CHANGELOG.md --prepend
          fi
```
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com>
Signed-off-by: Adam Poulemanos <[email protected]>
@github-actions
Copy link
Contributor

github-actions bot commented Dec 2, 2025

👋 Hey @bashandbone,

Thanks for your contribution to codeweaver! 🧵

You need to agree to the CLA first... 🖊️

Before we can accept your contribution, you need to agree to our Contributor License Agreement (CLA).

To agree to the CLA, please comment:

I read the contributors license agreement and I agree to it.

Those exact words are important1, so please don't change them. 😉

You can read the full CLA here: Contributor License Agreement


@bashandbone has signed the CLA.


0 out of 2 committers have signed the CLA.
@claude
@bashandbone
You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

Footnotes

  1. Our bot needs those exact words to recognize that you agree to the CLA.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 2, 2025

Code Review - PR #180: Automated Changelog Generation with git-cliff

I've reviewed this pull request that introduces automated changelog generation using git-cliff. Overall, this is a well-implemented and valuable addition to the project's release workflow. The implementation is thoughtful, well-documented, and follows good practices.


Strengths

  1. Clean Architecture: The separation of concerns is excellent - git-cliff configuration, GitHub workflows, and local mise tasks are all properly organized.

  2. Comprehensive Documentation: The updated docs/versioning.md provides clear guidance on how to use the new changelog system, including best practices and workflow integration.

  3. PR-Focused Approach: Filtering to only merge commits is smart - it reduces noise and focuses on meaningful changes. The branch naming conventions for categorization are well thought out.

  4. Multi-Platform Support: Providing both Unix and Windows scripts in mise.toml shows attention to cross-platform compatibility.

  5. Security: Proper use of pinned action versions with commit SHAs, appropriate permissions scoping (contents: write), and no exposure of secrets.

  6. Workflow Integration: The integration with the existing release workflow is clean and maintains backward compatibility with installation instructions.


⚠️ Issues to Address

1. Critical: changelog-tag Task Overwrites CHANGELOG.md (Sourcery comment #2579192673)

Location: mise.toml:354

The changelog-tag task uses git-cliff --tag "${usage_tag}" --output CHANGELOG.md, which completely replaces the file with only that tag's entries. This will erase all existing changelog history.

Impact: High - Users could lose changelog history unexpectedly.

Recommendation: Use --prepend flag to preserve existing content:

run = '''
#\!/usr/bin/env zsh
print -P "%F{209}[codeweaver]%f Generating changelog for tag ${usage_tag}..."
git-cliff --tag "${usage_tag}" --prepend --output CHANGELOG.md &&
print -P "%F{209}[codeweaver]%f ✅ CHANGELOG.md updated for ${usage_tag}\!"
'''

Alternatively, if the intent is to generate per-tag files, output to CHANGELOG-${usage_tag}.md instead.


2. Critical: GitHub Workflow Has Same Issue

Location: .github/workflows/changelog.yml:42-48

The workflow's tag path also overwrites CHANGELOG.md entirely, which conflicts with the --unreleased path that uses --prepend. This creates inconsistent behavior.

Recommendation: Add --prepend to the tag path as well:

if [ -n "${{ github.event.inputs.tag }}" ]; then
  echo "Generating changelog for tag ${{ github.event.inputs.tag }}"
  git-cliff --tag "${{ github.event.inputs.tag }}" --output CHANGELOG.md --prepend
else
  echo "Generating changelog for unreleased changes"
  git-cliff --unreleased --output CHANGELOG.md --prepend
fi

3. Medium: Tag Pattern May Be Too Permissive

Location: cliff.toml:116

The pattern tag_pattern = "v[0-9].*" will match any tag starting with v followed by a digit, including non-SemVer tags like v1beta, v2-experimental, etc.

Recommendation: Tighten to proper SemVer pattern:

tag_pattern = "^v[0-9]+\.[0-9]+\.[0-9]+.*$"

This ensures only valid version tags (e.g., v1.2.3, v1.2.3-alpha.1) are included.


4. Medium: Commit Preprocessor Assumes Single-Line PR Descriptions

Location: cliff.toml:77

The regex pattern assumes PR descriptions are single-line and immediately follow the merge commit line. Multi-line descriptions or leading blank lines won't be captured correctly.

Current:

{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+(.+)', replace = "Merge pull request ${1} from ${2} | ${3}" }

Impact: PR descriptions with multiple paragraphs or leading whitespace may be truncated or missed.

Consideration: This might be acceptable if PR titles are typically single-line. If full PR bodies are needed, consider using GitHub API integration or adjusting the regex to capture multiple lines (e.g., (.+(?:\n.+)*)).


5. Low: Squash Merges Not Handled

Location: cliff.toml:81-109

The current setup only parses "Merge pull request #..." format. If the project uses squash merges or rebase merges, those commits will be excluded due to filter_commits = true.

Recommendation:

  • If you expect other merge strategies, add parsers for those patterns
  • Or document that the project should use merge commits (not squash) for changelog generation
  • The documentation does mention this in docs/versioning.md:271 ("works with both squash commits and merge commits"), but the implementation seems focused on merge commits only

🔍 Minor Observations

  1. Git-cliff version pinning: Using [email protected] is good for reproducibility. Consider documenting when/how to update this version.

  2. Error handling: The mise tasks use && for success messages, which is appropriate. The Windows version correctly checks %ERRORLEVEL%.

  3. Artifact retention: 7-day retention for changelog artifacts in the workflow is reasonable.

  4. Template quality: The Tera templates in cliff.toml are well-structured and handle edge cases (missing descriptions, breaking changes).


📊 Performance & Security

  • Performance: ✅ No concerns. git-cliff is efficient and the workflows are appropriately scoped.
  • Security: ✅ Good practices observed:
    • Pinned action versions with commit SHAs
    • Minimal permissions (contents: write only where needed)
    • No exposure of secrets or sensitive data
    • Proper git configuration for bot commits

🎯 Recommendations Summary

Must Fix (before merge):

  1. Add --prepend to changelog-tag task to avoid data loss
  2. Add --prepend to workflow's tag path for consistency

Should Fix (before merge):
3. Tighten tag_pattern to proper SemVer format
4. Consider improving commit preprocessor regex or document limitations

Consider for future:
5. Document or handle squash merge strategy explicitly


Approval Recommendation

Once the two critical issues (changelog overwrites) are addressed, this PR is ready to merge. The implementation is solid, well-documented, and will significantly improve the release workflow.

The existing Sourcery AI review raised the same concerns, and I agree with their suggestions. Addressing comment #2579192673 and the corresponding workflow issue will resolve the main blockers.

CI Status: Lint and security checks are passing. Tests are pending but this is primarily workflow/tooling changes, so no test failures are expected.

Great work on this comprehensive changelog automation! 🎉

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Review of PR #180: Automated Changelog Generation with git-cliff

I've reviewed this PR that introduces git-cliff for automated changelog generation. Overall, this is a well-structured and thoughtful implementation that successfully replaces the changesets-based approach with a PR-focused changelog system.

✅ Strengths

  1. Clean Architecture: The separation of concerns is excellent - configuration in cliff.toml, workflows in .github/workflows/, and local tooling in mise.toml
  2. Comprehensive Documentation: The updates to docs/versioning.md provide clear guidance on usage, best practices, and workflow integration
  3. Cross-platform Support: Both Unix and Windows support in mise tasks shows attention to detail
  4. Consistent Code Style: Follows existing project conventions (SPDX headers, formatting, etc.)
  5. PR-focused Approach: Filtering merge commits reduces noise and focuses on meaningful changes
  6. Good Template Design: The git-cliff template properly extracts PR descriptions and handles edge cases

🔍 Regarding Comment #2579192676

The Sourcery AI bot raised a valid concern about the changelog-tag task in mise.toml:354 potentially overwriting CHANGELOG.md history. However, I believe the current implementation is correct for the following reasons:

  1. Intended Behavior: The changelog-tag task appears designed for generating release-specific changelogs, not for maintaining cumulative history
  2. Separate Use Cases: The PR provides distinct tasks:
    • changelog-update: Updates CHANGELOG.md cumulatively (uses --prepend)
    • changelog-tag: Generates tag-specific output (overwrites by design)
  3. Release Workflow Context: Looking at .github/workflows/release.yml:104, git-cliff generates release notes for specific tag ranges (--strip all), which aligns with the tag-specific approach

However, there is a legitimate issue in the GitHub Actions workflow at .github/workflows/changelog.yml:42-48:

The workflow has inconsistent behavior:

  • With tag: Overwrites CHANGELOG.md entirely (line 44)
  • Without tag: Prepends to CHANGELOG.md (line 47 uses --prepend)

This inconsistency could lead to accidental history loss if someone runs the workflow with a tag and commits=true.

📝 Recommendations

1. Fix the Workflow Inconsistency (Important)

The .github/workflows/changelog.yml should use consistent behavior. I recommend using --prepend for both paths:

# .github/workflows/changelog.yml:42-48
if [ -n "${{ github.event.inputs.tag }}" ]; then
  echo "Generating changelog for tag ${{ github.event.inputs.tag }}"
  git-cliff --tag "${{ github.event.inputs.tag }}" --output CHANGELOG.md --prepend
else
  echo "Generating changelog for unreleased changes"
  git-cliff --unreleased --output CHANGELOG.md --prepend
fi

2. Consider Tightening Tag Pattern (Optional)

The tag_pattern = "v[0-9].*" in cliff.toml:116 is quite permissive. If you want to strictly match SemVer tags, consider:

tag_pattern = "^v[0-9]+\.[0-9]+\.[0-9]+.*$"

However, the current pattern may be intentional to catch alpha/beta tags like v0.1.0a1.

3. Enhance Commit Preprocessor Robustness (Optional)

The regex at cliff.toml:77 assumes single-line PR descriptions. Consider handling multi-line descriptions:

{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+([\s\S]+?)(?=\n\nCo-authored-by:|\$)', replace = "Merge pull request ${1} from ${2} | ${3}" }

Though this may be over-engineering if your PR descriptions are typically single-line.

4. Clarify mise Task Documentation (Minor)

Consider adding a note to mise.toml:345-346 explaining that changelog-tag overwrites CHANGELOG.md:

description = "Generate changelog for a specific tag (overwrites CHANGELOG.md)"

🔒 Security & Performance

  • ✅ No security concerns identified
  • ✅ Pinned action versions with commit SHAs (good practice)
  • ✅ Appropriate permissions (contents: write only where needed)
  • ✅ Performance is acceptable (git-cliff is efficient)

🎯 Verdict

This PR is ready to merge with one recommended fix for the workflow inconsistency. The rest are optional improvements.

Recommended Action: Address the workflow --prepend inconsistency, then merge.

Great work on this comprehensive changelog automation! 🚀

Copy link
Contributor

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 pull request replaces the changesets-based changelog system with git-cliff for automated changelog generation, implementing a PR-focused approach that categorizes changes based on branch naming conventions.

  • Adds git-cliff configuration with custom templates for PR-based changelog generation
  • Integrates git-cliff into local development workflows via mise tasks and GitHub Actions workflows
  • Updates documentation to reflect the new changelog management process

Reviewed changes

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

Show a summary per file
File Description
cliff.toml New git-cliff configuration defining templates, commit parsers, and branch-based categorization rules
mise.toml Updated changelog tasks to use git-cliff instead of changesets, adding commands for viewing, updating, and tag-specific generation
.github/workflows/changelog.yml New workflow for manual changelog generation with options for tags and auto-commit
.github/workflows/release.yml Modified release workflow to generate release notes using git-cliff
CHANGELOG.md Initial changelog file generated by git-cliff showing unreleased changes
docs/versioning.md Updated documentation explaining the new git-cliff-based changelog workflow and usage patterns

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

cliff.toml Outdated
# Extract PR description and append to subject for template use
# Input: "Merge pull request #123 from org/branch\n\nPR Description"
# Output: "Merge pull request #123 from org/branch | PR Description"
{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+(.+)', replace = "Merge pull request ${1} from ${2} | ${3}" },
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The regex pattern in the commit preprocessor may not handle PR descriptions correctly if they contain newlines within the description. The pattern \n+(.+) will only capture text up to the first newline within the PR description, truncating multi-paragraph PR descriptions to just the first line.

Consider using (.+) with the DOTALL flag or ([\s\S]+) to capture the full PR description including newlines.

Suggested change
{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+(.+)', replace = "Merge pull request ${1} from ${2} | ${3}" },
{ pattern = 'Merge pull request (#[0-9]+) from ([^\n]+)\n+([\s\S]+)', replace = "Merge pull request ${1} from ${2} | ${3}" },

Copilot uses AI. Check for mistakes.
### Bug Fixes
- Verify sparse-only vector search fix (ISSUE-001) ([#176](https://github.com/knitli/codeweaver/pull/176))
- Fix Docker Compose CI test failures - correct Qdrant health endpoint ([#178](https://github.com/knitli/codeweaver/pull/178))
- chore: Add plans for server separation of services refactor to enable… ([#179](https://github.com/knitli/codeweaver/pull/179))
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

This entry appears to be miscategorized. The description starts with "chore:" which suggests it should be in a "Maintenance" or "Chores" section, not "Bug Fixes". This is likely caused by the branch name containing "issue-" which matches the fix pattern on line 91 of cliff.toml.

The commit parsers should be refined to handle cases where branch names might match fix patterns but the actual change is not a fix (based on conventional commit prefixes like "chore:").

Copilot uses AI. Check for mistakes.
mise run changelog-update

# Generate changelog for specific tag
mise run changelog-tag v0.1.0
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The documentation states to use mise run changelog-tag v0.1.0, but according to the task definition in mise.toml (line 348), the correct syntax should be mise run changelog-tag -- --usage_tag=v0.1.0 or the task should accept positional arguments. The current task definition uses usage field with an argument named <tag>, which requires specific mise argument syntax.

Verify the correct syntax for invoking this task and update the documentation accordingly.

Suggested change
mise run changelog-tag v0.1.0
mise run changelog-tag -- --usage_tag=v0.1.0

Copilot uses AI. Check for mistakes.
Comment on lines 81 to 110
commit_parsers = [
# Skip non-PR merge commits (like "Merge branch 'main'")
{ message = "^Merge branch", skip = true },
# Features - check branch name patterns
{ message = "^Merge pull request #[0-9]+ from .*/feat", group = "Features" },
{ message = "^Merge pull request #[0-9]+ from .*/feature", group = "Features" },
# Fixes - multiple patterns for fix-related branches
{ message = "^Merge pull request #[0-9]+ from .*/fix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/bugfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/hotfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/issue-", group = "Bug Fixes" },
# Documentation
{ message = "^Merge pull request #[0-9]+ from .*/docs", group = "Documentation" },
{ message = "^Merge pull request #[0-9]+ from .*/doc", group = "Documentation" },
# Performance
{ message = "^Merge pull request #[0-9]+ from .*/perf", group = "Performance" },
{ message = "^Merge pull request #[0-9]+ from .*/optimize", group = "Performance" },
# Refactoring
{ message = "^Merge pull request #[0-9]+ from .*/refactor", group = "Refactoring" },
# Testing
{ message = "^Merge pull request #[0-9]+ from .*/test", group = "Testing" },
# CI/CD and tooling
{ message = "^Merge pull request #[0-9]+ from .*/ci", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/workflow", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/build", group = "Build System" },
# Chores and maintenance
{ message = "^Merge pull request #[0-9]+ from .*/chore", group = "Maintenance" },
# Catch-all for other PRs (will be categorized as miscellaneous)
{ message = "^Merge pull request #[0-9]+", group = "Other Changes" },
]
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The commit parser patterns rely solely on branch names for categorization, which can lead to incorrect categorization when PR descriptions contain conventional commit prefixes (e.g., "feat:", "chore:", "fix:") that conflict with the branch name pattern. This is evidenced in the generated CHANGELOG.md where entries like "chore: Add plans..." appear under "Bug Fixes" and "feat: implement..." appears under "Performance".

Consider enhancing the commit_preprocessors to extract and use conventional commit prefixes from PR descriptions for categorization, or document that branch naming conventions should take precedence over commit message conventions to avoid confusion.

Copilot uses AI. Check for mistakes.
mise.toml Outdated
[tasks.changelog-tag]
description = "Generate changelog for a specific tag"
usage = '''
arg "<tag>" help="Git tag to generate changelog for (e.g., v0.1.0)" required=true
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The usage definition expects an argument named <tag> (line 348) but the script references it as ${usage_tag} (line 353) and %usage_tag% (line 358). According to mise documentation, usage arguments should be referenced with the usage_ prefix, but the angle brackets in the argument name definition might cause issues.

The argument definition should likely be arg "tag" without angle brackets, and the references ${usage_tag} and %usage_tag% are correct for accessing it.

Suggested change
arg "<tag>" help="Git tag to generate changelog for (e.g., v0.1.0)" required=true
arg "tag" help="Git tag to generate changelog for (e.g., v0.1.0)" required=true

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 2, 2025 01:04
bashandbone and others added 2 commits December 1, 2025 20:05
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copy link
Contributor

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

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


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

cat >> release_notes.md << EOF
**This is a pre-release version.** Install with:
\`\`\`bash
pip install --pre code-weaver
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The installation instruction suggests pip install --pre codeweaver but the package name should be code-weaver (with hyphen) for consistency with line 131. This inconsistency could lead users to install the wrong package.

Copilot uses AI. Check for mistakes.
run: |
if [ -n "${{ github.event.inputs.tag }}" ]; then
echo "Generating changelog for tag ${{ github.event.inputs.tag }}"
git-cliff --tag "${{ github.event.inputs.tag }}" --output CHANGELOG.md --prepend
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The --prepend flag is used here but not in the changelog-tag task (line 354). This inconsistency means that changelog-tag will overwrite CHANGELOG.md instead of prepending to it. For consistency, either add --prepend to the changelog-tag task or document that it intentionally overwrites the file.

Copilot uses AI. Check for mistakes.
Comment on lines +85 to +107
{ message = "^Merge pull request #[0-9]+ from .*/feat", group = "Features" },
{ message = "^Merge pull request #[0-9]+ from .*/feature", group = "Features" },
# Fixes - multiple patterns for fix-related branches
{ message = "^Merge pull request #[0-9]+ from .*/fix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/bugfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/hotfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/issue-", group = "Bug Fixes" },
# Documentation
{ message = "^Merge pull request #[0-9]+ from .*/docs", group = "Documentation" },
{ message = "^Merge pull request #[0-9]+ from .*/doc", group = "Documentation" },
# Performance
{ message = "^Merge pull request #[0-9]+ from .*/perf", group = "Performance" },
{ message = "^Merge pull request #[0-9]+ from .*/optimize", group = "Performance" },
# Refactoring
{ message = "^Merge pull request #[0-9]+ from .*/refactor", group = "Refactoring" },
# Testing
{ message = "^Merge pull request #[0-9]+ from .*/test", group = "Testing" },
# CI/CD and tooling
{ message = "^Merge pull request #[0-9]+ from .*/ci", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/workflow", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/build", group = "Build System" },
# Chores and maintenance
{ message = "^Merge pull request #[0-9]+ from .*/chore", group = "Maintenance" },
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The branch pattern matching uses partial matches (e.g., /feat, /feature) which will also match branches like /feature-xyz or /feats. While this might be intentional for flexibility, it could lead to unexpected categorization. Consider using more explicit patterns like /feat/ or /feature/ if branches are expected to follow a strict type/description format, or document that partial matching is intentional.

Suggested change
{ message = "^Merge pull request #[0-9]+ from .*/feat", group = "Features" },
{ message = "^Merge pull request #[0-9]+ from .*/feature", group = "Features" },
# Fixes - multiple patterns for fix-related branches
{ message = "^Merge pull request #[0-9]+ from .*/fix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/bugfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/hotfix", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/issue-", group = "Bug Fixes" },
# Documentation
{ message = "^Merge pull request #[0-9]+ from .*/docs", group = "Documentation" },
{ message = "^Merge pull request #[0-9]+ from .*/doc", group = "Documentation" },
# Performance
{ message = "^Merge pull request #[0-9]+ from .*/perf", group = "Performance" },
{ message = "^Merge pull request #[0-9]+ from .*/optimize", group = "Performance" },
# Refactoring
{ message = "^Merge pull request #[0-9]+ from .*/refactor", group = "Refactoring" },
# Testing
{ message = "^Merge pull request #[0-9]+ from .*/test", group = "Testing" },
# CI/CD and tooling
{ message = "^Merge pull request #[0-9]+ from .*/ci", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/workflow", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/build", group = "Build System" },
# Chores and maintenance
{ message = "^Merge pull request #[0-9]+ from .*/chore", group = "Maintenance" },
{ message = "^Merge pull request #[0-9]+ from .*/feat/", group = "Features" },
{ message = "^Merge pull request #[0-9]+ from .*/feature/", group = "Features" },
# Fixes - multiple patterns for fix-related branches
{ message = "^Merge pull request #[0-9]+ from .*/fix/", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/bugfix/", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/hotfix/", group = "Bug Fixes" },
{ message = "^Merge pull request #[0-9]+ from .*/issue-", group = "Bug Fixes" },
# Documentation
{ message = "^Merge pull request #[0-9]+ from .*/docs/", group = "Documentation" },
{ message = "^Merge pull request #[0-9]+ from .*/doc/", group = "Documentation" },
# Performance
{ message = "^Merge pull request #[0-9]+ from .*/perf/", group = "Performance" },
{ message = "^Merge pull request #[0-9]+ from .*/optimize/", group = "Performance" },
# Refactoring
{ message = "^Merge pull request #[0-9]+ from .*/refactor/", group = "Refactoring" },
# Testing
{ message = "^Merge pull request #[0-9]+ from .*/test/", group = "Testing" },
# CI/CD and tooling
{ message = "^Merge pull request #[0-9]+ from .*/ci/", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/workflow/", group = "CI/CD" },
{ message = "^Merge pull request #[0-9]+ from .*/build/", group = "Build System" },
# Chores and maintenance
{ message = "^Merge pull request #[0-9]+ from .*/chore/", group = "Maintenance" },

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 2, 2025 01:08
bashandbone and others added 2 commits December 1, 2025 20:09
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copy link
Contributor

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

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


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

- **Automatic categorization**: PRs are grouped by branch name patterns:
- `feat/` or `feature/` → Features
- `fix/`, `bugfix/`, `hotfix/`, `issue-` → Bug Fixes
- `optimize/`, `perf/` → Performance
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The example shows branch name pattern issue- (line 223) which would match branches like issue-123-fix-bug, but the corresponding commit parser in cliff.toml (line 95) uses from .*/issue- which requires the pattern to appear after a slash. This means a branch named issue-123 from a fork like user/issue-123 would be matched, but the documentation doesn't make this clear.

Consider clarifying in the documentation that the pattern matching is based on the full branch path after the repository name, not just the branch name itself.

Copilot uses AI. Check for mistakes.
conventional_commits = false
# Filter out commits that are not conventional
filter_unconventional = false
# Process merge commits - THIS IS KEY for PR-based changelog
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The comment on line 73 states "THIS IS KEY for PR-based changelog" but the actual setting split_commits = false is on line 74. The comment seems to indicate this is an important setting, but the description could be clearer about what split_commits does and why false is the correct value for PR-based changelogs.

Consider expanding the comment to explain: "Set to false to treat merge commits as single entries (important for PR-based changelogs)" for better maintainability.

Suggested change
# Process merge commits - THIS IS KEY for PR-based changelog
# Set to false to treat merge commits (such as PR merges) as single entries in the changelog.
# This is important for PR-based changelogs, as it ensures each PR appears as one changelog entry.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +66
git commit -m "docs: update CHANGELOG.md for ${{ github.event.inputs.tag }}"
else
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The commit message also uses unsanitized user input from github.event.inputs.tag. While less critical than command injection, this could allow malicious commit messages to be created.

Consider validating the tag input or using a sanitized version in the commit message.

Suggested change
git commit -m "docs: update CHANGELOG.md for ${{ github.event.inputs.tag }}"
else
# Sanitize the tag input: allow only alphanumerics, dots, dashes, and underscores
SAFE_TAG=$(echo "${{ github.event.inputs.tag }}" | grep -Eo '^[A-Za-z0-9._-]+$')
if [ -z "$SAFE_TAG" ]; then
echo "Tag input contains invalid characters. Using 'unknown-tag' in commit message."
git commit -m "docs: update CHANGELOG.md for unknown-tag"
else
git commit -m "docs: update CHANGELOG.md for $SAFE_TAG"
fi

Copilot uses AI. Check for mistakes.
@bashandbone bashandbone marked this pull request as draft December 2, 2025 02:19
@bashandbone
Copy link
Contributor Author

@copilot please address the following issues identified in these PR comments (#180):

Add a parser to incorporate squash merges. We will likely be moving to squash commits for pr merges soon.

Consider comments about potentially overwriting the changelog. I note that the https://github.com/knitli/codeweaver/pull/180#pullrequestreview-3527667922, but it merits further consideration, exploration, and documentation.

Ensure the correct package name is used. The pypi package is "code-weaver" all other references should still be "codeweaver" or "CodeWeaver".

There are several comments about malformed HEREDOC in release.yml -- please review carefully and ensure it is correct and optimally structured (commits may have already addressed these comments).

Consider https://github.com/knitli/codeweaver/pull/180#discussion_r2579248101 and update the task if you feel it's merited. We currently only use linux runners.

Conduct further research on proper usage tagging and syntax ([usage.jdx.dev](https://usage.jdx.dev/) and [mise.jdx.dev/tasks/task-arguments.html](https://mise.jdx.dev/tasks/task-arguments.html)) and ensure the syntax and usage (of usage) is correct.

Copy link
Contributor

Copilot AI commented Dec 2, 2025

@bashandbone I've opened a new pull request, #181, to work on those changes. Once the pull request is ready, I'll request review from you.

Addresses all review comments from PR #180:

**1. Add squash merge support**
- Added preprocessors to detect GitHub squash merge format: "type: description (#123)"
- Added commit parsers for conventional commit types in squash merges
- Updated template to handle both merge commits and squash merges
- Squash merges are now categorized by conventional commit prefix (feat, fix, etc.)

**2. Fix malformed HEREDOC in release.yml**
- Fixed broken HEREDOC at lines 128-138 that was missing proper closure
- Removed incomplete sed command
- Changed to non-quoted HEREDOC (EOF instead of 'EOF') to allow $VERSION expansion
- Properly escaped backticks in the heredoc content

**3. Fix package name consistency**
- Updated all pip install commands to use "code-weaver" (PyPI package name)
- Fixed docs/versioning.md lines 184, 189, 202, 208
- "CodeWeaver" remains for product name, "code-weaver" for PyPI package

**4. Remove Windows commands from mise tasks**
- Removed run_windows sections from all changelog tasks
- Project only uses Linux runners, Windows support not needed
- Simplified to bash-only scripts

**5. Fix mise task usage syntax**
- Updated usage syntax to use proper KDL block format with curly braces
- Removed redundant `required=true` (angle brackets indicate required)
- Added proper error checking with `${usage_tag:?}` expansion
- Follows mise documentation standards from usage.jdx.dev

**6. Document changelog overwrite behavior**
- Added comprehensive documentation about --prepend behavior in docs/versioning.md
- Added warnings about potential duplicate entries and git conflicts
- Added best practices section for changelog management
- Added inline comments in changelog.yml workflow explaining --prepend risks
- Documented that CHANGELOG.md should be treated as generated content

All changes maintain backward compatibility while preparing for the move to squash commits.
@bashandbone bashandbone marked this pull request as ready for review December 2, 2025 02:59
Copilot AI review requested due to automatic review settings December 2, 2025 02:59
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The new mise changelog tasks only define Unix run commands and dropped the previous run_windows implementation, which may break the existing Windows workflow; consider adding Windows variants for the new git-cliff–based tasks to keep cross-platform parity.
  • You pin [email protected] in the GitHub Actions workflows but use tools."cargo:git-cliff" = "latest" in mise.toml; aligning these to a single pinned version would avoid subtle differences in changelog output between local runs and CI.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `mise` changelog tasks only define Unix `run` commands and dropped the previous `run_windows` implementation, which may break the existing Windows workflow; consider adding Windows variants for the new git-cliff–based tasks to keep cross-platform parity.
- You pin `[email protected]` in the GitHub Actions workflows but use `tools."cargo:git-cliff" = "latest"` in `mise.toml`; aligning these to a single pinned version would avoid subtle differences in changelog output between local runs and CI.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

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

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


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

Comment on lines 305 to 309
run = '''
#!/usr/bin/env zsh
print -P "%F{209}[codeweaver]%f Generating changelog..."
mise x -- npm exec changeset version
#!/usr/bin/env bash
echo "Generating changelog..."
git-cliff
'''
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The run_windows script has been removed but Windows support appears incomplete. The new tasks only provide bash scripts (lines 306-342) without Windows equivalents. This breaks changelog generation on Windows systems.

Consider adding run_windows sections for each new task that use PowerShell or cmd syntax, similar to how other tasks in this file handle cross-platform support.

Copilot uses AI. Check for mistakes.
cat >> release_notes.md << EOF
**This is a pre-release version.** Install with:
\`\`\`bash
pip install --pre code-weaver
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

Inconsistent package name. The documentation uses codeweaver (no hyphen) in the pip install command, but elsewhere in the file it's been corrected to code-weaver (with hyphen). This line should use code-weaver for consistency.

pip install --pre code-weaver

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 2, 2025 03:05
bashandbone and others added 2 commits December 1, 2025 22:06
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copy link
Contributor

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

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


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

Comment on lines +106 to +109
git-cliff --strip header --tag "$CURRENT_TAG" "$PREVIOUS_TAG..$CURRENT_TAG" > changelog_section.md
else
# First release - get all commits
git-cliff --strip header --tag "$CURRENT_TAG" > changelog_section.md
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The --strip header flag is used on lines 106 and 109, but this flag doesn't exist in git-cliff 2.8.1. The correct flag is --strip all or --body to exclude the header. This will cause the release notes generation to fail.

Suggested change
git-cliff --strip header --tag "$CURRENT_TAG" "$PREVIOUS_TAG..$CURRENT_TAG" > changelog_section.md
else
# First release - get all commits
git-cliff --strip header --tag "$CURRENT_TAG" > changelog_section.md
git-cliff --strip all --tag "$CURRENT_TAG" "$PREVIOUS_TAG..$CURRENT_TAG" > changelog_section.md
else
# First release - get all commits
git-cliff --strip all --tag "$CURRENT_TAG" > changelog_section.md

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Copilot AI review requested due to automatic review settings December 2, 2025 03:09
bashandbone and others added 2 commits December 1, 2025 22:10
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
Co-authored-by: Copilot <[email protected]>
Signed-off-by: Adam Poulemanos <[email protected]>
@bashandbone bashandbone merged commit 3f79a2f into main Dec 2, 2025
7 of 8 checks passed
@bashandbone bashandbone deleted the claude/setup-codeweaver-changelog-01RCoZdCtStt7a1VwMtpMFE6 branch December 2, 2025 03:12
Copy link
Contributor

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

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


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

2. **Use branch name conventions**: Follow the naming patterns (`feat/`, `fix/`, etc.) for automatic categorization
3. **Update before releases**: Run `mise run changelog-update` before creating release tags to keep CHANGELOG.md current
4. **Squash vs Merge**: The setup works with both squash commits and merge commits, but handles them differently:
- **Squash merges** REQUIRE conventional commit prefixes (e.g., `feat:`, `fix:`) in the commit message for proper changelog categorization.
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] The documentation mentions that squash merges "REQUIRE conventional commit prefixes" but doesn't list all the supported prefixes. The cliff.toml configuration supports: feat, fix, docs, style, refactor, perf, test, build, ci, chore, and revert (line 96), but the documentation only lists a subset of branch patterns. Consider adding a complete list of conventional commit prefixes to help developers understand all options for squash commits.

Suggested change
- **Squash merges** REQUIRE conventional commit prefixes (e.g., `feat:`, `fix:`) in the commit message for proper changelog categorization.
- **Squash merges** REQUIRE conventional commit prefixes in the commit message for proper changelog categorization. Supported prefixes are: `feat:`, `fix:`, `docs:`, `style:`, `refactor:`, `perf:`, `test:`, `build:`, `ci:`, `chore:`, and `revert:`.

Copilot uses AI. Check for mistakes.
### Bug Fixes
- Verify sparse-only vector search fix (ISSUE-001) ([#176](https://github.com/knitli/codeweaver/pull/176))
- Fix Docker Compose CI test failures - correct Qdrant health endpoint ([#178](https://github.com/knitli/codeweaver/pull/178))
- chore: Add plans for server separation of services refactor to enable… ([#179](https://github.com/knitli/codeweaver/pull/179))
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

[nitpick] This changelog entry appears to be miscategorized. The PR description mentions "Add plans for server separation of services refactor" which sounds like planning/documentation rather than a bug fix. Based on the branch naming conventions in the documentation, this should likely be in "Documentation" or "Other Changes" rather than "Bug Fixes".

Copilot uses AI. Check for mistakes.
# 2. Mark squash merge commits for easier template detection
# Input: "feat: some feature (#123)"
# Output: "SQUASH | feat: some feature | #123"
{ pattern = '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+?\))?: (.+) \(#([0-9]+)\)$', replace = "SQUASH | ${1}${2}: ${3} | #${4}" },
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The regex pattern for squash merges with conventional commit prefixes is missing the optimize type which is mentioned in the documentation (docs/versioning.md line 223: optimize/, perf/ → Performance). Consider adding |optimize to the pattern to ensure consistency between branch naming conventions and squash merge commit parsing:

{ pattern = '^(feat|fix|docs|style|refactor|perf|optimize|test|build|ci|chore|revert)(\(.+?\))?: (.+) \(#([0-9]+)\)$', replace = "SQUASH | ${1}${2}: ${3} | #${4}" },
Suggested change
{ pattern = '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\(.+?\))?: (.+) \(#([0-9]+)\)$', replace = "SQUASH | ${1}${2}: ${3} | #${4}" },
{ pattern = '^(feat|fix|docs|style|refactor|perf|optimize|test|build|ci|chore|revert)(\(.+?\))?: (.+) \(#([0-9]+)\)$', replace = "SQUASH | ${1}${2}: ${3} | #${4}" },

Copilot uses AI. Check for mistakes.
Comment on lines +111 to +121

# === Squash Merge Parsers (conventional commits) ===
# After preprocessing, squash merges are in format: "SQUASH | type: description | #123"
{ message = "^SQUASH \\| feat", group = "Features" },
{ message = "^SQUASH \\| fix", group = "Bug Fixes" },
{ message = "^SQUASH \\| docs", group = "Documentation" },
{ message = "^SQUASH \\| perf", group = "Performance" },
{ message = "^SQUASH \\| refactor", group = "Refactoring" },
{ message = "^SQUASH \\| test", group = "Testing" },
{ message = "^SQUASH \\| build", group = "Build System" },
{ message = "^SQUASH \\| ci", group = "CI/CD" },
Copy link

Copilot AI Dec 2, 2025

Choose a reason for hiding this comment

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

The squash merge commit parsers are missing handlers for optimize and revert types, which are mentioned in the branch naming documentation and in the preprocessor regex (line 96). Add the following parsers to maintain consistency:

{ message = "^SQUASH \\| optimize", group = "Performance" },
{ message = "^SQUASH \\| revert", group = "Reverts" },

Also note that revert is already handled at line 120, but optimize is missing entirely from the squash parsers.

Copilot uses AI. Check for mistakes.
@github-actions github-actions bot locked and limited conversation to collaborators Dec 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

ci-cd Issues affecting ci/cd claude configuration documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants