Skip to content
Merged
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
- 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 }}"
13 changes: 12 additions & 1 deletion .github/workflows/pythonpublish.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
name: Upload Python Package

# With the current configuration this workflow will be
# triggered via `workflow_dispatch` in `bumpversion.yml`.
# We leave the `push.tags` trigger to allow for manual releases
# in case we need to bump locally, and we actively push the tag.
# The PERSONAL_ACCESS_TOKEN is no longer needed as we use the OIDC token instead.
# We favor this approach because it requires less steps to set up and is more secure.
on:
push:
tags:
- "v*"
workflow_dispatch:
inputs:
version:
description: "Version to trigger"
required: true

jobs:
deploy:
Expand All @@ -15,8 +26,8 @@ jobs:
steps:
- uses: actions/checkout@v6
with:
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
fetch-depth: 0
ref: ${{ inputs.version || github.ref_name }}
- 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`

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://un5h82ptgj7rc.julianrbryant.com/spec/v1.0.0.html): use if you are stuck with semver v1

**Examples**

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

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://un5gmtkzgjcywhd1hkae4.julianrbryant.com/dev/peps/pep-0440/
[semver]: https://un5h82ptgj7rc.julianrbryant.com/
[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`.

```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