Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The project follows Semantic Versioning.

## [Unreleased]

## [0.1.7] - 2026-08-24
## [0.1.8] - 2026-08-25

- Added a trusted default-branch Dependabot catalog synchronizer. Failed
same-repository Dependabot action bumps are updated in place from a
Expand All @@ -27,6 +27,9 @@ The project follows Semantic Versioning.
- Isolated owner-only side-effect runtime fixtures from Dependabot pull
requests so real bot commits and repository labels are never mistaken for
disposable commitlint or label-mutation evidence.
- Made release-ledger date reconciliation timezone-independent by deriving the
tagged commit's UTC author date. The signed `0.1.7` tag remains immutable
rejected evidence and has no release.

## [0.1.6] - 2026-08-24

Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.7
0.1.8
17 changes: 15 additions & 2 deletions scripts/check_release_ledger.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"""
from __future__ import annotations

import datetime as dt
import re
import subprocess
import sys
Expand Down Expand Up @@ -48,9 +49,14 @@
KNOWN_UNRELEASED_TAGS: dict[str, str] = {
"0.1.4": "tag target still declared VERSION 0.1.3; preflight rejected run 32620039075",
"0.1.5": "historical 0.1.4 tag lacked a release heading; preflight rejected run 32748217729",
"0.1.7": "timezone-dependent ledger date rejected release run 32764221081",
}


def _utc_date(value: str) -> str:
return dt.datetime.fromisoformat(value).astimezone(dt.timezone.utc).date().isoformat()


def _headings() -> tuple[list[tuple[int, str, str | None]], list[str]]:
"""Every release heading as (line number, version, date), plus problems."""
problems: list[str] = []
Expand Down Expand Up @@ -228,6 +234,8 @@ def case(label, headings, tags, known, dates, expected):
case("date-mismatch", one, {"1.0.0"}, {}, {"1.0.0": "2026-01-02"},
["1.0.0 is dated 2026-01-01 in CHANGELOG.md but its tag is 2026-01-02"])
case("unknown-tag-date-tolerated", one, {"1.0.0"}, {}, {}, [])
if _utc_date("2026-08-25T00:30:00+06:00") != "2026-08-24":
problems.append("UTC date selftest accepted a local-midnight rollover")

for version, reason in KNOWN_UNTAGGED.items():
if not str(reason).strip():
Expand All @@ -251,10 +259,15 @@ def check_tags() -> list[str]:

def tag_date(version: str) -> str | None:
shown = subprocess.run(
["git", "log", "-1", "--format=%ad", "--date=short", version],
["git", "log", "-1", "--format=%aI", version],
cwd=REPO_ROOT, env=clean_environment(), capture_output=True, text=True, check=False,
)
return shown.stdout.strip() if shown.returncode == 0 else None
if shown.returncode != 0 or not shown.stdout.strip():
return None
try:
return _utc_date(shown.stdout.strip())
except ValueError:
return None

return problems + _reconcile(
headings, tags, KNOWN_UNTAGGED, tag_date, KNOWN_UNRELEASED_TAGS
Expand Down
Loading