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
54 changes: 28 additions & 26 deletions .claude/skills/pr-workflow/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,28 +49,29 @@ behaviour change that affects packet contents or timing —
reviewers shouldn't have to reverse-engineer why a constant moved
or a probe interval changed.

## 3. Commit message conventions

Commit messages are linted by `commitlint` with
`@commitlint/config-conventional`, _and_ by `commitizen` in
pre-commit (`stages: [commit-msg]`). Both must pass.

- **Conventional Commits prefix is required.** Pick from:
`feat`, `fix`, `perf`, `refactor`, `docs`, `test`, `build`,
`ci`, `chore`, `style`, `revert`. The `feat`/`fix`/`perf`
prefixes show up in the release-notes; `chore*` and `ci*` are
excluded by semantic-release (`exclude_commit_patterns` in
`pyproject.toml`), so use those for housekeeping.
## 3. PR title conventions

PRs are squash-merged, so the PR title becomes the commit on
`master`. Only the PR title is linted (by the `pr-title` CI job
running `amannn/action-semantic-pull-request`); per-commit
messages on the PR branch are not checked.

- **Conventional Commits prefix is required on the PR title.**
Pick from: `feat`, `fix`, `perf`, `refactor`, `docs`, `test`,
`build`, `ci`, `chore`, `style`, `revert`. The
`feat`/`fix`/`perf` prefixes show up in the release-notes;
`chore*` and `ci*` are excluded by semantic-release
(`exclude_commit_patterns` in `pyproject.toml`), so use those
for housekeeping.
- **Imperative-mood subject.** "fix: handle empty answer", not
"fix: handled empty answer".
- **No header length cap.** The commitlint config sets
`header-max-length: [0, "always", Infinity]`, so a slightly
longer subject is fine if it earns the space; don't pad.
- **Lowercase first character after the prefix** (enforced by
`subjectPattern: ^(?![A-Z]).+$`).
- **No `Co-Authored-By` trailers from automated agents.**
- **One logical change per commit.** Let pre-commit run (ruff
- **One logical change per PR.** Let pre-commit run (ruff
lint + format, mypy, flake8, codespell, cython-lint,
pyupgrade). If a hook auto-fixes something, re-stage and
re-commit; the commit-msg hook re-runs on the new commit.
re-commit.

## 4. Cython / `.pxd` discipline

Expand Down Expand Up @@ -101,22 +102,23 @@ Always pass the body via `--body-file`, never `--body "..."` with
shell-escaping — Markdown backticks, asterisks, and angle
brackets must pass through verbatim.

The PR title should match the commit subject (same Conventional
Commits prefix). If the PR ends up squash-merged, the title
becomes the merged commit message, so it has to satisfy
commitlint on its own.
The PR title is what gets enforced — it becomes the squash-merge
commit subject on `master`, so it has to parse as a Conventional
Commit on its own. Per-commit messages on the branch are not
linted.

## 6. After the PR is open

CI runs three jobs:

- `lint` — `pre-commit/action`. If pre-commit passed locally
this passes too.
- `commitlint` — `wagoid/commitlint-github-action`. Validates
every commit on the PR; if you amended after pushing, force-
push the branch so the rewritten commits get linted.
- `test` — the full pytest matrix across CPython 3.9–3.14,
3.14t (free-threaded), and PyPy 3.9 / 3.10, on Linux + macOS +
- `pr-title` — `amannn/action-semantic-pull-request`. Validates
the PR title against Conventional Commits. If it fails, fix
the title in the GitHub UI or with `gh pr edit --title "..."`;
the workflow re-runs on the edit, no push needed.
- `test` — the full pytest matrix across CPython 3.10–3.14,
3.14t (free-threaded), and PyPy 3.10, on Linux + macOS +
Windows. The free-threaded entry is the canary for unguarded
shared-state bugs; failures there are often genuine even when
the GIL-enabled rows pass.
Expand Down
23 changes: 9 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,10 @@ jobs:
python-version: "3.12"
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1

# Make sure commit messages follow the conventional commits convention:
# Make sure the PR title follows the conventional commits convention:
# https://www.conventionalcommits.org
commitlint:
name: Lint Commit Messages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@b948419dd99f3fd78a6548d48f94e3df7f6bf3ed # v6

# PRs are squash-merged, so the PR title becomes the commit subject on
# master. Validate it against Conventional Commits so the squashed commit
# stays release-tool-friendly even when individual commits don't.
# PRs are squash-merged, so the PR title becomes the commit on master and
# drives python-semantic-release's version bump.
pr-title:
name: Lint PR Title
runs-on: ubuntu-latest
Expand All @@ -48,6 +38,12 @@ jobs:
- uses: amannn/action-semantic-pull-request@48f256284bd46cdaab1048c3721360e808335d50 # v6.1.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
subjectPattern: ^(?![A-Z]).+$
subjectPatternError: |
The subject "{subject}" found in the pull request title "{title}"
didn't match the configured pattern. Please ensure that the subject
starts with a lowercase character.

test:
strategy:
Expand Down Expand Up @@ -155,7 +151,6 @@ jobs:
needs:
- test
- lint
- commitlint
if: ${{ github.repository_owner }} == "python-zeroconf"

runs-on: ubuntu-latest
Expand Down
5 changes: 0 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,6 @@ ci:
autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate"

repos:
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.16.2
hooks:
- id: commitizen
stages: [commit-msg]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
hooks:
Expand Down
22 changes: 13 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,17 @@ path. The authoritative list of cythonized modules lives in

## Commit / PR conventions

- **Conventional Commits are enforced.** CI runs commitlint with
`@commitlint/config-conventional`, and pre-commit runs
commitizen on the commit message. The header has no length cap
(`header-max-length = [0, "always", Infinity]`), but the
_type_ prefix is required: `feat:`, `fix:`, `chore:`, `ci:`,
`docs:`, `refactor:`, `test:`, `perf:`, `build:`, etc.
`semantic-release` excludes `chore*` and `ci*` from the
- **Conventional Commits PR title, lowercase subject.** PRs are
squash-merged, so the **PR title** becomes the commit on
`master` and is the only string that has to parse as a
Conventional Commit. The repo enforces this via the `pr-title`
CI job in `ci.yml` using `amannn/action-semantic-pull-request`.
Accepted types: `feat`, `fix`, `chore`, `ci`, `docs`,
`refactor`, `test`, `perf`, `build`, etc. The subject (text
after `type(scope):`) must start lowercase (enforced by
`subjectPattern: ^(?![A-Z]).+$`). Per-commit messages on the
PR branch are **not** linted; they get collapsed at squash-
merge. `semantic-release` excludes `chore*` and `ci*` from the
changelog, so use those prefixes for housekeeping and reserve
`feat`/`fix`/`perf` for user-visible changes.
- **No `Co-Authored-By` trailers from automated agents.** Project
Expand Down Expand Up @@ -267,8 +271,8 @@ or commit that names the bug class and the affected code path.
the resulting wheel will crash at import time.
- **Don't add `Co-Authored-By` trailers from automated agents
to commits** in this repo.
- **Don't introduce a commit message that violates Conventional
Commits.** The commitlint job will fail the PR.
- **Don't introduce a PR title that violates Conventional
Commits.** The `pr-title` job will fail the PR.
- **Don't tighten timings or constants in `const.py` without an
RFC citation in the commit message.** mDNS interop with
Avahi / Bonjour / Windows hinges on those numbers.
Expand Down
8 changes: 0 additions & 8 deletions commitlint.config.mjs

This file was deleted.

Loading