Skip to content

release check: the changelog date has to be true, not just present - #39

Merged
github-actions[bot] merged 1 commit into
mainfrom
ci/changelog-date-must-be-true
Aug 18, 2026
Merged

release check: the changelog date has to be true, not just present#39
github-actions[bot] merged 1 commit into
mainfrom
ci/changelog-date-must-be-true

Conversation

@melbinjp

@melbinjp melbinjp commented Aug 18, 2026

Copy link
Copy Markdown
Owner

check_release.py required a release section to carry a date. It never asked
whether the date was right.

rigout 0.3.1 shipped carrying:

## [0.3.1] - 2026-08-02

PyPI recorded the upload on 2026-08-17. Every check in the file passed: the
version matched, the tag matched, the section had a date and was not empty. The
entry was drafted when the work was done and never touched again when it went
out fifteen days later.

A changelog is read for the one thing git log does not answer at a glance -
when a version reached users - and this one was wrong by two weeks. Nothing
failed, because nothing looked.

The rule

When a tag is being released, the date on that version's heading must be the day
it goes out.

Not applied to the working tree. Without a tag the date is legitimately the day
the entry was drafted, and failing a pull request for that would be noise. One
day of tolerance either way, because the release runs on a UTC runner and the
entry is written in whoever's local timezone.

Verified against the real defect, before the tests were written

Run on this repository with the changelog as it stood:

$ python scripts/check_release.py
Release checks passed for 0.3.1.

$ python scripts/check_release.py --tag v0.3.1
Release checks failed:
  - the `## [0.3.1]` heading is dated 2026-08-02 but this release is going out
    on 2026-08-18, 16 days later. The date says when a version reached users, so
    an entry drafted early and never updated makes the changelog wrong about the
    one thing it is read for.

Silent without a tag, refuses with one. 0.3.1's date is corrected to the upload
date in this PR.

One thing this change would have broken

test_the_matching_tag_passes and test_a_tag_naming_another_version_is_refused
call check() with a tag and the real clock. Passing a tag now also checks the
date, so both would have started failing the day after the changelog was last
written - a test that goes red on a calendar rather than on a defect. Both now
pin today to the entry's own date; date drift has its own tests.

Checks

591 unit tests pass, ruff and mypy clean. The new tests were mutation-checked:
making stale_date_problem always return None fails exactly the three that
assert refusal, and the two tolerance tests correctly survive it.

check_release.py required a release section to carry a date and never asked
whether the date was right. 0.3.1 shipped carrying '## [0.3.1] - 2026-08-02'
while PyPI recorded the upload on 2026-08-17. Every existing check passed: the
version matched, the tag matched, the section had a date and was not empty. The
entry was drafted when the work was done and never touched again when it went
out fifteen days later.

A changelog is read for the one thing a git log does not answer at a glance -
when a version reached users - and this one was wrong by two weeks.

Only applied when a tag is being released. On the working tree the date is
legitimately the day the entry was drafted, and failing a pull request for that
would be noise. One day of tolerance either way, because the release runs on a
UTC runner and the entry is written in the author's own timezone.

Also corrected 0.3.1's date to the PyPI upload date, and pinned 'today' in the
two existing tests that pass a tag - they call check() with the real clock, so
without that they would have started failing the day after the changelog was
last written.
@github-actions
github-actions Bot enabled auto-merge (squash) August 18, 2026 08:14
@github-actions

github-actions Bot commented Aug 18, 2026

Copy link
Copy Markdown

Jules Review

COVERAGE: 2c965f6 3 files

Summary

This PR enforces that a released tag's changelog date matches the day it is actually tagged, preventing a release's recorded date from silently drifting from its drafted date. It accurately parses the date, computes the drift, and enforces a one-day tolerance to account for timezone differences between the author and the UTC runner. The test coverage correctly pins dates where necessary to ensure isolation of the tested behaviors. The fix for the variable shadowing of datetime.date is cleanly implemented. Overall, this is a solid set of changes.

Findings

[WARN]

scripts/check_release.py, line 198 - The regex CHANGELOG_HEADING matches any string shaped like YYYY-MM-DD, including impossible dates like 2026-02-30. Calling date.fromisoformat(entry_date) directly on these strings will crash the script with a raw ValueError rather than gracefully appending to the problems list. Wrapping this parsing in a try...except ValueError: block to report the malformed date would keep the script robust and allow it to aggregate other problems in the same run.

Verdict

VERDICT: comment


This review never edits code or force-blocks a merge. No blocking issues were found, so this PR was auto-approved.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated approval: Jules found no blocking issues (verdict: comment). See the review comment above.

@github-actions
github-actions Bot merged commit 1bea5c1 into main Aug 18, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant