1
0
Fork 0

Adding upstream version 4.6.0.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-04-21 10:42:01 +02:00
parent f3ad83a1a5
commit a7fbe822ec
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
278 changed files with 30423 additions and 0 deletions

View file

@ -0,0 +1,68 @@
# Automatically check message before commit
## About
To automatically check a commit message prior to committing, you can use a [git hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks).
## How to
There are two common methods for installing the hook:
### Method 1: Add git hook through [pre-commit](https://pre-commit.com/)
- Step 1: Install [pre-commit](https://pre-commit.com/)
```sh
python -m pip install pre-commit
```
- Step 2: Create `.pre-commit-config.yaml` at your root directory with the following content
```yaml
---
repos:
- repo: https://github.com/commitizen-tools/commitizen
rev: v1.17.0
hooks:
- id: commitizen
stages: [commit-msg]
```
- Step 3: Install the configuration into git hook through `pre-commit`
```bash
pre-commit install --hook-type commit-msg
```
### Method 2: Manually add git hook
The command might be included inside of a Git hook (inside of `.git/hooks/` at the root of the project).
The selected hook might be the file called commit-msg.
This example shows how to use the check command inside of commit-msg.
At the root of the project:
```bash
cd .git/hooks
touch commit-msg
chmod +x commit-msg
```
Open the file and edit it:
```sh
#!/bin/bash
MSG_FILE=$1
cz check --allow-abort --commit-msg-file $MSG_FILE
```
Where `$1` is the name of the temporary file that contains the current commit message. To be more explicit, the previous variable is stored in another variable called `$MSG_FILE`, for didactic purposes.
The `--commit-msg-file` flag is required, not optional.
Each time you create a commit, automatically, this hook will analyze it.
If the commit message is invalid, it'll be rejected.
The commit should follow the given committing rules; otherwise, it won't be accepted.

View file

@ -0,0 +1,46 @@
# Automatically prepare message before commit
## About
It can be desirable to use commitizen for all types of commits (i.e. regular, merge,
squash) so that the complete git history adheres to the commit message convention
without ever having to call `cz commit`.
To automatically prepare a commit message prior to committing, you can
use a [prepare-commit-msg Git hook][prepare-commit-msg-docs]:
> This hook is invoked by git-commit right after preparing the
> default log message, and before the editor is started.
To automatically perform arbitrary cleanup steps after a successful commit you can use a
[post-commit Git hook][post-commit-docs]:
> This hook is invoked by git-commit. It takes no parameters, and is invoked after a
> commit is made.
A combination of these two hooks allows for enforcing the usage of commitizen so that
whenever a commit is about to be created, commitizen is used for creating the commit
message. Running `git commit` or `git commit -m "..."` for example, would trigger
commitizen and use the generated commit message for the commit.
## Installation
Copy the hooks from [here](https://github.com/commitizen-tools/commitizen/tree/master/hooks) into the `.git/hooks` folder and make them
executable by running the following commands from the root of your Git repository:
```bash
wget -O .git/hooks/prepare-commit-msg https://raw.githubusercontent.com/commitizen-tools/commitizen/master/hooks/prepare-commit-msg.py
chmod +x .git/hooks/prepare-commit-msg
wget -O .git/hooks/post-commit https://raw.githubusercontent.com/commitizen-tools/commitizen/master/hooks/post-commit.py
chmod +x .git/hooks/post-commit
```
## Features
- Commits can be created using both `cz commit` and the regular `git commit`
- The hooks automatically create a backup of the commit message that can be reused if
the commit failed
- The commit message backup can also be used via `cz commit --retry`
[post-commit-docs]: https://git-scm.com/docs/githooks#_post_commit
[prepare-commit-msg-docs]: https://git-scm.com/docs/githooks#_prepare_commit_msg

View file

@ -0,0 +1,78 @@
# Dev Releases
## About
To make use of a `.dev` suffix, as per
[PEP440](https://peps.python.org/pep-0440/#developmental-releases).
If more than one active branch attempts to create a tag, relative to the main
branch, there is the possibility that each will attempt to create the _same_
tag, resulting in a collision.
Developmental releases aim to avoid this by including a `.dev` segment which
includes a non-negative integer unique to that workflow:
```txt
X.Y.devN
```
!!! note
As noted in
[PEP440](https://peps.python.org/pep-0440/#developmental-releases),
although developmental releases are useful in avoiding the situation
described above, depending on the value passed as the developmental
release, they can be _"difficult to parse for human readers"_.
## How to
### Example 1: CircleCI
For example, CircleCI [provides](https://circleci.com/docs/variables/)
`CIRCLE_BUILD_NUM`, a unique number for each job which will increment with each
run:
```sh
--devrelease ${CIRCLE_BUILD_NUM}
```
This will result in a unique developmental release of, for example:
```sh
1.3.2.dev2478
```
### Example 2: GitHub
GitHub also
[provides](https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables)
`GITHUB_RUN_ID`, a _"unique number for each workflow run"_ which will also
provide a unique number for each workflow:
```sh
--devrelease ${GITHUB_RUN_ID}
```
This will result in a unique developmental release of, for example:
```sh
1.3.2.dev6048584598
```
### Example 3: Unix time
Equally, as the developmental release needs only a non-negative integer, it is
possible to use the Unix time (i.e. the number of seconds since 1st January
1970 UTC).
This would create the possibility of a collision if two builds occur at
precisely the same second but this may be sufficient for many cases:
```sh
--devrelease $(date +%s)
```
This will result in a unique developmental release of, for example:
```sh
1.3.2.dev1696238452
```

View file

@ -0,0 +1,125 @@
## Create a new release with Github Actions
### Automatic bumping of version
To execute `cz bump` in your CI, and push the new commit and
the new tag, back to your master branch, we have to:
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.
!!! 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.
```yaml
name: Bump version
on:
push:
branches:
- master
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@v3
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 }}
```
Push to master and that's it.
### 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`
The commitizen action creates an env variable called `REVISION`, containing the
newely 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 }}
```
### Publishing a python package
Once the new tag is created, triggering an automatic publish command would be desired.
In order to do so, the credential needs to be added with the information of our PyPI account.
Instead of using username and password, we suggest using [api token](https://pypi.org/help/#apitoken) generated from PyPI.
After generate api token, use the token as the PyPI password and `__token__` as the username.
Go to `Settings > Secrets > Add new secret` and add the secret: `PYPI_PASSWORD`.
Create a file in `.github/workflows/pythonpublish.yaml` with the following content:
```yaml
name: Upload Python Package
on:
push:
tags:
- "*" # Will trigger for every tag, alternative: 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: "3.x"
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: latest
virtualenvs-in-project: true
virtualenvs-create: true
- name: Install dependencies
run: |
poetry --version
poetry install
- name: Build and publish
env:
PYPI_USERNAME: __token__
PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: |
./scripts/publish
```
Notice that we are using poetry, and we are calling a bash script in `./scripts/publish`. You should configure the action, and the publish with your tools (twine, poetry, etc.). Check [commitizen example](https://github.com/commitizen-tools/commitizen/blob/master/scripts/publish)
You can also use [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) to publish your package.
Push the changes and that's it.

113
docs/tutorials/gitlab_ci.md Normal file
View file

@ -0,0 +1,113 @@
## Create a new release using GitLab CI
For this example, we have a `python/django` application and `Docker` as a containerization tool.
_Goal_: Bump a new version every time that a change occurs on the `master` branch. The bump should be executed automatically by the `CI` process.
### Development Workflow
1. A developer creates a new commit on any branch (except `master`)
2. A developer creates a merge request (MR) against `master` branch
3. When the `MR` is merged into master, the 2 stages of the CI are executed
4. For simplification, we store the software version in a file called `VERSION`. You can use any file that you want as `commitizen` supports it.
5. The commit message executed automatically by the `CI` must include `[skip-ci]` in the message; otherwise, the process will generate a loop. You can define the message structure in [commitizen](../commands/bump.md) as well.
### Gitlab Configuration
To be able to change files and push new changes with `Gitlab CI` runners, we need to have a `ssh` key and configure a git user.
First, let's create a `ssh key`. The only requirement is to create it without a passphrase:
```bash
ssh-keygen -f deploy_key -N ""
```
The previous command will create a private and public key under the files `deploy_key` and `deploy_key.pub`. We will use them later.
For the git user, we need an email and username. You can choose whatever you want; in this example, we choose `ci-runner@myproject.com` and `admin`, respectively.
Now, we need to create three environment variables that will be visible for the runners. They should be created in the `variables` section under `settings/ci_cd`:
![gitlab variables](../images/gitlab_ci/gitlab_variables.png)
Create `SSH_PRIVATE_KEY`, `CI_EMAIL`, `CI_USERNAME` variables, and fill them with the `private_key`, `email` and `username` that we have created previously.
The latest step is to create a `deploy key.` To do this, we should create it under the section `settings/repository` and fill it with the `public key` generated before. Check `Write access allowed`; otherwise, the runner won't be able to write the changes to the repository.
![gitlab deploy key](../images/gitlab_ci/gitlab_deploy_key.png)
If you have more projects under the same organization, you can reuse the deploy key created before, but you will have to repeat the step where we have created the environment variables (ssh key, email, and username).
tip: If the CI raise some errors, try to unprotected the private key.
### Defining GitLab CI Pipeline
1. Create a `.gitlab-ci.yaml` file that contains `stages` and `jobs` configurations. You can find more info [here](https://docs.gitlab.com/ee/ci/quick_start/).
2. Define `stages` and `jobs`. For this example, we define two `stages` with one `job` each one.
- Test the application.
- Auto bump the version. This means changing the file/s that reflects the version, creating a new commit and git tag.
### Stages and Jobs
```yaml
image: docker:latest
services:
- docker:dind
variables:
API_IMAGE_NAME: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
before_script:
- apk add --no-cache py-pip
- pip install docker-compose
stages:
- test
- auto-bump
test:
stage: test
script:
- docker-compose run -e DJANGO_ENVIRONMENT=dev your_project python manage.py test # run tests
auto-bump:
stage: auto-bump
image: python:3.9
before_script:
- "which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )"
- eval `ssh-agent -s`
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null # add ssh key
- pip3 install -U commitizen # install commitizen
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
dependencies:
- test
script:
- git remote set-url origin git@gitlab.com:discover/rentee-core.git # git configuration
- git config --global user.email "${CI_EMAIL}" && git config --global user.name "${CI_USERNAME}"
- 'exists=`git show-ref refs/heads/master` && if [ -n "$exists" ]; then git branch -D master; fi'
- git checkout -b master
- cz bump --yes # execute auto bump and push to master
- git push origin master:$CI_COMMIT_REF_NAME
- TAG=$(head -n 1 VERSION) # get the new software version and save into artifacts
- echo "#!/bin/sh" >> variables
- echo "export TAG='$TAG'" >> variables
- git push origin $TAG
only:
refs:
- master
artifacts:
paths:
- variables
```
So, every time that a developer push to any branch, the `test` job is executed. If the branch is `master` and the test jobs success, the `auto-bump` takes place.
To be able to push using the Gitlab runner, we have to set the ssh key, configure git, and finally execute the auto bump.
After merging the new changed into master, we have the final result:
![gitlab final ci result](../images/gitlab_ci/gitlab_final_ci_result.png)

View file

@ -0,0 +1,53 @@
# Create a new release with Jenkins Pipelines
For this we are using the modern approach of [declarative pipelines](https://www.jenkins.io/doc/book/pipeline/).
You must also ensure your jenkins instance supports docker.
Most modern jenkins systems do have support for it, [they have embraced it](https://www.jenkins.io/doc/book/pipeline/docker/).
```groovy
pipeline {
agent {
any
}
environment {
CI = 'true'
}
stages {
stage('Bump version') {
when {
beforeAgent true
expression { env.BRANCH_IS_PRIMARY }
not {
changelog '^bump:.+'
}
}
steps {
script {
useCz {
sh "cz bump --changelog"
}
// Here push back to your repository the new commit and tag
}
}
}
}
}
def useCz(String authorName = 'Jenkins CI Server', String authorEmail = 'your-jenkins@email.com', String image = 'registry.hub.docker.com/commitizen/commitizen:latest', Closure body) {
docker
.image(image)
.inside("-u 0 -v $WORKSPACE:/workspace -w /workspace -e GIT_AUTHOR_NAME='${authorName}' -e GIT_AUTHOR_EMAIL='${authorEmail}' -entrypoint='/bin/sh'") {
sh 'git config --global --add safe.directory "*"'
sh "git config --global user.email '${authorName}'"
sh "git config --global user.name '${authorEmail}'"
body()
}
}
```
!!! warning
Using jenkins pipeline with any git plugin may require many different configurations,
you'll have to tinker with it until your pipelines properly detects git events. Check your
webhook in your git repository and check the "behaviors" and "build strategies" in
your pipeline settings.

View file

@ -0,0 +1,81 @@
# Configuring commitizen in a monorepo
This tutorial assumes the monorepo layout is designed with multiple components that can be released independently of each
other, it also assumes that conventional commits with scopes are in use. Some suggested layouts:
```shell-session
.
├── library-b
│   └── .cz.toml
└── library-z
└── .cz.toml
```
```shell-session
src
├── library-b
│   └── .cz.toml
└── library-z
└── .cz.toml
```
Sample `.cz.toml` for each component:
```toml
# library-b/.cz.toml
[tool.commitizen]
name = "cz_customize"
version = "0.0.0"
tag_format = "${version}-library-b" # the component name can be a prefix or suffix with or without a separator
ignored_tag_formats = ["${version}-library-*"] # Avoid noise from other tags
update_changelog_on_bump = true
```
```toml
# library-z/.cz.toml
[tool.commitizen]
name = "cz_customize"
version = "0.0.0"
tag_format = "${version}-library-z"
ignored_tag_formats = ["${version}-library-*"] # Avoid noise from other tags
update_changelog_on_bump = true
```
And finally, to bump each of these:
```sh
cz --config library-b/.cz.toml bump --yes
cz --config library-z/.cz.toml bump --yes
```
## Changelog per component
In order to filter the correct commits for each component, you'll have to come up with a strategy.
For example:
- Trigger the pipeline based on the changed path, which can have some downsides, as you'll rely on the developer not including files from other files
- [github actions](https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushpull_requestpull_request_targetpathspaths-ignore) uses `path`
- [Jenkins](https://www.jenkins.io/doc/book/pipeline/syntax/#built-in-conditions) uses `changeset`
- [Gitlab](https://docs.gitlab.com/ee/ci/yaml/#ruleschanges) uses `rules:changes`
- Filter certain pattern of the commit message (recommended)
### Example with scope in conventional commits
For this example, to include the message in the changelog, we will require commits to use a specific scope.
This way, only relevant commits will be included in the appropriate change log for a given component, and any other commit will be ignored.
Example config and commit for `library-b`:
```toml
[tool.commitizen.customize]
changelog_pattern = "^(feat|fix)\\(library-b\\)(!)?:" #the pattern on types can be a wild card or any types you wish to include
```
A commit message looking like this, would be included:
```
fix:(library-b) Some awesome message
```

View file

@ -0,0 +1,101 @@
# Managing tag formats
## Tag format and version scheme
For most projects, the tag format is simply the version number which is set like this:
```yaml
[tool.commitizen]
tag_format: $version
version_scheme: pep440
```
As this is the default value so you don't have to specify it.
This setting means that:
- The tag generated on bump will have this format: `1.0.0` :
- the version is generated following PEP440 scheme
- the tag is exactly the generated version
- All tags having this format will be recognized as version tag when:
- searching the last while bumping a release
- searching previous versions while:
- generating incremental changelog
- generating a changelog for a version range
- The changelog versions (section titles) will have this format
- The `scm` version provider will identify the current version using this tag format
The version format will change depending on your configured version scheme.
For most, it will only impact pre-releases and [developmental releases](dev_releases.md) formats (i.e. `1.0.0-rc.1` vs. `1.0.0.rc1`)
But you may need a different tagging convention, let's say using `semver` and prefixed with a `v`.
In this case you will define your settings like this:
```yaml
[tool.commitizen]
tag_format: v${version}
version_scheme: semver
```
As a result, the tag generated on bump will have this format: `v1.0.0` and the version will be generated following `semver` scheme.
!!! note
Both `$version` and `${version}` syntaxes are strictly equivalent. You can use the one you prefer.
See [the `version_scheme` section in `bump` command documentation](../commands/bump.md#version_scheme) for more details on version schemes and how to define your own.
See [`tag_format`](../config.md#tag_format) and [`version_scheme`](../config.md#version_scheme) settings in [Configuration reference](../config.md) for more details on these settings.
## Changing convention
Now, let's say you need to change the tag format for some reason (company convention, [migration to a monorepo](monorepo_guidance.md)...).
You will obviously want to keep all those features working as expected.
Commitizen can deal with it as long as you provide the legacy tag format in the configuration.
Using the previous example, let say you want to move from `v${version}` to `component-${version}`.
Then `component-${version}` will be the new tag format and `v${version}` the legacy one.
```yaml
[tool.commitizen]
tag_format: component-${version}
legacy_tag_formats:
- v${version}
```
This way, you won't loose your version history, you'll still be able to generate you changelog properly
and on the next version bump, your last version in the form `v${version}` will be properly recognizef if you use the `scm` version provider.
Your new tag will be in the form `component-${version}`.
## Known tags to ignore
Now let's say you have some known tags you want to ignore, either because they are not versions, either because they are not versions of the component you are dealing with.
As a consequence, you don't want them to trigger a warning because Commitizen detected an unknown tag format:
Then you can tell Commitizen about it using the [`ignored_tag_formats`](../config.md#ignored_tag_formats) setting:
```yaml
[tool.commitizen]
ignored_tag_formats:
- prod
- other-component-${version}
- prefix-*
```
This will ignore:
- The `prod` tag
- Any version tag prefixed with `other-component-`
- Any tag prefixed with `prefix-`
!!! tip
Note the `*` in the `prefix-*` pattern. This is a wildcard and only exists for `ignored_tag_formats`.
It will match any string from any length. This allows to exclude by prefix, whether it is followed by a version or not.
!!! tip
If you don't want to be warned when Commitizen detect an unknown tag, you can by setting:
```
[tool.commitizen]
ignored_tag_formats = ["*"]
```
But be aware that you will not be warned if you have a typo in your tag formats.

View file

@ -0,0 +1,46 @@
For this project to work well in your pipeline, a commit convention must be followed.
By default commitizen uses the known [conventional commits][conventional_commits], but
you can create your own following the docs information over at
[customization][customization].
## Conventional commits
If you are using [conventional commits][conventional_commits], the most important
thing to know is that you must begin your commits with at least one of these tags:
`fix`, `feat`. And if you introduce a breaking change, then, you must
add to your commit body the following `BREAKING CHANGE`.
Using these 3 keywords will allow the proper identification of the semantic version.
Of course, there are other keywords, but I'll leave it to the reader to explore them.
## Writing commits
Now to the important part, when writing commits, it's important to think about:
- Your future self
- Your colleagues
You may think this is trivial, but it's not. It's important for the reader to
understand what happened.
Emojis may be added as well (e.g. see [cz-emoji][cz_emoji]), which requires the `utf-8`, or equivalent, character encoding to support unicode characters. By default, `commitizen` uses the `utf-8` character encoding, but a different encoding may be set through the `encoding` [configuration option][configuration].
### Recommendations
- **Keep the message short**: Makes the list of commits more readable (~50 chars).
- **Talk imperative**: Follow this rule: `If applied, this commit will <commit message>`
- **Think about the CHANGELOG**: Your commits will probably end up in the changelog
so try writing for it, but also keep in mind that you can skip sending commits to the
CHANGELOG by using different keywords (like `build`).
- **Use a commit per new feature**: if you introduce multiple things related to the same
commit, squash them. This is useful for auto-generating CHANGELOG.
| Do's | Don'ts |
| ---- | ------ |
| `fix(commands): bump error when no user provided` | `fix: stuff` |
| `feat: add new commit command` | `feat: commit command introduced` |
[customization]: ../customization.md
[conventional_commits]: https://www.conventionalcommits.org
[cz_emoji]: https://commitizen-tools.github.io/commitizen/third-party-commitizen/#cz-emoji
[configuration]: ../config.md#encoding