Skip to content

Commit ac8e2e5

Browse files
shenxianpengclaude
andauthored
docs: add a guide for GitLab CI, Bitbucket and Azure Pipelines (#49)
<!-- ccr-projects-attribution: {"github_login":"shenxianpeng"} --> _Requested by **Xianpeng** · [project thread](https://claude.ai/code/project/chan_017XBs7zagX2sxAJ7SUwfyPW?thread=cmsg_017XBs7zagX2sxAJ7SUwfyPWGW1J6v52rdKGW6MGk2bt6z)_ Before: the site only covers running Commit Check on GitHub. A GitLab, Bitbucket or Azure user who writes the obvious `commit-check --message --branch` job gets two silent gaps. The checkout is a detached HEAD, so `--branch` judges `HEAD`, which is always allowed. And only the last commit of the merge request is checked. After: a new page, [GitLab CI, Bitbucket and Azure Pipelines](https://github.com/commit-check/commit-check.com/blob/claude/project-thread-pofwgp/docs/guides/other-ci.md), gives a copy-paste job for each. Each job pipes the branch name from that CI's own variable into `--branch`, and loops `--rev` over exactly the commits the merge or pull request adds. The page is linked from "Where to run it" and from the Guides navigation. How: everything on the page is what 2.18.2 does today. Piping into a lone `--branch` is the behaviour #579 pinned with tests. The CI variables, clone-depth settings and pull request checkouts come from each vendor's documentation ([GitLab predefined variables](https://docs.gitlab.com/ci/variables/predefined_variables/), [Bitbucket variables](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/) and [start conditions](https://support.atlassian.com/bitbucket-cloud/docs/pipeline-start-conditions/), [Azure predefined variables](https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables) and [checkout](https://learn.microsoft.com/en-us/azure/devops/pipelines/yaml-schema/steps-checkout)). I had no GitLab, Bitbucket or Azure runner to try them on. Instead, I extracted each script from the page and ran it with commit-check 2.18.2 against a local repository laid out as that CI leaves it: - a GitLab merge request pipeline, and a merged results pipeline (HEAD is a merge into an advanced target); - a Bitbucket pull request with the destination merged in, and a 12-character destination SHA; - an Azure merge commit, with both `refs/heads/` and bare source branch values. Each run judged only the request's own commits: a bad message on the target branch was never reported. A bad branch name failed, and an unreadable range failed loudly instead of passing. The YAML of all three snippets parses. commit-check/commit-check#600 teaches the CLI to read these variables itself. Once a release ships it, the `echo ... |` lines become optional, and this page can say so then. **Site brought in step with v2.18.2**, per AGENTS.md: the four pre-commit pins move from v2.18.1 to v2.18.2, and the changelog gains the v2.18.2 entry (2026-09-28, the two fixes from #579 and #591, both re-checked against 2.18.2). It is a bug-fix release, so there is no Highlights row. Checks: `python -m pytest tests/` passes against the released 2.18.2 (10 passed). `mkdocs build --strict` passes with `SOCIAL_CARDS=false`, as the deploy previews build; the social cards could not fetch Google Fonts from this sandbox. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013rE6bouKaJvsRyKA4tjqCb --- _Generated by [Claude Code](https://claude.ai/code/session_013rE6bouKaJvsRyKA4tjqCb)_ <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Documentation** * Added setup guidance for running Commit Check in GitLab CI, Bitbucket Pipelines, and Azure Pipelines, including checks for merge and pull requests. * Clarified how piped input is handled when `--message` is combined with other checks. * Documented when CC301 reports a skipped check and how that status appears. * Updated pre-commit examples to use v2.18.2. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Claude <noreply@anthropic.com>
1 parent a2fa2e8 commit ac8e2e5

7 files changed

Lines changed: 158 additions & 4 deletions

File tree

‎docs/changelog.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,26 @@ below and to the page that documents the feature properly.
2929
| [2.5.0](#v250) | Organization-wide config with `inherit_from` | [Across an organization](guides/organization.md) |
3030
| [2.0.0](#v200) | Configuration moved from YAML to TOML — breaking | [Migrating from v1](migration.md) |
3131

32+
## v2.18.2 (2026-09-28) { #v2182 }
33+
34+
### Fixed
35+
36+
* **A piped message is only the message** — next to `--message`, piped stdin
37+
was read by every requested check, so on a valid `feature/streaming-support`
38+
branch `printf 'feat: add streaming support\n' | commit-check --message
39+
--branch` failed [CC201](rules.md#cc201) on the message text, and the author
40+
and tag checks did the same. The other checks now read git. A value piped
41+
into one check on its own, such as `echo feature/x | commit-check --branch`,
42+
is still what that check judges.
43+
See PR [#579](https://github.com/commit-check/commit-check/pull/579).
44+
45+
* **[CC301](rules.md#cc301) reports a skip when it has nothing to compare** —
46+
with no push refs, no upstream, or only malformed ref lines, the force-push
47+
check reported a pass. It now prints `⊘ skipped (not validated):
48+
no-force-push` on stderr and reports `"skip"` in `--format json` and from
49+
`validate_push`. Exit codes do not change.
50+
See PR [#591](https://github.com/commit-check/commit-check/pull/591).
51+
3252
## v2.18.1 (2026-09-24) { #v2181 }
3353

3454
### Changed

‎docs/configuration.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ Used from a hook definition, with no config file anywhere in the repository:
239239
```yaml title=".pre-commit-config.yaml"
240240
repos:
241241
- repo: https://github.com/commit-check/commit-check
242-
rev: v2.18.1
242+
rev: v2.18.2
243243
hooks:
244244
- id: check-message
245245
args:

‎docs/example.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pushed:
131131
```yaml title=".pre-commit-config.yaml"
132132
repos:
133133
- repo: https://github.com/commit-check/commit-check
134-
rev: v2.18.1
134+
rev: v2.18.2
135135
hooks:
136136
- id: check-no-force-push
137137
stages: [pre-push]

‎docs/guides/integrations.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ developer sees locally and what is enforced on the pull request.
99
| [Pre-commit hook](pre-commit.md) | As the message is written | Yes — `--no-verify` | `.pre-commit-config.yaml` in each repository |
1010
| [GitHub Action](github-actions.md) | On every push and pull request, in CI | No | A workflow file in each repository |
1111
| [GitHub App](github-app.md) | On every push and pull request, hosted | No | Install once for the organization |
12+
| [GitLab CI, Bitbucket, Azure Pipelines](other-ci.md) | On every merge or pull request, in CI | No | A job in each repository's pipeline file |
1213
| [Command line](../example.md) | Wherever you call it: a range of commits, a CI you write yourself | — | `pip install commit-check` |
1314
| [MCP server](mcp.md) | Before the commit exists, inside an AI coding agent | — | One entry in the agent's MCP config |
1415
| [Python API](python-api.md) | Wherever your own code runs: a bot, a server-side hook, an agent you build | — | `pip install commit-check`, then `import commit_check.api` |

‎docs/guides/other-ci.md‎

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# GitLab CI, Bitbucket and Azure Pipelines
2+
3+
On GitHub, the [Action](github-actions.md) and the [App](github-app.md) do
4+
this work for you. Everywhere else Commit Check runs as one job in the
5+
pipeline: it is a Python package with no runtime dependencies, so any runner
6+
that can `pip install` can run it, and it reads the same `cchk.toml` as the
7+
hook and the Action.
8+
9+
Two things are different from running it on your own machine, and each
10+
example below handles both:
11+
12+
- **The checkout is a detached HEAD.** git has no branch to report, so
13+
`commit-check --branch` would judge `HEAD`, which is always allowed, and
14+
pass whatever the branch is called. Pipe the branch name in from the CI's
15+
own variable instead: a value piped into `--branch` on its own is the name
16+
it checks.
17+
- **A merge request has more than one commit.** `--rev` checks one commit, so
18+
the job loops over the commits the merge request adds, as in
19+
[Checking a range of commits](../example.md#checking-a-range-of-commits).
20+
The loop needs the history those commits sit on, so each example turns
21+
shallow cloning off. If the range cannot be read, the job fails rather than
22+
passing with nothing checked.
23+
24+
Each job runs on merge or pull requests only, because the variables it reads
25+
exist only there. Add `--author-name --author-email` to the `commit-check`
26+
call in the loop to check each commit's author as well.
27+
28+
## GitLab CI
29+
30+
```yaml title=".gitlab-ci.yml"
31+
commit-check:
32+
image: python:3.13
33+
variables:
34+
GIT_DEPTH: "0"
35+
rules:
36+
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
37+
script:
38+
- pip install commit-check
39+
- echo "$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME" | commit-check --branch
40+
- |
41+
head="${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA:-$CI_COMMIT_SHA}"
42+
shas=$(git rev-list "$CI_MERGE_REQUEST_DIFF_BASE_SHA..$head") || exit 1
43+
status=0
44+
for sha in $shas; do
45+
commit-check --message --rev "$sha" --compact || status=1
46+
done
47+
exit $status
48+
```
49+
50+
- `GIT_DEPTH: "0"` turns shallow cloning off.
51+
- In a merged results pipeline, `HEAD` is a merge commit GitLab made, and
52+
`CI_MERGE_REQUEST_SOURCE_BRANCH_SHA` names the merge request's own last
53+
commit. In a plain merge request pipeline that variable is empty and
54+
`CI_COMMIT_SHA` is that commit.
55+
- The `python` image ships with git. A `-slim` image does not, and needs it
56+
installed first.
57+
58+
## Bitbucket Pipelines
59+
60+
```yaml title="bitbucket-pipelines.yml"
61+
image: python:3.13
62+
63+
pipelines:
64+
pull-requests:
65+
'**':
66+
- step:
67+
name: Commit Check
68+
clone:
69+
depth: full
70+
script:
71+
- pip install commit-check
72+
- echo "$BITBUCKET_BRANCH" | commit-check --branch
73+
- |
74+
shas=$(git rev-list "$BITBUCKET_PR_DESTINATION_COMMIT..$BITBUCKET_COMMIT") || exit 1
75+
status=0
76+
for sha in $shas; do
77+
commit-check --message --rev "$sha" --compact || status=1
78+
done
79+
exit $status
80+
```
81+
82+
- `depth: full` turns off the default clone depth of 50 commits.
83+
- Bitbucket merges the destination branch into the pull request before the
84+
step runs. The range stops at `BITBUCKET_COMMIT`, the pull request's own
85+
last commit, so commits that only came in with that merge are not checked.
86+
87+
## Azure Pipelines
88+
89+
```yaml title="azure-pipelines.yml"
90+
trigger: none
91+
92+
pr:
93+
branches:
94+
include: ["*"]
95+
96+
pool:
97+
vmImage: ubuntu-latest
98+
99+
steps:
100+
- checkout: self
101+
fetchDepth: 0
102+
- task: UsePythonVersion@0
103+
inputs:
104+
versionSpec: "3.13"
105+
- script: pip install commit-check
106+
displayName: Install Commit Check
107+
- script: echo "${SYSTEM_PULLREQUEST_SOURCEBRANCH#refs/heads/}" | commit-check --branch
108+
displayName: Check the branch name
109+
- script: |
110+
shas=$(git rev-list HEAD^1..HEAD^2) || exit 1
111+
status=0
112+
for sha in $shas; do
113+
commit-check --message --rev "$sha" --compact || status=1
114+
done
115+
exit $status
116+
displayName: Check the commit messages
117+
```
118+
119+
- `trigger: none` keeps the pipeline to pull requests; on a plain push there
120+
is no source branch to check and no merge commit to read the range from.
121+
- `fetchDepth: 0` turns off shallow fetch, which new pipelines have on by
122+
default.
123+
- A pull request build checks out a merge commit whose first parent is the
124+
target branch and second the pull request, so `HEAD^1..HEAD^2` is exactly
125+
the commits the pull request adds.
126+
- `System.PullRequest.SourceBranch` is `refs/heads/feature/x` in Azure Repos
127+
and `feature/x` for a GitHub repository; `#refs/heads/` strips the prefix
128+
where there is one.
129+
- In Azure Repos the `pr:` section is ignored. Pull request builds come from a
130+
[build validation branch policy](https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies#set-build-validation)
131+
on the target branch, and `System.PullRequest.SourceBranch` is only set for
132+
builds a branch policy started.

‎docs/guides/pre-commit.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Add Commit Check to `.pre-commit-config.yaml`:
88
```yaml title=".pre-commit-config.yaml"
99
repos:
1010
- repo: https://github.com/commit-check/commit-check
11-
rev: v2.18.1
11+
rev: v2.18.2
1212
hooks:
1313
- id: check-message
1414
- id: check-branch
@@ -55,7 +55,7 @@ Options can be passed as hook arguments, which keeps everything in one file:
5555
```yaml title=".pre-commit-config.yaml"
5656
repos:
5757
- repo: https://github.com/commit-check/commit-check
58-
rev: v2.18.1
58+
rev: v2.18.2
5959
hooks:
6060
- id: check-message
6161
args:

‎mkdocs.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ nav:
173173
- Pre-commit hook: guides/pre-commit.md
174174
- GitHub Action: guides/github-actions.md
175175
- GitHub App: guides/github-app.md
176+
- GitLab, Bitbucket, Azure: guides/other-ci.md
176177
- Across an organization: guides/organization.md
177178
- MCP server: guides/mcp.md
178179
- Python API: guides/python-api.md

0 commit comments

Comments
 (0)