This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file provides **project-specific guidance for AI agents** (and other automated tools) working on the `commitizen` repository.
Follow these instructions in addition to any higher-level system or tool rules.
This file is the auto-loaded entry point for AI agents working on the `commitizen` repository. It holds the rules an agent needs in **every** session. Deeper guidance lives in:
## Project Overview
- [Contributing](docs/contributing/contributing.md) — setup, dev workflow, PR lifecycle.
- **Preserve public behavior and CLI UX** — no breaking changes to APIs, CLI flags, or exit codes unless explicitly requested.
- **Update or add tests/docs** when you change user-facing behavior.
- **Commit messages** must follow [Conventional Commits](https://www.conventionalcommits.org/) (enforced by commitizen itself).
- **Pull requests** must follow the [Pull Request Guidelines](docs/contributing/pull_request.md) and the template in `.github/pull_request_template.md`.
## Setup and Validation
> Full contributor guidelines (prerequisites, workflow, PR process): [`docs/contributing/contributing.md`](docs/contributing/contributing.md).
### Bootstrap
```bash
uv sync --frozen --group base --group test --group linters
uv run poe setup-pre-commit # install git hooks (uses prek, a pre-commit runner)
```
### Local commands
- **Format**: `uv run poe format` (runs `ruff check --fix` then `ruff format`)
- **Lint**: `uv run poe lint` (runs `ruff check` then `mypy`)
- **Test**: `uv run poe test` (runs `pytest -n auto`)
- **CI-equivalent**: `uv run poe ci` (commit check + pre-commit hooks via `prek` + test with coverage)
- **Full local check**: `uv run poe all` (format + lint + check-commit + coverage)
Follow these instructions in addition to any higher-level tool or system rules.
Always run at least `uv run ruff check --fix . && uv run ruff format .` before pushing. CI will fail if the formatter modifies any files.
## Project at a glance
### CI pipeline
- CI runs `poe ci` on a matrix of Python 3.10–3.14 × ubuntu/macos/windows.
- Pre-commit hooks are defined in `.pre-commit-config.yaml` and run via [`prek`](https://github.com/j178/prek) (a `pre-commit` compatible runner).
- The matrix is **fail-fast**: inspect the earliest failing job that completed; others are cancelled.
### Common CI failure patterns
- **"Format Python code...Failed"**: Run `uv run poe format` and commit the result.
- **mypy `[arg-type]` on TypedDict**: Dynamically-constructed dicts (e.g., from `pytest.mark.parametrize`) passed to TypedDict-typed params need `# type: ignore[arg-type]`.
- **"pathspec 'vX.Y.Z' did not match"**: `.pre-commit-config.yaml` pins a tag of this repo. Rebase onto master to pick up the tag.
- **`VersionProtocol` + `issubclass`**: This Protocol has non-method members (properties), so `issubclass()` raises `TypeError`. Use `hasattr` checks for runtime validation.
- **Project**: `commitizen` — Python CLI for enforcing Conventional Commits, automating version bumps, and generating changelogs.
- **Library + CLI**: code is reachable both via `cz` and `import commitizen`.
- **Cross-platform**: tests run on Linux/macOS/Windows × Python 3.10–3.14. Avoid POSIX-only assumptions (paths, subprocesses, line endings).
For recurring task types (add a provider, deprecate an API, regenerate snapshots, ...), use the matching playbook in [For AI Agents § Playbooks](docs/contributing/agents/index.md#playbooks) instead of reinventing the workflow.
## Do not touch
These files are regenerated by Commitizen-specific tooling, so hand-edits get reverted on the next release or doc rebuild:
- `CHANGELOG.md` — produced by `cz changelog`. Hand-edits will be overwritten on the next release.
- `commitizen/__version__.py` — bumped by `cz bump` via the configured version provider.
- `.pre-commit-config.yaml:rev:` lines under the `Commitizen` repo — bumped by `cz bump` (`version_files` in `pyproject.toml`).
- `docs/images/cli_help/*.svg` and `docs/images/cli_interactive/*.gif` — regenerated by `uv run poe doc:screenshots`. See the [update-snapshots playbook](docs/contributing/agents/playbooks/update-snapshots.md).
- `tests/**/*` snapshot files used by `pytest-regressions` — regenerated via `uv run poe test:regen`.
## Mandatory PR reminders
These are easy to miss when working from an agent and are required by the PR template:
- **Types**: Preserve or improve existing type hints.
- **Output**: Use `commitizen/out.py`; do not add noisy logging.
1. **Complete the AI disclosure**. Check "Was generative AI tooling used to co-author this PR?" and fill in the `Generated-by:` trailer with the tool name. Details: [Pull Request Guidelines § AI-Assisted Contributions](docs/contributing/pull_request.md#ai-assisted-contributions).
2. **Run `uv run poe all` before pushing**. This is the command named in the PR template; it auto-formats then runs the same lint/check/test pipeline as CI. To mirror CI exactly afterwards, run `uv run poe ci` (uses `prek`, does not auto-format).
3. **Fill in "Steps to Test This Pull Request"** with the exact commands you ran locally — the maintainers re-run them.
## When Unsure
## When unsure
- Prefer **reading tests and documentation first** to understand the expected behavior.
- When behavior is ambiguous, **assume backward compatibility** with current tests and docs is required.
When behavior is ambiguous, assume **backward compatibility with current tests and docs** is required. Add a deprecation window instead of breaking it; see the [deprecate-public-api playbook](docs/contributing/agents/playbooks/deprecate-public-api.md).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
These pages are written for AI agents contributing to Commitizen. Human contributors may also find them useful as a quick reference. They **complement** the existing human-facing contributor docs rather than replace them — anything covered by the human docs is linked, not restated.
> If you are an AI agent looking to **use** Commitizen as a tool (validate
> commit messages, bump versions in a downstream project), see the skill
> definition at `.agents/skills/commitizen/SKILL.md` in the repo root.
> The pages here are for working **on** Commitizen itself.
## When to read what
| You want to... | Read |
|---|---|
| Set up a local dev environment | [Contributing](../contributing.md#prerequisites-setup) |
| Look up a poe command | [Contributing TL;DR](../contributing_tldr.md#command-cheat-sheet) |
| Understand the codebase layout and extension points | [Architecture Overview](../architecture.md) |
| Open a pull request | [Pull Request Guidelines](../pull_request.md) and the [PR template](https://github.com/commitizen-tools/commitizen/blob/master/.github/pull_request_template.md) |
| Pick the right test selector for a change | [Validation Guide](validation.md#targeted-test-map) |
| Recover from a CI failure | [Validation Guide](validation.md#ci-failure-recipes) |
| Implement a recurring task type | [Playbooks](#playbooks) |
The repo-root [`AGENTS.md`](https://github.com/commitizen-tools/commitizen/blob/master/AGENTS.md) is the auto-loaded entry point for most agent tools. It holds the rules an agent needs in every session; this page is the deeper reference.
## Playbooks
Recipes for recurring task types. Each playbook is self-contained: trigger, files to read first, ordered steps, verification commands, and known pitfalls. They link out to the human-facing concept docs rather than restating concepts.
- [Add a version provider](playbooks/add-version-provider.md)
- [Add a changelog format](playbooks/add-changelog-format.md)
- [Add or modify a CLI flag](playbooks/add-cli-flag.md)
- [Deprecate a public API](playbooks/deprecate-public-api.md)
- [Update generated snapshots and screenshots](playbooks/update-snapshots.md)
If no playbook matches, read the [Architecture Overview](../architecture.md) for the relevant subsystem and follow 1-2 existing examples in the same directory before changing code.
## Updating these pages
Treat these pages like any other code change: open a PR, follow the template, run `uv run poe doc:build` to verify the mkdocs build, and check internal links. If you find yourself restating something that already lives in a human-facing doc, link to it instead and shorten the agent doc.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A changelog format handles parsing and rendering a `CHANGELOG.<ext>` file in a specific markup language. End-user documentation: [Changelog command](../../../commands/changelog.md). Built-ins are `markdown` (default), `asciidoc`, `textile`, `restructuredtext`.
- `commitizen/changelog_formats/base.py:BaseFormat` — provides a default `get_metadata_from_file` that walks the file once for **line-anchored** titles. You override `parse_version_from_title` and `parse_title_level` to fit your markup.
- A close-match existing format:
- Line-anchored heading prefix (`#`, `=`, `h1.`): `commitizen/changelog_formats/markdown.py`, `asciidoc.py`, or `textile.py` — each overrides only the two `parse_*` methods.
- Multi-line titles (overline/underline, as in reStructuredText): `commitizen/changelog_formats/restructuredtext.py` — overrides `get_metadata_from_file` directly because the base class assumes one-line titles.
- `commitizen/templates/` — Jinja2 templates named `CHANGELOG.<ext>.j2` (e.g. `CHANGELOG.md.j2`, `CHANGELOG.rst.j2`, `CHANGELOG.adoc.j2`); the file extension comes from the `extension` class attribute, not the format name.
- `tests/test_changelog_format_<name>.py` — every format has parity tests; copy the closest one.
## Steps
1. **Create the format module** at `commitizen/changelog_formats/<name>.py`. Subclass `BaseFormat`. Set the class attributes:
- `extension: ClassVar[str]` — primary file extension (no dot).
- `alternative_extensions: ClassVar[set[str]]` — other accepted extensions for the same format.
2. **Implement two methods** for line-anchored formats:
- `parse_version_from_title(line: str) -> VersionTag | None` — given one line, return a `VersionTag` if the line is a release heading.
- `parse_title_level(line: str) -> int | None` — return the heading level (1, 2, 3, ...) if the line is a heading. The base class `BaseFormat.get_metadata_from_file` walks the file once and calls both methods per line.
If your format's titles span multiple lines (overline/title/underline, as in reStructuredText), override `get_metadata_from_file` directly instead — see `RestructuredText` for the algorithm.
3. **Add the Jinja2 template** at `commitizen/templates/CHANGELOG.<ext>.j2`. Mirror the structure of `CHANGELOG.md.j2` — same blocks, different markup. Make sure the loops over `tree`, `entries`, and `change_type` match.
4. **Register the built-in** in `pyproject.toml` under `[project.entry-points."commitizen.changelog_format"]`:
5. **Add tests** at `tests/test_changelog_format_<name>.py`. Copy the closest existing test file and adapt the fixtures.
6. **Update the cross-format suite** `tests/test_changelog_formats.py` if it parametrizes over all formats — add the new one to its lists.
7. **Update user docs** at `docs/commands/changelog.md` and `docs/customization/changelog_template.md` — list the new format and show how to opt in via `changelog_format`.
8. **Re-run the install** so the entry point registers:
```bash
uv sync --frozen --group base --group test --group linters
```
## Validate
```bash
uv run pytest tests/test_changelog_format_<name>.py tests/test_changelog_formats.py tests/test_changelog.py tests/test_incremental_build.py -n auto
uv run poe lint
uv run poe doc:build # if docs changed
uv run poe all # final pre-push
```
## Pitfalls
- **`KNOWN_CHANGELOG_FORMATS` is populated at import time** from entry points, so you must re-run `uv sync` after editing `pyproject.toml` before tests can see your new format.
- **Forgetting `alternative_extensions`** — `_guess_changelog_format` uses both `extension` and `alternative_extensions` when the user does not set `changelog_format` explicitly. If a user has `CHANGELOG.<alt-ext>`, your format will not auto-detect without it.
- **Template encoding** — Jinja2 reads templates with the active encoding; keep them ASCII-safe or test with non-UTF-8 `encoding` settings.
- **Heading regex anchoring** — match the whole line (`^...$`) when the markup is line-anchored (Markdown headings); a substring match will pick up non-heading lines that mention `unreleased`.
- **Snapshot updates** — many changelog tests use `pytest-regressions`. See the [update-snapshots playbook](update-snapshots.md) when output intentionally changes.
## Stop and ask if
- The target format requires structured metadata that does not fit the `parse_title_*` Protocol (e.g., front-matter in YAML).
- The format implies a fundamentally different rendering tree (e.g., one file per release) — that is a bigger change than a format addition.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
docs(contributing): add agent-facing playbooks and architecture overview #2007
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Are you sure you want to change the base?
Uh oh!
There was an error while loading. Please reload this page.
docs(contributing): add agent-facing playbooks and architecture overview #2007
Filter by extension
Viewed files
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.