You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds an alternative authentication option for the GitLab CI bump pipeline that does not require SSH keys, using a GitLab Project Access Token over HTTPS. Also shows release/tag-only jobs to avoid running packaging steps on every commit.
Closes#482
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/tutorials/gitlab_ci.md
+129-4Lines changed: 129 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,21 @@ _Goal_: Bump a new version every time that a change occurs on the `master` branc
12
12
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.
13
13
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.
14
14
15
-
### GitLab Configuration
15
+
### Authentication options
16
+
17
+
To let `GitLab CI` runners push the bump commit and tag back to the repository, the runner needs write access. Two common approaches are documented below — pick whichever fits your environment best:
18
+
19
+
-**[SSH key](#option-a-ssh-key)** — push over `git@`. Requires generating a key pair, storing the private key as a CI variable, and registering the public key as a deploy key.
20
+
-**[Project Access Token (HTTPS)](#option-b-project-access-token-https)** — push over `https://`. No SSH client is required; the runner authenticates using a token managed in the GitLab UI.
21
+
22
+
Both options assume two CI/CD variables holding the git author identity used by the bump commit:
23
+
24
+
-`CI_EMAIL`
25
+
-`CI_USERNAME`
26
+
27
+
You can create them under your project's `Settings > CI/CD > Variables`.
28
+
29
+
### Option A: SSH key
16
30
17
31
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.
18
32
@@ -40,16 +54,14 @@ If you have more projects under the same organization, you can reuse the deploy
40
54
41
55
Tip: If the CI raise some errors, try to unprotect the private key.
42
56
43
-
### Defining GitLab CI Pipeline
57
+
####Defining the GitLab CI Pipeline (SSH)
44
58
45
59
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/).
46
60
47
61
2. Define `stages` and `jobs`. For this example, we define two `stages` with one `job` each one.
48
62
- Test the application.
49
63
- Auto bump the version. This means changing the file/s that reflects the version, creating a new commit and git tag.
50
64
51
-
### Stages and Jobs
52
-
53
65
```yaml
54
66
image: docker:latest
55
67
@@ -111,3 +123,116 @@ To be able to push using the GitLab runner, we have to set the SSH key, configur
111
123
After merging the new changes into master, we have the final result:
112
124
113
125

126
+
127
+
### Option B: Project Access Token (HTTPS)
128
+
129
+
If you cannot or do not want to manage SSH keys (for example, when your runners do not have an SSH client, or when SSH egress is blocked), you can let the runner push back over `HTTPS` using a [GitLab Project Access Token](https://docs.gitlab.com/user/project/settings/project_access_tokens/). This keeps everything inside the GitLab UI — no key generation, no deploy keys.
130
+
131
+
!!! note "Group / personal tokens"
132
+
The same approach works with [Group Access Tokens](https://docs.gitlab.com/user/group/settings/group_access_tokens/) (handy when several projects share automation) and [Personal Access Tokens](https://docs.gitlab.com/user/profile/personal_access_tokens/). Project Access Tokens are usually preferred because they are scoped to a single project.
133
+
134
+
!!! warning "`CI_JOB_TOKEN` is not enough"
135
+
GitLab's built-in `CI_JOB_TOKEN` cannot push to the repository. You need a Project (or Group / Personal) Access Token with at least the `Developer` role and the `write_repository` scope.
136
+
137
+
#### Step 1: Create a Project Access Token
138
+
139
+
1. In your GitLab project, go to `Settings > Access Tokens`.
140
+
2. Create a new token:
141
+
- **Name**: e.g. `commitizen-bump`.
142
+
- **Role**: `Developer` (or higher) — required to push to protected branches and tags.
143
+
- **Scopes**: tick `write_repository`. `read_repository` is implied.
144
+
- **Expiration date**: pick a date that suits your rotation policy.
145
+
3. Click `Create project access token` and **copy the token immediately** — GitLab only shows it once.
146
+
147
+
#### Step 2: Expose the token to the pipeline
148
+
149
+
1. Open `Settings > CI/CD > Variables`.
150
+
2. Add a new variable:
151
+
- **Key**: `GITLAB_TOKEN` (any name works; this tutorial uses `GITLAB_TOKEN`).
152
+
- **Value**: the token from Step 1.
153
+
- Tick `Masked` so it does not appear in job logs.
154
+
- Tick `Protected` if your bump runs only on protected branches/tags.
155
+
3. While you are there, make sure `CI_EMAIL` and `CI_USERNAME` variables exist (they configure the git author for the bump commit).
156
+
157
+
#### Step 3: Allow the token to push to the protected branch
158
+
159
+
If `master` (or `main`) is protected, the token's user (a [bot user](https://docs.gitlab.com/user/project/settings/project_access_tokens/#bot-users-for-projects) automatically created with the token) needs permission to push:
160
+
161
+
- Go to `Settings > Repository > Protected branches`.
162
+
- Make sure `Developers + Maintainers` (or at least the role you assigned to the token) is allowed to push.
163
+
- Do the same under `Settings > Repository > Protected tags` if you push tags such as `v*`.
164
+
165
+
#### Step 4: Defining the GitLab CI Pipeline (HTTPS)
166
+
167
+
The pipeline below mirrors the SSH example but authenticates over HTTPS using the token. It also splits the workflow so that release-only work happens on the bump commit and packaging/publishing only happens once the resulting tag is pushed:
168
+
169
+
```yaml
170
+
image: python:3.10
171
+
172
+
variables:
173
+
# Use the project URL exposed by GitLab so this works for any fork/mirror.
# Upload the artifacts to your registry of choice; this is just an example.
218
+
- twine upload --non-interactive dist/*
219
+
rules:
220
+
# This job only runs on tag pipelines created by the `bump` job above.
221
+
- if: $CI_COMMIT_TAG
222
+
artifacts:
223
+
paths:
224
+
- dist/
225
+
- release_notes.md
226
+
```
227
+
228
+
How the pipeline is wired:
229
+
230
+
- `test` runs on every branch and merge request, but is skipped on the bump commit so we do not waste runners re-testing what was just released.
231
+
- `bump`only runs on the default branch and asks `commitizen` to compute the next version, update the version files, write the changelog, commit and tag. The push uses the token via `oauth2:${GITLAB_TOKEN}@…`.
232
+
- `release`only runs on tag pipelines (i.e. when the tag pushed by `bump` arrives in GitLab). This is where you would publish artifacts, build and upload a Python package, deploy a Docker image, create a GitLab release, etc.
233
+
234
+
!!! tip "Avoiding pipeline loops"
235
+
The default `cz bump` commit message starts with `bump:`. The `rules:` blocks above use that prefix to skip both the `test` and `bump` jobs on the bump commit. If you customize `bump_message`, update the regex accordingly. You can also add `[skip ci]` to the bump message — see `bump_message` in the [bump command documentation](../commands/bump.md).
236
+
237
+
!!! tip "Token rotation"
238
+
Project Access Tokens expire. Set a calendar reminder before the expiration date to rotate the token and update the `GITLAB_TOKEN` CI/CD variable; otherwise the `bump` job will start failing with `403`/`401` errors.
0 commit comments