From dcd69f6a8f6ad976cd2dadba749a9788b937c23d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 4 May 2026 15:10:41 +0000 Subject: [PATCH 1/2] docs(contributing): document PR title format to prevent release-please CHANGELOG drops MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .pre-commit-config.yaml | 6 ++++++ CONTRIBUTING.md | 33 ++++++++++++++++++++++++++++++++ scripts/check-commit-msg.sh | 38 +++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100755 scripts/check-commit-msg.sh diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c640cf003..a9437a316 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -30,6 +30,12 @@ repos: types: [python] pass_filenames: false args: [src/adcp] + - id: check-commit-msg + name: release-please commit subject check + entry: scripts/check-commit-msg.sh + language: script + stages: [commit-msg] + always_run: true # Security scanning with bandit - repo: https://github.com/PyCQA/bandit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a443d8369..3595315bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -82,6 +82,39 @@ src/adcp/ 4. Update documentation 5. Submit PR with clear description +### PR Title Format + +This repository uses squash merges. The PR title becomes the commit subject that +release-please reads to build the CHANGELOG and determine version bumps. + +**The description portion of the commit subject — everything after `type(scope):` — +must not contain `(`, `)`, or `"` characters.** The release-please parser treats +these as grammar tokens and silently drops the commit from the CHANGELOG with no +error signal. + +**Wrong — parser drops these commits silently:** + +``` +fix(auth): synthesize AuthInfo(kind="bearer") in _build_request_context +feat(auth): serve(auth=BearerTokenAuth(...)) — A2A sibling shortcut +``` + +**Right — move code examples and parenthetical details to the PR body:** + +``` +fix(auth): synthesize bearer AuthInfo in _build_request_context +feat(auth): add A2A sibling and cross-transport shortcut for bearer auth +``` + +Place code snippets, type names with parens, and parenthetical clarifications in the PR +description body, not the title. release-please reads body footers (`BREAKING CHANGE:`, +`Fixes #N`) but otherwise ignores the body for CHANGELOG purposes. + +A `commit-msg` pre-commit hook (`scripts/check-commit-msg.sh`) catches violations on +direct commits. It does **not** catch squash-merge subjects (those are set by GitHub on +merge from the PR title), so keeping the PR title clean is the primary responsibility. +To enable the hook: `pre-commit install --hook-type commit-msg`. + ## Questions? Open an issue or email maintainers@adcontextprotocol.org diff --git a/scripts/check-commit-msg.sh b/scripts/check-commit-msg.sh new file mode 100755 index 000000000..5507732ca --- /dev/null +++ b/scripts/check-commit-msg.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Validates commit subjects against release-please parser constraints. +# Embedded ( ) or " in the description silently drop commits from the CHANGELOG. +# NOTE: this hook runs on direct commits only — squash-merge subjects (set by +# GitHub from the PR title) bypass it. Keep the PR title clean as the primary fix. +# +# Enable: pre-commit install --hook-type commit-msg + +set -euo pipefail + +msg_file="$1" +subject=$(head -1 "$msg_file") + +# Only validate conventional commit messages: type(scope): desc or type: desc +cc_pattern='^[a-z]+(\([^)]*\))?(!)?: ' +if echo "$subject" | grep -qE "$cc_pattern"; then + description="${subject#*: }" + if echo "$description" | grep -qE '[()"]'; then + echo "" + echo "commit-msg: release-please will silently drop this commit from the CHANGELOG." + echo "" + echo " Subject: $subject" + echo "" + echo ' The description (text after "type(scope):") contains ( ) or " characters,' + echo " which break release-please's conventional commit parser." + echo "" + echo " Fix: reword to avoid parentheses and quotes in the description." + echo " Move code snippets and type names with parens to the PR body instead." + echo "" + echo " Example:" + echo ' Wrong: fix(auth): synthesize AuthInfo(kind="bearer") in _build_request_context' + echo " Right: fix(auth): synthesize bearer AuthInfo in _build_request_context" + echo "" + exit 1 + fi +fi + +exit 0 From c512da2b85b9241ba570f378c8e8ebe5581cc9f7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 4 May 2026 15:17:26 +0000 Subject: [PATCH 2/2] docs(contributing): address pre-PR review feedback - Prose: clarify that paren/quote ban applies to the description portion only, not to type(scope) prefix; add parenthetical to prevent misreading - Dev Setup: add pre-commit hook installation steps so new contributors get the commit-msg hook active without reading the PR Title section - pre-commit config: remove always_run on commit-msg hook (redundant) https://claude.ai/code/session_01RZJ2jX6omDh5V9ua1UKkzy --- .pre-commit-config.yaml | 1 - CONTRIBUTING.md | 17 ++++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a9437a316..f972a2c97 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -35,7 +35,6 @@ repos: entry: scripts/check-commit-msg.sh language: script stages: [commit-msg] - always_run: true # Security scanning with bandit - repo: https://github.com/PyCQA/bandit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3595315bd..ff1e3051e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,9 +10,11 @@ git clone https://github.com/adcontextprotocol/adcp-client-python.git cd adcp-client-python ``` -2. Install dependencies: +2. Install dependencies and pre-commit hooks: ```bash pip install -e ".[dev]" +pre-commit install +pre-commit install --hook-type commit-msg ``` 3. Run tests: @@ -87,10 +89,11 @@ src/adcp/ This repository uses squash merges. The PR title becomes the commit subject that release-please reads to build the CHANGELOG and determine version bumps. -**The description portion of the commit subject — everything after `type(scope):` — +**The description portion of the commit subject — the text after `type(scope):` — must not contain `(`, `)`, or `"` characters.** The release-please parser treats -these as grammar tokens and silently drops the commit from the CHANGELOG with no -error signal. +those characters as grammar tokens when they appear in the description and silently +drops the commit from the CHANGELOG with no error signal. (The `type(scope)` prefix +itself is fine; only the description portion is constrained.) **Wrong — parser drops these commits silently:** @@ -107,13 +110,13 @@ feat(auth): add A2A sibling and cross-transport shortcut for bearer auth ``` Place code snippets, type names with parens, and parenthetical clarifications in the PR -description body, not the title. release-please reads body footers (`BREAKING CHANGE:`, -`Fixes #N`) but otherwise ignores the body for CHANGELOG purposes. +body (release-please reads body footers like `BREAKING CHANGE:` and `Fixes #N` but +otherwise ignores the body for CHANGELOG purposes). A `commit-msg` pre-commit hook (`scripts/check-commit-msg.sh`) catches violations on direct commits. It does **not** catch squash-merge subjects (those are set by GitHub on merge from the PR title), so keeping the PR title clean is the primary responsibility. -To enable the hook: `pre-commit install --hook-type commit-msg`. +Hook setup is included in step 2 of Development Setup above. ## Questions?