Skip to content

Commit de84101

Browse files
claudebokelley
authored andcommitted
docs(contributing): document PR title format to prevent release-please CHANGELOG drops
Commit subjects with embedded ( ) or " in the description silently drop from release-please's CHANGELOG (verified in run 25326163877, three commits lost from v4.4.0). Root cause: the parser treats those characters as grammar tokens. Adds a "PR Title Format" subsection to CONTRIBUTING.md explaining the causal chain (squash-merge → commit subject → release-please parser) with before/after examples from the three affected commits (#577, #566, #443). Also adds scripts/check-commit-msg.sh and a pre-commit commit-msg stage hook as a best-effort guardrail for direct commits. Squash-merge subjects (set by GitHub from the PR title) bypass it, so the docs convention is the primary fix. Refs #578 https://claude.ai/code/session_01RZJ2jX6omDh5V9ua1UKkzy
1 parent 37d2cda commit de84101

3 files changed

Lines changed: 77 additions & 0 deletions

File tree

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ repos:
3030
types: [python]
3131
pass_filenames: false
3232
args: [src/adcp]
33+
- id: check-commit-msg
34+
name: release-please commit subject check
35+
entry: scripts/check-commit-msg.sh
36+
language: script
37+
stages: [commit-msg]
38+
always_run: true
3339

3440
# Security scanning with bandit
3541
- repo: https://github.com/PyCQA/bandit

CONTRIBUTING.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,39 @@ src/adcp/
8282
4. Update documentation
8383
5. Submit PR with clear description
8484

85+
### PR Title Format
86+
87+
This repository uses squash merges. The PR title becomes the commit subject that
88+
release-please reads to build the CHANGELOG and determine version bumps.
89+
90+
**The description portion of the commit subject — everything after `type(scope):`
91+
must not contain `(`, `)`, or `"` characters.** The release-please parser treats
92+
these as grammar tokens and silently drops the commit from the CHANGELOG with no
93+
error signal.
94+
95+
**Wrong — parser drops these commits silently:**
96+
97+
```
98+
fix(auth): synthesize AuthInfo(kind="bearer") in _build_request_context
99+
feat(auth): serve(auth=BearerTokenAuth(...)) — A2A sibling shortcut
100+
```
101+
102+
**Right — move code examples and parenthetical details to the PR body:**
103+
104+
```
105+
fix(auth): synthesize bearer AuthInfo in _build_request_context
106+
feat(auth): add A2A sibling and cross-transport shortcut for bearer auth
107+
```
108+
109+
Place code snippets, type names with parens, and parenthetical clarifications in the PR
110+
description body, not the title. release-please reads body footers (`BREAKING CHANGE:`,
111+
`Fixes #N`) but otherwise ignores the body for CHANGELOG purposes.
112+
113+
A `commit-msg` pre-commit hook (`scripts/check-commit-msg.sh`) catches violations on
114+
direct commits. It does **not** catch squash-merge subjects (those are set by GitHub on
115+
merge from the PR title), so keeping the PR title clean is the primary responsibility.
116+
To enable the hook: `pre-commit install --hook-type commit-msg`.
117+
85118
## Questions?
86119

87120
Open an issue or email maintainers@adcontextprotocol.org

scripts/check-commit-msg.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#!/usr/bin/env bash
2+
# Validates commit subjects against release-please parser constraints.
3+
# Embedded ( ) or " in the description silently drop commits from the CHANGELOG.
4+
# NOTE: this hook runs on direct commits only — squash-merge subjects (set by
5+
# GitHub from the PR title) bypass it. Keep the PR title clean as the primary fix.
6+
#
7+
# Enable: pre-commit install --hook-type commit-msg
8+
9+
set -euo pipefail
10+
11+
msg_file="$1"
12+
subject=$(head -1 "$msg_file")
13+
14+
# Only validate conventional commit messages: type(scope): desc or type: desc
15+
cc_pattern='^[a-z]+(\([^)]*\))?(!)?: '
16+
if echo "$subject" | grep -qE "$cc_pattern"; then
17+
description="${subject#*: }"
18+
if echo "$description" | grep -qE '[()"]'; then
19+
echo ""
20+
echo "commit-msg: release-please will silently drop this commit from the CHANGELOG."
21+
echo ""
22+
echo " Subject: $subject"
23+
echo ""
24+
echo ' The description (text after "type(scope):") contains ( ) or " characters,'
25+
echo " which break release-please's conventional commit parser."
26+
echo ""
27+
echo " Fix: reword to avoid parentheses and quotes in the description."
28+
echo " Move code snippets and type names with parens to the PR body instead."
29+
echo ""
30+
echo " Example:"
31+
echo ' Wrong: fix(auth): synthesize AuthInfo(kind="bearer") in _build_request_context'
32+
echo " Right: fix(auth): synthesize bearer AuthInfo in _build_request_context"
33+
echo ""
34+
exit 1
35+
fi
36+
fi
37+
38+
exit 0

0 commit comments

Comments
 (0)