fix(version): exclude badge-bot commits from PATCH counter; require CHANGELOG entry per PR#232
Merged
Merged
Conversation
…de): require CHANGELOG.md entry per PR scripts/version.py's PATCH counter (README Version badge) used git describe --tags --long's raw commit count. Every push to main adds two commits: the merge/squash commit itself and a separate "chore(ci): update badges [skip ci]" bot commit (.github/workflows/ci.yml), which fires almost every time since the version badge changes on every commit. PATCH was growing roughly 2x faster than the number of real merged changes (34 raw commits since v1.6.0 vs. 21 excluding the bot). project_version() now gets the tag via `git describe --tags --abbrev=0` and counts commits separately via `git rev-list --count <tag>..HEAD --invert-grep --grep="chore(ci): update badges" --fixed-strings`, so the bot's own commits no longer inflate the count. Chose excluding bot commits over the inverse (counting only bot commits as a merge-count proxy) because it degrades safely: if the badge workflow ever changes or stops firing, PATCH keeps counting real commits instead of silently freezing. Does not affect setuptools-scm's own package version (X.Y.0.postN) -- that has independent, non-filterable commit-counting logic; scripts/version.py only drives the README badge. Also adds a CLAUDE.md rule (raised directly by the maintainer) that was missing: CHANGELOG.md needs an [Unreleased] entry in every merged PR, no exceptions for internal refactors -- the five-PR cli.py decomposition epic (#117-#122) that just landed skipped it entirely, which is exactly the gap this rule closes. docs/history.md and CHECKPOINT.md stay release-cadence (once per git tag), not per-PR, matching how they were already being used. Backfilled the CHANGELOG.md [Unreleased] entry for that epic and this fix, applying the new rule immediately rather than leaving it for the next release. Issue #231. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Applying the CHANGELOG-per-PR rule just added to CLAUDE.md immediately surfaced how far behind it already was: nine non-bot commits landed between the v1.6.0 tag and this session's work without ever getting a CHANGELOG.md entry (Runner Protocol abstraction #136-140, lazy CONFIG + i18n foundation #141-145, Stepik client retry/backoff #108-111, TestResult/Verdict #112-116, two bugfixes #191/#214, and three docs/CI PRs #173/#213/#215-218/#199/#116/#140/#156/#157/#152/#150/#204). Expanded [Unreleased] to cover all of them under Added/Fixed/Docs, alongside the cli.py decomposition entry from the prior commit. docs/history.md never got an archival entry for the v1.6.0 release itself (last entry was around issue #72, well before the epics that shipped in 1.6.0) -- added one, plus the missing v1.6.0 row in the metrics table (784 tests / 95%, matching CLAUDE.md's own metrics and docs/versions.md's canonical table). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three things, all raised directly by the maintainer:
1. Version counting was wrong.
scripts/version.py's PATCH counter usedgit describe --tags --long's raw commit count. Every push tomainlands two commits — the merge/squash commit and CI's ownchore(ci): update badges [skip ci]bot commit (fires almost every time, since the version badge changes on every commit) — so PATCH grew ~2x faster than real merged changes. Verified on current history: 34 raw commits sincev1.6.0, only 21 excluding the bot.Fixed by switching to
git rev-list --count <tag>..HEAD --invert-grep --grep="chore(ci): update badges" --fixed-strings. Chose excluding bot commits over the inverse (counting only bot commits as a merge-count proxy) — it degrades safely: if the badge workflow ever changes, PATCH keeps counting real commits instead of silently freezing. Doesn't touchsetuptools-scm's own package version (X.Y.0.postN) — independent, non-filterable logic;scripts/version.pyonly drives the README badge. Closes #231.2.
CHANGELOG.md/docs/history.mdupdate cadence was never a written rule. Added a CLAUDE.md section making it explicit:CHANGELOG.mdgets an[Unreleased]entry in every merged PR (no carve-out for "internal" refactors), whiledocs/history.md/CHECKPOINT.mdstay release-cadence (once per git tag).3. Applying that rule immediately surfaced how far behind both files already were. Nine non-bot commits landed between the
v1.6.0tag and this session's work without a CHANGELOG entry: Runner Protocol abstraction (#136-140), lazy CONFIG + i18n foundation (#141-145), Stepik client retry/backoff (#108-111),TestResult/Verdict(#112-116), two bugfixes (#191/#214), and several docs/CI PRs (#173/#213/#215-218 and the architecture-docs batch #199/#116/#140/#156/#157/#152/#150/#204). Backfilled[Unreleased]with all of it, plus thecli.pydecomposition epic (#117-#122) and this PR's own fix.docs/history.mdnever got an archival entry for thev1.6.0release itself (last entry predated the epics that shipped in it) — added one, plus the missingv1.6.0row in the metrics table (784 tests / 95%, matchingdocs/versions.md's canonical table).Test plan
pytest tests/test_version_script.py tests/test_generate_version_badge.py tests/test_check_version_consistency.py -v— 17 passed, including a new regression test asserting the--invert-grep/--fixed-stringsargs are actually passedpytest tests/ -q— 847 passed, 3 skippedpython scripts/version.py— now prints1.6.21(was1.6.34)python scripts/check_version_consistency.py— still passes with the new CHANGELOG contentpython scripts/check_docs_guardrails.py— README budget + Markdown links still OK (323 links checked)ruff check/ruff format --check/mypy— clean🤖 Generated with Claude Code