Skip to content
Open
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
169 changes: 117 additions & 52 deletions docs/tutorials/github_actions.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,49 @@
## Create a new release with GitHub Actions

### Automatic bumping of version
This guide shows you how to automatically bump versions, create changelogs, and publish releases using Commitizen in GitHub Actions.

To execute `cz bump` in your CI, and push the new commit and
the new tag, back to your master branch, we have to:
### Prerequisites

1. Create a personal access token. [Follow the instructions here](https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line#creating-a-token). And copy the generated key
2. Create a secret called `PERSONAL_ACCESS_TOKEN`, with the copied key, by going to your
project repository and then `Settings > Secrets > Add new secret`.
3. In your repository create a new file `.github/workflows/bumpversion.yml`
with the following content.
Before setting up the workflow, you'll need:

!!! warning
If you use `GITHUB_TOKEN` instead of `PERSONAL_ACCESS_TOKEN`, the job won't trigger another workflow. It's like using `[skip ci]` in other CI's.
1. A personal access token with repository write permissions
2. Commitizen configured in your project (see [configuration documentation](../config/configuration_file.md))

```yaml
### Automatic version bumping

To automatically execute `cz bump` in your CI and push the new commit and tag back to your repository, follow these steps:

#### Step 1: Create a personal access token

1. Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens)
2. Click "Generate new token (classic)"
3. Give it a descriptive name (e.g., "Commitizen CI")
4. Select the `repo` scope to grant full repository access
5. Click "Generate token" and **copy the token immediately** (you won't be able to see it again)

!!! warning "Important: Use Personal Access Token, not GITHUB_TOKEN"
If you use `GITHUB_TOKEN` instead of `PERSONAL_ACCESS_TOKEN`, the workflow won't trigger another workflow run. This is a GitHub security feature to prevent infinite loops. The `GITHUB_TOKEN` is treated like using `[skip ci]` in other CI systems.

#### Step 2: Add the token as a repository secret

1. Go to your repository on GitHub
2. Navigate to `Settings > Secrets and variables > Actions`
3. Click "New repository secret"
4. Name it `PERSONAL_ACCESS_TOKEN`
5. Paste the token you copied in Step 1
6. Click "Add secret"

#### Step 3: Create the workflow file

Create a new file `.github/workflows/bumpversion.yml` in your repository with the following content:

```yaml title=".github/workflows/bumpversion.yml"
name: Bump version

on:
push:
branches:
- master
- master # or 'main' if that's your default branch

jobs:
bump-version:
Expand All @@ -29,7 +52,7 @@ jobs:
name: "Bump version and create changelog with commitizen"
steps:
- name: Check out
uses: actions/checkout@v3
uses: actions/checkout@v6
with:
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
fetch-depth: 0
Expand All @@ -39,62 +62,106 @@ jobs:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
```

Push to master and that's it.
#### How it works

- **Trigger**: The workflow runs on every push to the `master` branch (or `main` if you change it)
- **Conditional check**: The `if` condition prevents infinite loops by skipping the job if the commit message starts with `bump:`
- **Checkout**: Uses your personal access token to check out the repository with full history (`fetch-depth: 0`)
- **Bump**: The `commitizen-action` automatically:
- Determines the version increment based on your commit messages
- Updates version files (as configured in your `pyproject.toml` or other config)
- Creates a new git tag
- Generates/updates the changelog
- Pushes the commit and tag back to the repository

Once you push this workflow file to your repository, it will automatically run on the next push to your default branch.

Check out [commitizen-action](https://github.com/commitizen-tools/commitizen-action) for more details.

### Creating a GitHub release

You can modify the previous action.

Add the variable `changelog_increment_filename` in the `commitizen-action`, specifying
where to output the content of the changelog for the newly created version.

And then add a step using a GitHub action to create the release: `softprops/action-gh-release`

Commitizen action creates an env variable called `REVISION`, containing the
newly created version.

```yaml
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
changelog_increment_filename: body.md
- name: Release
uses: softprops/action-gh-release@v1
with:
body_path: "body.md"
tag_name: ${{ env.REVISION }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
To automatically create a GitHub release when a new version is bumped, you can extend the workflow above.

The `commitizen-action` creates an environment variable called `REVISION` containing the newly created version. You can use this to create a release with the changelog content.

```yaml title=".github/workflows/bumpversion.yml"
name: Bump version

on:
push:
branches:
- master # or 'main' if that's your default branch

jobs:
bump-version:
if: "!startsWith(github.event.head_commit.message, 'bump:')"
runs-on: ubuntu-latest
name: "Bump version and create changelog with commitizen"
steps:
- name: Check out
uses: actions/checkout@v6
with:
token: "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
fetch-depth: 0
- name: Create bump and changelog
uses: commitizen-tools/commitizen-action@master
with:
github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
changelog_increment_filename: body.md
- name: Release
uses: ncipollo/release-action@v1
with:
tag: v${{ env.REVISION }}
bodyFile: "body.md"
skipIfReleaseExists: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
```

### Publishing a python package
You can find the complete workflow in our repository at [bumpversion.yml](https://github.com/commitizen-tools/commitizen/blob/master/.github/workflows/bumpversion.yml).

Once the new tag is created, triggering an automatic publish command would be desired.
### Publishing a Python package

In order to do so, the credential needs to be added with the information of our PyPI account.
After a new version tag is created by the bump workflow, you can automatically publish your package to PyPI.

Instead of using username and password, we suggest using [api token](https://pypi.org/help/#apitoken) generated from PyPI.
#### Step 1: Create a PyPI API token

After generate api token, use the token as the PyPI password and `__token__` as the username.
1. Go to [PyPI Account Settings](https://pypi.org/manage/account/)
2. Scroll to the "API tokens" section
3. Click "Add API token"
4. Give it a name (e.g., "GitHub Actions")
5. Set the scope (project-specific or account-wide)
6. Click "Add token" and **copy the token immediately**

Go to `Settings > Secrets > Add new secret` and add the secret: `PYPI_PASSWORD`.
!!! tip "Using API tokens"
PyPI API tokens are more secure than passwords. Use `__token__` as the username and the token as the password.
Comment on lines +130 to +137
Copy link
Member

Choose a reason for hiding this comment

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

Let's suggest using trusted publisher insetad


Create a file in `.github/workflows/pythonpublish.yaml` with the following content:
#### Step 2: Add the token as a repository secret

```yaml
1. Go to your repository on GitHub
2. Navigate to `Settings > Secrets and variables > Actions`
3. Click "New repository secret"
4. Name it `PYPI_PASSWORD`
5. Paste the PyPI token
6. Click "Add secret"

#### Step 3: Create the publish workflow

Create a new file `.github/workflows/pythonpublish.yml` that triggers on tag pushes:

```yaml title=".github/workflows/pythonpublish.yml"
name: Upload Python Package

on:
push:
tags:
- "*" # Will trigger for every tag, alternative: 'v*'
- "*" # Will trigger for every tag, alternative: 'v*'

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Python
Expand All @@ -118,9 +185,7 @@ jobs:
run: poetry publish --build
```

Notice that we are using poetry to publish the package.


You can also use [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) to publish your package.
This workflow uses Poetry to build and publish the package. You can find the complete workflow in our repository at [pythonpublish.yml](https://github.com/commitizen-tools/commitizen/blob/master/.github/workflows/pythonpublish.yml).

Push the changes and that's it.
!!! note "Alternative publishing methods"
You can also use [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) or other build tools like `setuptools`, `flit`, or `hatchling` to publish your package.