Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 29 additions & 11 deletions .github/workflows/bumpversion.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,38 @@ jobs:
if: ${{ github.repository == 'commitizen-tools/commitizen' && !startsWith(github.event.head_commit.message, 'bump:') }}
runs-on: ubuntu-latest
name: "Bump version and create changelog with commitizen"
permissions:
contents: write
actions: write
steps:
- name: Check out
uses: actions/checkout@v6
with:
fetch-depth: 0
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
changelog_increment_filename: body.md
fetch-tags: true
- uses: commitizen-tools/setup-cz@main
- id: bump-version
run: |
cz bump --yes
git push --follow-tags
new_version="$(cz version -p)"
echo "new_version=$new_version" >> $GITHUB_OUTPUT
new_version_tag="$(cz version -p --tag)"
echo "new_version_tag=$new_version_tag" >> $GITHUB_OUTPUT
- name: Build changelog for Release
env:
NEW_VERSION: ${{ steps.bump-version.outputs.new_version }}
run: |
cz changelog --dry-run "${NEW_VERSION}" > .changelog.md
Comment on lines +33 to +35
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

cz changelog --dry-run "${NEW_VERSION}" treats the positional argument as a revision range/version selector and will still render the “Unreleased” header unless --unreleased-version is provided. For GitHub Release notes you likely want --unreleased-version "${NEW_VERSION_TAG}" (tag-formatted) so the notes are labeled with the released version.

Suggested change
NEW_VERSION: ${{ steps.bump-version.outputs.new_version }}
run: |
cz changelog --dry-run "${NEW_VERSION}" > .changelog.md
NEW_VERSION_TAG: ${{ steps.bump-version.outputs.new_version_tag }}
run: |
cz changelog --dry-run --unreleased-version "${NEW_VERSION_TAG}" > .changelog.md

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Wrong

- name: Release
uses: ncipollo/release-action@v1
with:
tag: v${{ env.REVISION }}
bodyFile: "body.md"
skipIfReleaseExists: true
env:
GH_TOKEN: ${{ github.token }}
NEW_VERSION_TAG: ${{ steps.bump-version.outputs.new_version_tag }}
run: |
gh release create "${NEW_VERSION_TAG}" --notes-file .changelog.md
- name: trigger other workflow
env:
GH_TOKEN: ${{ github.token }}
run: |
gh workflow run pythonpublish.yml \
-f "version=${{ steps.bump-version.outputs.new_version_tag }}"
7 changes: 6 additions & 1 deletion .github/workflows/pythonpublish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Version to trigger"
required: true

jobs:
deploy:
Expand All @@ -15,8 +20,8 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
fetch-depth: 0
ref: ${{ inputs.version || github.ref_name }}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

inputs.version is only available for workflow_dispatch runs; on tag push runs this context can be undefined and cause expression evaluation to fail. Use github.event.inputs.version (with a fallback to github.ref_name) or gate the expression by event type.

Suggested change
ref: ${{ inputs.version || github.ref_name }}
ref: ${{ github.event.inputs.version || github.ref_name }}

Copilot uses AI. Check for mistakes.
- name: Set up Python
uses: astral-sh/setup-uv@v7
- name: Build
Expand Down
3 changes: 3 additions & 0 deletions commitizen/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def from_str(cls, value: str) -> ExitCode:


class CommitizenException(Exception):
exit_code: ExitCode
message: str

def __init__(self, *args: str, **kwargs: Any) -> None:
self.output_method = kwargs.get("output_method") or out.error
self.exit_code: ExitCode = self.__class__.exit_code
Expand Down
4 changes: 2 additions & 2 deletions commitizen/project_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ def get_default_config_filename() -> Literal["pyproject.toml", ".cz.toml"]:
return "pyproject.toml" if Path("pyproject.toml").is_file() else ".cz.toml"


def get_default_version_scheme() -> Literal["pep440", "semver"]:
def get_default_version_scheme() -> Literal["pep440", "semver2"]:
return (
"pep440"
if Path("pyproject.toml").is_file() or Path("setup.py").is_file()
else "semver"
else "semver2"
)
184 changes: 95 additions & 89 deletions docs/commands/bump.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,94 +30,6 @@ The version follows the `MAJOR.MINOR.PATCH` format, with increments determined b
| `MINOR` | New features | `feat` |
| `PATCH` | Fixes and improvements | `fix`, `perf`, `refactor`|

### `--version-scheme`

By default, Commitizen uses [PEP 440][pep440] for version formatting. You can switch to semantic versioning using either:

1. Command line:
```sh
cz bump --version-scheme semver
```

2. Configuration file:
```toml title="pyproject.toml"
[tool.commitizen]
version_scheme = "semver"
```

Available options are:

- `pep440`: [PEP 440][pep440] (**default** and recommended for Python projects)
- `semver`: [Semantic Versioning][semver] (recommended for non-Python projects)

You can also set this in the configuration file with `version_scheme = "semver"`.

