Skip to content

Conversation

@arkanoider
Copy link
Collaborator

@arkanoider arkanoider commented Sep 21, 2025

@grunch ,

  • fixed wrong key sended in admin add solver command
  • removed first committer part from cliff.toml and added the emoticons for different parts as in mostro and mostro-core

Now commit with changelog is created by github actions and then committed remotely, so in the end there is one more automatic commit, but we removed git cliff boilerplate from cargo.toml. Let me know if you like this or we can use the same trick everywhere and let the commit be made locally without the automatic one.

This new way has pros:

  • no more problems with gh api rate limit
  • no more boilerplate code in cargo.toml to preprocess and commit changelog

cons:

  • one commit more is generated for changelog

in both cases then we can have releases autobuild with nice changelog!

Summary by CodeRabbit

  • Documentation

    • Revamped changelog formatting with clearer grouped headings, emoji-labeled categories, improved PR/mention linking, and newest-first ordering.
    • Contributors section now lists all contributors with contribution notes.
  • Chores

    • Removed GitHub token from remote config.
    • Expanded changelog/config options for commit grouping, preprocessing, linking, filtering, and sorting.
  • Refactor

    • Centralized admin direct-message handling for dispute workflows via a shared messaging helper.

removed from cliff.toml the redundant part of first committer
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 21, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Release config (cliff.toml) expanded with grouped commit_parsers, link parsers, and many [git] options while removing remote.github.token. Code adds pub async fn admin_send_dm in src/util.rs and replaces multiple direct send_dm calls in src/cli/take_dispute.rs to use the new helper.

Changes

Cohort / File(s) Summary
Release changelog configuration
cliff.toml
Removed [remote.github].token. Added grouped commit_parsers, a postprocessor to strip HTML comments, renamed contributors header and removed first-time filter, and expanded [git] with conventional_commits, filter_unconventional, split_commits, commit_preprocessors, filter_commits, topo_order, sort_commits, and link_parsers.
Admin DM helper and call-sites
src/util.rs, src/cli/take_dispute.rs
Added pub async fn admin_send_dm(ctx: &Context, msg: String) -> anyhow::Result<()> to src/util.rs. Replaced direct send_dm invocations in src/cli/take_dispute.rs with util::admin_send_dm, removing manual passing of client/keys/pubkey at those sites.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as Admin CLI
  participant Take as take_dispute.rs
  participant Util as util::admin_send_dm
  participant Msg as send_dm

  CLI->>Take: run admin dispute command
  Take->>Util: admin_send_dm(ctx, message)
  Util->>Msg: send_dm(ctx.client, ctx.identity_keys, ctx.trade_keys, ctx.pubkey, message)
  Msg-->>Util: result
  Util-->>Take: propagate result
  Take-->>CLI: return outcome
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Catrya
  • grunch

Poem

I hop through diffs with whiskers bright,
Parsers grouped and tokens out of sight.
One helper now delivers every plea,
A tidy burrow of changelog glee. 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly and concisely states the primary functional change — correcting the wrong key used in execute_admin_add_solver — which matches the code edits in src/cli/take_dispute.rs and the new admin_send_dm helper in src/util.rs; the additional cliff.toml config changes are ancillary and do not make the title misleading.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 45e5385 and 8871a4a.

📒 Files selected for processing (1)
  • cliff.toml (3 hunks)

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
Contributor

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

🧹 Nitpick comments (2)
src/cli/take_dispute.rs (1)

23-31: Optional: DRY up repeated send_dm patterns for admin disputes.

All admin functions pass the same params except the message. Extract a helper to reduce repetition and future key mix-ups.

// helper (place near other CLI utils)
async fn admin_send_dm(ctx: &Context, msg: String) -> anyhow::Result<()> {
    send_dm(&ctx.client, Some(&ctx.context_keys), &ctx.trade_keys, &ctx.mostro_pubkey, msg, None, false).await?;
    Ok(())
}

// usage inside execute_admin_add_solver / cancel / settle / take
admin_send_dm(ctx, take_dispute_message).await?;
cliff.toml (1)

