* feat(parser): allow commits to be parsed by multiple parsers
Add an opt-in `continue` field to commit parsers. When set, parsing
keeps going after a parser matches, so a commit can be handled by more
than one parser in order (e.g. one sets the scope, the next sets the
group). Default behavior is unchanged: the first matching parser wins
and short-circuits.
* fix(parser): keep fields set by earlier parsers when a later one matches
A terminal parser (one without continue) used to overwrite group, scope
and default_scope wholesale, so a scope set by a preceding continue
parser was reset to None when a later parser only matched to set the
group. Make terminal parsers override just the fields they set, matching
the sha-based match path, so composing parsers augment instead of
clobbering each other.
Add a unit case and a test-multiple-commit-parsers fixture that derive a
scope from a git footer and then group by conventional type, and update
the docs with that real-world use case.
* docs(parser): shorten the multiple-parser section and note the match caveat
Trim the git.md write-up to a short example and move the fuller
walkthrough to tips and tricks. Document that parser matching evaluates
against the original commit, so a later parser cannot match on a field
set by an earlier one.
* fix(parser): preserve legacy terminal parser behavior
* docs: polish documentation
---------
Co-authored-by: Chris (ChrisJr404) <[email protected]>
Co-authored-by: Orhun Parmaksız <[email protected]>
* feat(changelog): add opt-in Markdown formatting for the output
* test(changelog): add fixture for opt-in Markdown formatting
Covers the [changelog] format = true path end to end. The template
renders sloppy but valid Markdown (star bullet markers and runs of
blank lines) and the fixture asserts that the formatter normalizes it,
converting the bullets to - and collapsing the blank lines.
* feat(changelog): enable GFM and dedupe header on formatted prepend
- Enable ENABLE_GFM in the Markdown formatter
- Detect Markdown from the --prepend extension too when deciding to format
- Strip the formatted header on prepend so it is not duplicated
- Document the mdformat postprocessor alternative in a note
---------
Co-authored-by: Chris (ChrisJr404) <[email protected]>
Co-authored-by: Orhun Parmaksız <[email protected]>
Add a configurable changelog header marker for use with --prepend.
The marker lets git-cliff reliably identify and remove the previously
rendered header when its template output changes between releases.
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
Represent `Opt::config` as `Option<PathBuf>` to distinguish an explicit config
from automatic discovery.
BREAKING CHANGE: `Opt::config` is now `Option<PathBuf>` instead of `PathBuf`
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
BREAKING CHANGE: Adds `pr_author` to `RemoteContributor` and author fields to
the public remote pull request types. Downstream code constructing these types
with struct literals must initialize the new fields
---------
Signed-off-by: Jimisola Laursen <[email protected]>
Co-authored-by: Orhun Parmaksız <[email protected]>
* feat(cli): support user-defined templates for --init
Add `--templates-dir <PATH>` (env: GIT_CLIFF_TEMPLATES_DIR) so `--init`
can look up user-defined templates, and `--list-templates` to print all
available template names (built-in and user-defined) for shell/editor
completion. A user template overrides a built-in template of the same name.
Closes#412
* refactor: clean up implementation
* refactor: remove tests
* style: fix formatting
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
* fix(bump): evaluate increment regexes against the commit subject only
When `conventional_commits` is disabled, git-cliff passed each commit's
full raw message (including the body) to `next_version`, so the custom
`custom_major_increment_regex`, `custom_minor_increment_regex` and
`no_increment_regex` matched against body text and could trigger an
unintended version bump.
For example, with `custom_major_increment_regex = "breaking"`, a commit
whose subject is `fix: real bug` but whose body contains the word
"breaking" was bumped to a major version instead of a patch.
Mirror the conventional-commits path: when `conventional_commits` is
disabled, feed only the commit subject (the first line) to the version
calculator. The conventional path is unchanged, so `BREAKING CHANGE:`
footer detection still relies on the full message.
Added a regression test that fails (major bump from body text) before
the change and passes (patch bump) after it.
Closes#1476
* test(bump): cover no_increment_regex subject-only in non-conventional mode
Extends the non-conventional subject-only coverage to no_increment_regex,
which the fix's doc-comment lists alongside the custom_major/minor regexes.
A commit whose body (but not subject) matches no_increment_regex must still
bump, because only the subject is evaluated when conventional commits are
disabled.
Ref: #1476
* docs(bump): clarify unconventional commit handling
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
* feat(git): ignore commits listed in .git-blame-ignore-revs
Adds a use_git_blame_ignore_revs config option that, when enabled,
excludes:
- commits whose hash (full or abbreviated) is listed in the
repository's .git-blame-ignore-revs file, and
- commits that only modify that file.
Mirrors what 'git blame --ignore-revs-file' already does for blame
output, letting large non-semantic commits (e.g. mass reformatting)
stay out of the changelog the same way they stay out of blame.
Closes#1084
* refactor(git): drop config option, always ignore .git-blame-ignore-revs
Per review feedback: a config flag is unnecessary here since the
behavior is a no-op when .git-blame-ignore-revs doesn't exist, so it
can just be applied unconditionally.
* docs(git): move .git-blame-ignore-revs mention to tips and tricks
Per review: git.md documents config options, and this isn't one
anymore (it's always-on behavior), so it doesn't belong there.
* docs(website): move .git-blame-ignore-revs to skipping commits page
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
* feat(template): add commit_groups filter for ordered group rendering
Tera's built-in `group_by(attribute="group")` filter backs its result with a
BTreeMap, so groups always come out in alphabetical (or emoji-codepoint)
order regardless of the order in which they were declared in
`commit_parsers`. This is the long-standing behavior tracked in #9 and the
reason most users prefix group names with `<!-- N -->` HTML comments and
strip them with `striptags` to coerce a particular order. The project's own
`cliff.toml` does this too.
This change keeps `group_by` untouched and adds a new filter,
`commit_groups`, that yields entries as an array of `{ name, commits }`
records, so iteration order is deterministic and template-defined.
The filter has two modes:
* No `groups` argument: groups appear in the order they first occur in the
input list, matching commit chronology.
* With a `groups=...` argument (an array of group names): groups are sorted
to match that order, with any unlisted groups appended afterward in
first-appearance order.
To make the common case ergonomic, `Changelog::build` now injects the
ordered list of group names from `commit_parsers` into the template context
as `commit_parsers_groups`, so users can write:
{% for entry in commits | commit_groups(groups=commit_parsers_groups) %}
### {{ entry.name }}
{% for commit in entry.commits %}- {{ commit.message }}
{% endfor %}
{% endfor %}
and get groups in the order they wrote them in `cliff.toml`. The default
templates and `group_by` callers are left as-is; this is purely additive.
A regression test using the reproducer from #9 verifies the order, plus
unit tests cover the no-args case, the `groups=` argument, the unknown-
group fallthrough, and the null-group skip behavior.
Closes#9
* style: cargo +nightly fmt
* refactor: switch to commit_groups filter for docs and config
* refactor: rename entry.name to entry.group for commit_groups filter
* chore: bring back custom ordering
* style: fix formatting
* chore: bring back striptags to default config
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
This commit adds a configurable `processing_order` option for custom changelog generation pipelines:
```toml
[git]
processing_order = [
"commit_preprocessors",
"split_commits",
"conventional_commits",
"commit_parsers",
"link_parsers",
]
```
Useful for cases where users want to apply custom commit preprocessors before splitting commits,
or when they want to run link parsers before commit parsers.
This change provides more flexibility in how the changelog generation pipeline is structured.
* feat(git): add configurable commit processing order
Co-authored-by: Daniel Lemus <[email protected]>
* refactor: fix imports
* style: run cargo fmt
* refactor: add missing import
* test: update the test case
* refactor: avoid unwrap in tests
* docs(website): link to processing steps
* refactor: remove process_commit_list
---------
Co-authored-by: Daniel Lemus <[email protected]>
Add `bump_type` field to the `Release` struct so that templates
can reference `{{ bump_type }}` and the JSON context (`-x`) includes
the determined version bump type ("major", "minor", "patch", or null).
The bump type is derived by comparing the previous and next semver
versions, or taken directly from the forced `bump_type` config when set.
* refactor: use NextVersion struct instead of tuple
* docs(website): add bump_type to context
---------
Co-authored-by: Orhun Parmaksız <[email protected]>
**git-cliff** now looks for the following configuration files in this order:
- `cliff.toml`
- `.cliff.toml`
- `.config/cliff.toml`
- `$HOME/cliff.toml`
- `$HOME/.cliff.toml`
- `$HOME/.config/cliff.toml`
Co-authored-by: Orhun Parmaksız <[email protected]>
* chore(deps): install ca-certificates in docker image
Required to support custom CA certificates at runtime via
update-ca-certificates in a CI pipeline.
Closes#1386
* docs: corporate trust GitLab CI/CD example
* feat(docker): apply latest tag to stable only
This patch adds an enablement check to `latest` to only apply on tags. Then introduces a new `nightly` tag for all other builds for any automated testing to look for for un-stable work.
* Modify Docker workflow for tagging and SHA extraction
Updated Docker workflow to use 'main' tag for builds and added SHA tag extraction step.
* Document Docker tags and CI generation rules
Add section on Docker tags and their generation rules.
* Enhance comments in docker.yml for SHA tag extraction
Add comments to clarify the jq script for SHA tag extraction.
* Rename SHA tag step and update image reference
* Update website/docs/docker.md
* Update website/docs/docker.md
---------
Co-authored-by: Orhun Parmaksız <[email protected]>