!!! note
[pep440][pep440] and [semver][semver] are quite similar, although their difference lies in
how the prereleases look. For example, `0.3.1a0` in pep440 is equivalent to `0.3.1-a0` in semver.

The following table illustrates the difference between the two schemes:

| Version Type | pep440 | semver |
|--------------|----------------|-----------------|
| Non-prerelease | `0.1.0` | `0.1.0` |
| Prerelease | `0.3.1a0` | `0.3.1-a0` |
| Devrelease | `0.1.1.dev1` | `0.1.1-dev1` |
| Dev and pre | `1.0.0a3.dev1` | `1.0.0-a3-dev1` |


!!! note "Incomplete Version Handling"
Commitizen treats a three-part version (major.minor.patch) as complete.
If your configured version is incomplete (for example, `1` or `1.2`), Commitizen pads missing parts with zeros when it needs `major/minor/patch` for tag formatting.
The tag output depends on your `tag_format`: formats using `${version}` keep `1`/`1.2`, while formats using `${major}.${minor}.${patch}` will render `1.0.0`/`1.2.0`.

When bumping from an incomplete version, Commitizen looks for the latest existing tag that matches the provided release prefix.
For example, if the current version is `1.2` and the latest `1.2.x` tag is `1.2.3`, then a patch bump yields `1.2.4` and a minor bump yields `1.3.0`.

!!! tip
To control the behaviour of bumping and version parsing, you may implement your own `version_scheme` by inheriting from `commitizen.version_schemes.BaseVersion` or use an existing plugin package.


### PEP440 Version Examples

Commitizen supports the [PEP 440][pep440] version format, which includes several version types. Here are examples of each:

#### Standard Releases
```text
0.9.0 # Initial development release
0.9.1 # Patch release
0.9.2 # Another patch release
0.9.10 # Tenth patch release
0.9.11 # Eleventh patch release
1.0.0 # First stable release
1.0.1 # Patch release after stable
1.1.0 # Minor feature release
2.0.0 # Major version release
```

#### Pre-releases
```text
1.0.0a0 # Alpha release 0
1.0.0a1 # Alpha release 1
1.0.0b0 # Beta release 0
1.0.0rc0 # Release candidate 0
1.0.0rc1 # Release candidate 1
```

#### Development Releases
```text
1.0.0.dev0 # Development release 0
1.0.0.dev1 # Development release 1
```

#### Combined Pre-release and Development
```text
1.0.0a1.dev0 # Development release 0 of alpha 1
1.0.0b2.dev1 # Development release 1 of beta 2
```

> **Note**: `post` releases (e.g., `1.0.0.post1`) are not currently supported.

## Command line options

![cz bump --help](../images/cli_help/cz_bump___help.svg)
Expand Down Expand Up @@ -176,7 +88,7 @@ For example, if the current version is `1.0.0b1` then bumping with `--prerelease
Applies the exact changes that have been specified with `--increment` or determined from the commit log.
For example, `--prerelease beta` will always result in a `b` tag, and `--increment PATCH` will always increase the patch component.

#### Examples
**Examples**

The following table illustrates the difference in behavior between the two modes:

Expand Down Expand Up @@ -525,6 +437,100 @@ Automatically answers “yes” to all interactive prompts during the bump proce
cz bump --yes
```

### `--version-scheme`
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I moved it to the bottom, to have a cohesive view of the cli options.

Eventually, version-scheme should have it's own section, where the differences between pep440 and semver are explained.


Format used for the version.

**Available options**

- `pep440`: [PEP 440][pep440]: recommended for Python projects, **default** (for legacy reasons)
- `semver2`: [Semantic Versioning v2][semver]: recommended for non-Python projects
- `semver`: [Semantic Versioning v1](https://semver.org/spec/v1.0.0.html): use if you are stuck with semver v1

**Examples**

1. Command line:
```sh
cz bump --version-scheme semver
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

The --version-scheme examples are inconsistent with the new recommendation of semver2: the command-line example uses semver (v1) while the config example uses semver2. Consider updating the CLI example to cz bump --version-scheme semver2 to avoid confusion.

Suggested change
cz bump --version-scheme semver
cz bump --version-scheme semver2

Copilot uses AI. Check for mistakes.
```

2. Configuration file:
```toml title="pyproject.toml"
[tool.commitizen]
version_scheme = "semver2"
```


!!! note
[pep440][pep440] and [semver][semver] are quite similar, although their difference lies in
how the prereleases look. For example, `0.3.1a0` in pep440 is equivalent to `0.3.1-a0` in semver.

The following table illustrates the difference between the two schemes:

| Version Type | pep440 | semver |
|--------------|----------------|-----------------|
| Non-prerelease | `0.1.0` | `0.1.0` |
| Prerelease | `0.3.1a0` | `0.3.1-a0` |
| Devrelease | `0.1.1.dev1` | `0.1.1-dev1` |
| Dev and pre | `1.0.0a3.dev1` | `1.0.0-a3-dev1` |


!!! note "Incomplete Version Handling"
Commitizen treats a three-part version (major.minor.patch) as complete.
If your configured version is incomplete (for example, `1` or `1.2`), Commitizen pads missing parts with zeros when it needs `major/minor/patch` for tag formatting.
The tag output depends on your `tag_format`: formats using `${version}` keep `1`/`1.2`, while formats using `${major}.${minor}.${patch}` will render `1.0.0`/`1.2.0`.

When bumping from an incomplete version, Commitizen looks for the latest existing tag that matches the provided release prefix.
For example, if the current version is `1.2` and the latest `1.2.x` tag is `1.2.3`, then a patch bump yields `1.2.4` and a minor bump yields `1.3.0`.

!!! tip
To control the behaviour of bumping and version parsing, you may implement your own `version_scheme` by inheriting from `commitizen.version_schemes.BaseVersion` or use an existing plugin package.


### PEP440 Version Examples

Commitizen supports the [PEP 440][pep440] version format, which includes several version types. Here are examples of each:

#### Standard Releases

```text
0.9.0 # Initial development release
0.9.1 # Patch release
0.9.2 # Another patch release
0.9.10 # Tenth patch release
0.9.11 # Eleventh patch release
1.0.0 # First stable release
1.0.1 # Patch release after stable
1.1.0 # Minor feature release
2.0.0 # Major version release
```

#### Pre-releases

```text
1.0.0a0 # Alpha release 0
1.0.0a1 # Alpha release 1
1.0.0b0 # Beta release 0
1.0.0rc0 # Release candidate 0
1.0.0rc1 # Release candidate 1
```

#### Development Releases

```text
1.0.0.dev0 # Development release 0
1.0.0.dev1 # Development release 1
```

#### Combined Pre-release and Development

```text
1.0.0a1.dev0 # Development release 0 of alpha 1
1.0.0b2.dev1 # Development release 1 of beta 2
```

> **Note**: `post` releases (e.g., `1.0.0.post1`) are not currently supported.

[pep440]: https://www.python.org/dev/peps/pep-0440/
[semver]: https://semver.org/
[version_files]: ../config/bump.md#version_files
24 changes: 16 additions & 8 deletions docs/commands/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,28 +77,36 @@ cz changelog --extra key=value -e short="quoted value"

### `--file-name`

This value can be updated in the configuration file with the key `changelog_file` under `tool.commitizen`.

Specify the name of the output file. Note that changelog generation only works with Markdown files.

```bash
cz changelog --file-name="CHANGES.md"
```

This value can be updated in the configuration file with the key `changelog_file` under `tool.commitizen`.

```toml
[tool.commitizen]
# ...
changelog_file = "CHANGES.md"
```

### `--incremental`

This flag can be set in the configuration file with the key `changelog_incremental` under `tool.commitizen`
Build from the latest version found in changelog.

Benefits:

- Build from the latest version found in changelog. This is useful if you have an existing changelog and want to use commitizen to extend it.
- Useful if you have an existing changelog and want to use commitizen to extend it.
- Update unreleased area
- Allows users to manually edit the changelog without it being completely rewritten.

```bash
cz changelog --incremental
```

This flag can be set in the configuration file with the key `changelog_incremental` under `tool.commitizen`
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

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

Missing trailing punctuation on these “can be set/updated in the configuration file…” sentences makes the option docs read like incomplete statements. Consider ending them with a period for consistency with surrounding sections.

Suggested change
This flag can be set in the configuration file with the key `changelog_incremental` under `tool.commitizen`
This flag can be set in the configuration file with the key `changelog_incremental` under `tool.commitizen`.

Copilot uses AI. Check for mistakes.

```toml
[tool.commitizen]
# ...
Expand All @@ -107,14 +115,14 @@ changelog_incremental = true

### `--start-rev`

This value can be set in the configuration file with the key `changelog_start_rev` under `tool.commitizen`

Start from a given git rev to generate the changelog. Commits before that rev will not be considered. This is especially useful for long-running projects adopting conventional commits, where old commit messages might fail to be parsed for changelog generation.

```bash
cz changelog --start-rev="v0.2.0"
```

This value can be set in the configuration file with the key `changelog_start_rev` under `tool.commitizen`

```toml
[tool.commitizen]
# ...
Expand All @@ -123,14 +131,14 @@ changelog_start_rev = "v0.2.0"

### `--merge-prerelease`

This flag can be set in the configuration file with the key `changelog_merge_prerelease` under `tool.commitizen`

Collects changes from prereleases into the next non-prerelease version. If you have a prerelease version followed by a normal release, the changelog will show the prerelease changes as part of the normal release. If not set, prereleases will be included as separate entries in the changelog.

```bash
cz changelog --merge-prerelease
```

This flag can be set in the configuration file with the key `changelog_merge_prerelease` under `tool.commitizen`

```toml
[tool.commitizen]
# ...
Expand Down
Loading
Loading