80-97: Solid commit_parsers; consider a few regex nits and making Security case-insensitive.

These small adjustments improve match accuracy without changing intent.

 commit_parsers = [
-  { message = "^feat", group = "<!-- 0 -->🚀 Features" },
-  { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
-  { message = "^doc", group = "<!-- 3 -->📚 Documentation" },
+  { message = "^feat", group = "<!-- 0 -->🚀 Features" },
+  { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
+  { message = "^docs?", group = "<!-- 3 -->📚 Documentation" },
   { message = "^perf", group = "<!-- 4 -->⚡ Performance" },
   { message = "^refactor", group = "<!-- 2 -->🚜 Refactor" },
   { message = "^style", group = "<!-- 5 -->🎨 Styling" },
   { message = "^test", group = "<!-- 6 -->🧪 Testing" },
   { message = "^chore\\(release\\): prepare for", skip = true },
   { message = "^chore\\(deps.*\\)", skip = true },
   { message = "^chore\\(pr\\)", skip = true },
   { message = "^chore\\(pull\\)", skip = true },
-  { message = "^chore|^ci", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
-  { body = ".*security", group = "<!-- 8 -->🛡️ Security" },
+  { message = "^(chore|ci|build)", group = "<!-- 7 -->⚙️ Miscellaneous Tasks" },
+  { body = "(?i)security", group = "<!-- 8 -->🛡️ Security" },
   { message = "^revert", group = "<!-- 9 -->◀️ Revert" },
   { message = ".*", group = "<!-- 10 -->💼 Other" },
 ]
  • Note: With the current changelog template, groups aren’t rendered; only a flat “commits” list is shown. If you want the new grouping to appear, switch the template to iterate commit_groups, e.g.:
# inside [changelog].body template
{%- for group in commit_groups -%}
### {{ group.title }}
{%- for commit in group.commits -%}
* {{ commit.message | split(pat="\n") | first | trim }}{% if commit.remote.username %} by @{{ commit.remote.username }}{% endif %}{% if commit.remote.pr_number %} in [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}){% endif %}
{%- endfor -%}
{%- endfor -%}
  • Also confirm it’s intentional that commit_preprocessors rewrite “Merge pull request #…” to start with “feat:” so merges show under Features.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c4741c and e91dcdf.

📒 Files selected for processing (2)
  • cliff.toml (2 hunks)
  • src/cli/take_dispute.rs (1 hunks)
🔇 Additional comments (2)
cliff.toml (1)

45-55: Contributors section tweak looks good.

Renaming to “Contributors” and removing first-timer filtering aligns with the PR goals; the surrounding {% if github %} guard keeps this safe when API data is unavailable.

Confirm your CI environment provides sufficient GitHub API access (e.g., GITHUB_TOKEN) so contributors populate; otherwise the section will correctly omit itself.

src/cli/take_dispute.rs (1)

23-31: Correct key: context_keys for AdminAddSolver — verified

All send_dm calls in src/cli/take_dispute.rs use ctx.context_keys (lines 23, 51, 79, 112); remaining identity_keys occurrences are in non-admin flows/util.rs and are expected.

@arkanoider
Copy link
Collaborator Author

arkanoider commented Sep 21, 2025

All admin functions pass the same params except the message. Extract a helper to reduce repetition and future key mix-ups.

Can you explicitate which functions? It does not seem that from cli they only get the message as parameter @coderabbitai

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for admin functions in the codebase
echo "=== Searching for admin functions ==="
rg -n "fn.*admin" --type rust

echo -e "\n=== Looking for execute_admin functions specifically ==="
rg -n "execute_admin" --type rust -A 5 -B 2

echo -e "\n=== Examining the file with admin functions ==="
fd "take_dispute.rs" --exec cat {}

Length of output: 5910


@arkanoider You're absolutely right to question my previous suggestion. Let me be more explicit about what I observed:

The admin functions I was referring to are these four functions in src/cli/take_dispute.rs:

  1. execute_admin_add_solver(npubkey: &str, ctx: &Context)
  2. execute_admin_cancel_dispute(dispute_id: &Uuid, ctx: &Context)
  3. execute_admin_settle_dispute(dispute_id: &Uuid, ctx: &Context)
  4. execute_take_dispute(dispute_id: &Uuid, ctx: &Context)

You're correct that from the CLI perspective, they don't just differ by message - they have different input parameters (npubkey vs dispute_id).

What I was observing is that all these functions share an identical send_dm call pattern:

send_dm(
    &ctx.client,
    Some(&ctx.context_keys),
    &ctx.trade_keys,
    &ctx.mostro_pubkey,
    [the_message], // Only this varies
    None,
    false,
)

The commonality is in the send_dm parameters, not in the CLI function signatures. However, upon closer inspection, each function also has unique logic:

  • Different Action types (AdminAddSolver, AdminCancel, AdminSettle, AdminTakeDispute)
  • Different message construction (some with payload, some without)
  • Different input validation needs

So you're right - my initial suggestion for a helper function was overly aggressive. The current approach is actually quite reasonable, and the key fix (using context_keys instead of identity_keys) was the right solution to prevent future mix-ups.

@arkanoider
Copy link
Collaborator Author

  • Note: With the current changelog template, groups aren’t rendered; only a flat “commits” list is shown. If you want the new grouping to appear, switch the template to iterate commit_groups, e.g.:

Explain this with an example please! @coderabbitai

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Examine the cliff.toml file to see the current template
echo "=== Current cliff.toml content ==="
cat cliff.toml

echo -e "\n=== Looking for template section specifically ==="
rg -n -A 10 -B 2 "\[.*template\]" cliff.toml || echo "No template section found"

echo -e "\n=== Looking for any template-related content ==="
rg -n -A 5 -B 2 "template" cliff.toml

Length of output: 6294


@arkanoider Here's a detailed explanation with examples of the changelog template issue:

The Problem

The current cliff.toml has defined commit groups with emojis:

commit_parsers = [
  { message = "^feat", group = "<!-- 0 -->🚀 Features" },
  { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
  { message = "^doc", group = "<!-- 3 -->📚 Documentation" },
  # ... etc
]

But the template is ignoring these groups and just iterating over all commits in a flat list:

Current template (problematic):

{% for commit in commits %}
  {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
  {%- else -%}
    {%- set commit_message = commit.message -%}
  {%- endif -%}
  * {{ commit_message | split(pat="\n") | first | trim }}\
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in \
      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
    {%- endif %}
{%- endfor -%}

The Solution

Change the template to iterate over commit_groups instead:

Fixed template (grouped):

{%- for group, commits in commit_groups %}
## {{ group | trim_start_matches(pat="<!-- ") | trim_end_matches(pat=" -->") }}
{% for commit in commits -%}
  {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
  {%- else -%}
    {%- set commit_message = commit.message -%}
  {%- endif -%}
  * {{ commit_message | split(pat="\n") | first | trim }}\
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in \
      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
    {%- endif %}
{% endfor -%}
{%- endfor -%}

Output Comparison

Current output (flat list):

## What's Changed

* Add new solver validation feature by @user1 in #123
* Fix authentication bug by @user2 in #124  
* Update documentation by @user3 in #125
* Refactor code structure by @user4 in #126

With grouped template (organized):

## What's Changed

## 🚀 Features
* Add new solver validation feature by @user1 in #123

## 🐛 Bug Fixes  
* Fix authentication bug by @user2 in #124

## 📚 Documentation
* Update documentation by @user3 in #125

## 🚜 Refactor
* Refactor code structure by @user4 in #126

The key difference is that commit_groups is a map where each key is a group name (like "🚀 Features") and each value is an array of commits that belong to that group, allowing you to create organized sections in your changelog.

@arkanoider
Copy link
Collaborator Author

arkanoider commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.
🧩 Analysis chain

@arkanoider Here's a detailed explanation with examples of the changelog template issue:

The Problem

The current cliff.toml has defined commit groups with emojis:

commit_parsers = [
  { message = "^feat", group = "<!-- 0 -->🚀 Features" },
  { message = "^fix", group = "<!-- 1 -->🐛 Bug Fixes" },
  { message = "^doc", group = "<!-- 3 -->📚 Documentation" },
  # ... etc
]

But the template is ignoring these groups and just iterating over all commits in a flat list:

Current template (problematic):

{% for commit in commits %}
  {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
  {%- else -%}
    {%- set commit_message = commit.message -%}
  {%- endif -%}
  * {{ commit_message | split(pat="\n") | first | trim }}\
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in \
      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
    {%- endif %}
{%- endfor -%}

The Solution

Change the template to iterate over commit_groups instead:

Fixed template (grouped):

{%- for group, commits in commit_groups %}
## {{ group | trim_start_matches(pat="<!-- ") | trim_end_matches(pat=" -->") }}
{% for commit in commits -%}
  {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
  {%- else -%}
    {%- set commit_message = commit.message -%}
  {%- endif -%}
  * {{ commit_message | split(pat="\n") | first | trim }}\
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in \
      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
    {%- endif %}
{% endfor -%}
{%- endfor -%}

Output Comparison

Current output (flat list):

## What's Changed

* Add new solver validation feature by @user1 in #123
* Fix authentication bug by @user2 in #124  
* Update documentation by @user3 in #125
* Refactor code structure by @user4 in #126

With grouped template (organized):

## What's Changed

## 🚀 Features
* Add new solver validation feature by @user1 in #123

## 🐛 Bug Fixes  
* Fix authentication bug by @user2 in #124

## 📚 Documentation
* Update documentation by @user3 in #125

## 🚜 Refactor
* Refactor code structure by @user4 in #126

The key difference is that commit_groups is a map where each key is a group name (like "🚀 Features") and each value is an array of commits that belong to that group, allowing you to create organized sections in your changelog.

Can you prepare a commit for this? @coderabbitai

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 21, 2025

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

@arkanoider I'll prepare the commit to fix the changelog template. Let me first examine the current template structure and then provide the updated version.

Here's the commit that updates the cliff.toml template to use grouped commits instead of a flat list:

# git-cliff ~ default configuration file
# https://git-cliff.org/docs/configuration
#
# Lines starting with "#" are comments.
# Configuration options are organized into tables and keys.
# See documentation for more information on available options.

[changelog]
# template for the changelog body
# https://keats.github.io/tera/docs/#introduction
body = """
{%- macro remote_url() -%}
  https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}

{% macro print_commit(commit) -%}
  {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
  {%- else -%}
    {%- set commit_message = commit.message -%}
  {%- endif -%}
  * {{ commit_message | split(pat="\n") | first | trim }}\
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in \
      [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }}) \
    {%- endif %}
{%- endmacro -%}

## What's Changed
{%- if commit_groups -%}
{%- for group, commits in commit_groups %}
{%- if commits | length > 0 %}
### {{ group | trim_start_matches(pat="<!-- ") | trim_end_matches(pat=" -->") }}
{% for commit in commits -%}
{{ self::print_commit(commit=commit) }}
{% endfor -%}
{%- endif -%}
{%- endfor -%}
{%- else -%}
{% for commit in commits -%}
{{ self::print_commit(commit=commit) }}
{%- endfor -%}
{%- endif -%}

{%- if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
{%- raw %}

## New Contributors
{%- endraw -%}
{%- endif %}

{% for contributor in github.contributors | filter(attribute="is_first_time", value=true) %}
  * @{{ contributor.username }} made their first contribution in [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }})
{%- endfor %}

**Full Changelog**: {{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}
"""

# The rest of the configuration remains the same...

Key changes made:

  1. Added a macro print_commit to avoid code duplication
  2. Template now checks for commit_groups and iterates over them first
  3. Fallback to flat commits list if commit_groups is not available (backwards compatibility)
  4. Group headers use the emoji names defined in commit_parsers
  5. Preserved all existing functionality (PR titles, usernames, PR numbers)

This will produce organized changelog sections like:

## What's Changed
### 🚀 Features
* Add new solver validation feature by @user1 in #123

### 🐛 Bug Fixes  
* Fix authentication bug by @user2 in #124

### 📚 Documentation
* Update documentation by @user3 in #125

The template maintains backward compatibility, so if commit_groups isn't populated for any reason, it falls back to the original flat list format.


🏁 Script executed:

#!/bin/bash
# Read the current cliff.toml file to see the exact template structure
echo "=== Current cliff.toml content ==="
cat cliff.toml

echo -e "\n=== Extract just the template section ==="
rg -A 20 -B 2 "body = " cliff.toml

Length of output: 7834


🚀 Features"

  • The template has a complex structure with GPG verification instructions at the top
  • The remote_url macro is defined at the bottom
  • There's a Contributors section that shows all contributors (not just first-time)
    [analysis]
    I need to:
  1. Replace the {% for commit in commits %} loop with a {% for group, commits in commit_groups %} loop
  2. Add group headers for each category
  3. Preserve all existing functionality including the GPG verification section
  4. Maintain the same commit formatting
  5. Keep the Contributors section unchanged
  6. Provide the exact file content that should replace the current template
    [actions]
  • Create the updated cliff.toml template that uses commit_groups
  • Ensure backward compatibility
  • Present it as a complete file replacement for the commit
    -->

@arkanoider Here's the complete updated cliff.toml file that fixes the template to use grouped commits:

# git-cliff ~ configuration file
# https://git-cliff.org/docs/configuration

[remote.github]
owner = "MostroP2P"
repo = "mostro-cli"

[changelog]
# A Tera template to be rendered for each release in the changelog.
# See https://keats.github.io/tera/docs/#introduction
body = """
## Verifying the Release
In order to verify the release, you'll need to have gpg or gpg2 installed on your system. Once you've obtained a copy (and hopefully verified that as well), you'll first need to import the keys that have signed this release if you haven't done so already:
```bash
curl https://raw.githubusercontent.com/MostroP2P/mostro/main/keys/negrunch.asc | gpg --import

Once you have the required PGP keys, you can verify the release (assuming manifest.txt.sig and manifest.txt are in the current directory) with:

gpg --verify manifest.txt.sig manifest.txt

gpg: Firmado el jue 03 ago 2023 15:07:05 -03
gpg:                usando RSA clave 1E41631D137BA2ADE55344F73852B843679AD6F0
gpg: Firma correcta de "Francisco Calderón <fjcalderon@gmail.com>" [absoluta]

That will verify the signature of the manifest file, which ensures integrity and authenticity of the archive you've downloaded locally containing the binaries. Next, depending on your operating system, you should then re-compute the sha256 hash of the archive with shasum -a 256 <filename>, compare it with the corresponding one in the manifest file, and ensure they match exactly.

What's Changed

{%- if version %} in {{ version }}{%- endif -%}
{%- if commit_groups -%}
{%- for group, commits in commit_groups %}
{%- if commits | length > 0 %}

{{ group | trim_start_matches(pat="") }}

{% for commit in commits -%}
{% if commit.remote.pr_title -%}
{%- set commit_message = commit.remote.pr_title -%}
{%- else -%}
{%- set commit_message = commit.message -%}
{%- endif -%}

  • {{ commit_message | split(pat="\n") | first | trim }}
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in
    [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})
    {%- endif %}
    {% endfor -%}
    {%- endif -%}
    {%- endfor -%}
    {%- else -%}
    {% for commit in commits -%}
    {% if commit.remote.pr_title -%}
    {%- set commit_message = commit.remote.pr_title -%}
    {%- else -%}
    {%- set commit_message = commit.message -%}
    {%- endif -%}
  • {{ commit_message | split(pat="\n") | first | trim }}
    {% if commit.remote.username %} by @{{ commit.remote.username }}{%- endif -%}
    {% if commit.remote.pr_number %} in
    [#{{ commit.remote.pr_number }}]({{ self::remote_url() }}/pull/{{ commit.remote.pr_number }})
    {%- endif %}
    {%- endfor -%}
    {%- endif -%}

{%- if github -%}
{% if github.contributors | length != 0 %}
{% raw %}\n{% endraw -%}

Contributors

{%- endif %}
{% for contributor in github.contributors %}

  • @{{ contributor.username }} made their contribution
    {%- if contributor.pr_number %} in
    [#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }})
    {%- endif %}
    {%- endfor -%}
    {%- endif -%}

{% if version %}
{% if previous.version %}
Full Changelog: {{ self::remote_url() }}/compare/{{ previous.version }}...{{ version }}
{% endif %}
{% else -%}
{% raw %}\n{% endraw %}
{% endif %}

{%- macro remote_url() -%}
https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}
{%- endmacro -%}
"""

Remove leading and trailing whitespaces from the changelog's body.

trim = true

A Tera template to be rendered as the changelog's footer.

See https://keats.github.io/tera/docs/#introduction

footer = """

"""

An array of regex based postprocessors to modify the changelog.

Replace the placeholder <REPO> with a URL.

postprocessors = []

regex for parsing and grouping commits

commit_parsers = [
{ message = "^feat", group = "🚀 Features" },
{ message = "^fix", group = "🐛 Bug Fixes" },
{ message = "^doc", group = "📚 Documentation" },
{ message = "^perf", group = "⚡ Performance" },
{ message = "^refactor", group = "🚜 Refactor" },
{ message = "^style", group = "🎨 Styling" },
{ message = "^test", group = "🧪 Testing" },
{ message = "^chore\(release\): prepare for", skip = true },
{ message = "^chore\(deps.*\)", skip = true },
{ message = "^chore\(pr\)", skip = true },
{ message = "^chore\(pull\)", skip = true },
{ message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" },
{ body = ".security", group = "🛡️ Security" },
{ message = "^revert", group = "◀️ Revert" },
{ message = ".
", group = "💼 Other" },
]

[git]

Parse commits according to the conventional commits specification.

See https://www.conventionalcommits.org

conventional_commits = true

Exclude commits that do not match the conventional commits specification.

filter_unconventional = false

Split commits on newlines, treating each line as an individual commit.

split_commits = false

An array of regex based parsers to modify commit messages prior to further processing.

commit_preprocessors = [
{ pattern = 'Merge pull request #([0-9]+)', replace = "feat: merge pull request #$1" },
]

Exclude commits that are not matched by any commit parser.

filter_commits = false

Order releases topologically instead of chronologically.

topo_order = false

Order of commits in each group/release within the changelog.

Allowed values: newest, oldest

sort_commits = "newest"

Enable link parsing for PR references and user mentions

link_parsers = [
{ pattern = "Merge pull request #([0-9]+)", href = "https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}/pull/$1" },
{ pattern = "#([0-9]+)", href = "https://github.com/{{ remote.github.owner }}/{{ remote.github.repo }}/pull/$1" },
{ pattern = "@([a-zA-Z0-9_-]+(?:\[[^\\]]+\])?)", href = "https://github.com/$1" },
]


**Key changes made:**

1. **Added conditional logic** to check if `commit_groups` exists
2. **Group iteration**: `{%- for group, commits in commit_groups %}`
3. **Group headers**: `### {{ group | trim_start_matches(pat="<!-- ") | trim_end_matches(pat=" -->") }}`
4. **Fallback compatibility**: If `commit_groups` doesn't exist, falls back to the original flat list
5. **Preserved all existing functionality** including GPG verification section, contributors section, and commit formatting

Now your changelog will show organized sections like:

```markdown
## What's Changed in v1.2.0

### 🚀 Features
* Add new solver validation feature by @user1 in #123

### 🐛 Bug Fixes  
* Fixed wrong key in execute_admin_add_solver function by @arkanoider in #137

### 🚜 Refactor
* Improve code structure by @user3 in #125

This maintains backward compatibility while enabling the organized changelog format you want!

@arkanoider arkanoider merged commit 70737c6 into main Sep 21, 2025
1 check was pending
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants