From 1a116b3c6492347e040d0546135c9b4c70540fbb Mon Sep 17 00:00:00 2001 From: Mads Lorentzen <50207393+MadsLorentzen@users.noreply.github.com> Date: Sun, 6 Sep 2026 20:19:17 +0200 Subject: [PATCH] chore(release): cut v1.7.1 (#434) Rolls [Unreleased] into [1.7.1] - 2026-09-06 and moves the compare links. Keeps an empty [Unreleased] heading above the release, per Keep a Changelog, and teaches the CHANGELOG structure guard that an absent [Unreleased] section is nothing to check rather than an error. Claude-Session: https://claude.ai/code/session_013fqqLgQSnwgWkv98twQhHi Co-authored-by: Claude Fable 5.1 --- CHANGELOG.md | 5 ++++- tests/test_changelog_structure.py | 15 +++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66db8da..f6cee2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ per-file diff commands. ## [Unreleased] +## [1.7.1] - 2026-09-06 + ### Added - **CHANGELOG structure guard** (`tests/test_changelog_structure.py`) - every PR edits this one @@ -1212,7 +1214,8 @@ At this baseline the framework provides: - **Cross-runtime support** - a root `AGENTS.md` pointer so Codex and Antigravity can discover the portable portal skills, with Claude Code as the reference runtime. -[Unreleased]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.7.0...HEAD +[Unreleased]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.7.1...HEAD +[1.7.1]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.7.0...v1.7.1 [1.7.0]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.6.0...v1.7.0 [1.6.0]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.5.0...v1.6.0 [1.5.0]: https://github.com/MadsLorentzen/ai-job-search/compare/v1.4.0...v1.5.0 diff --git a/tests/test_changelog_structure.py b/tests/test_changelog_structure.py index 27d15c2..7590f86 100644 --- a/tests/test_changelog_structure.py +++ b/tests/test_changelog_structure.py @@ -24,8 +24,13 @@ CONFLICT_MARKERS = ("<<<<<<< ", "=======", ">>>>>>> ") def unreleased_block(text: str) -> str: - """The lines between `## [Unreleased]` and the next `## [` heading.""" - start = text.index("## [Unreleased]") + """The lines between `## [Unreleased]` and the next `## [` heading. + + An absent heading (right after a release cut) yields an empty block: + nothing to check is not a defect.""" + start = text.find("## [Unreleased]") + if start == -1: + return "" end = text.find("\n## [", start + 1) return text[start:] if end == -1 else text[start:end] @@ -108,6 +113,12 @@ class UnreleasedProblemsTests(unittest.TestCase): problems = unreleased_problems(text) self.assertTrue(any("conflict marker" in p for p in problems), problems) + def test_missing_unreleased_section_is_not_a_defect(self): + # Right after a release cut there may be no [Unreleased] heading at all + # (the 1.7.0 cut removed it). Nothing to check is not a failure. + text = "# Changelog\n\n## [1.7.1] - 2026-09-06\n\n### Fixed\n\n- **A fixed thing** - described.\n" + self.assertEqual(unreleased_problems(text), []) + def test_released_sections_are_not_inspected(self): # A duplicate heading in an old release is history, not a defect here. text = CLEAN + "\n### Fixed\n\n- another old entry\n"