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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- uses: actions/setup-python@v5
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
with:
python-version: "3.11"
- run: python scripts/check_version_linearity.py
Expand Down
8 changes: 7 additions & 1 deletion scripts/check_version_linearity.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ def check(root: Path) -> tuple[int, str]:
if not changelog_path.exists():
return 1, f"CHANGELOG.md not found at {changelog_path}"

declared = tomllib.loads(pyproject_path.read_text())["project"]["version"]
try:
declared = tomllib.loads(pyproject_path.read_text())["project"]["version"]
except tomllib.TOMLDecodeError as exc:
return 1, f"invalid pyproject.toml: {exc}"
except (KeyError, TypeError):
return 1, "pyproject.toml must define [project].version"

latest = latest_changelog_version(changelog_path.read_text())

if latest is None:
Expand Down
18 changes: 17 additions & 1 deletion tests/scripts/test_version_linearity.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
def _load_script():
"""Import the script as a module (it is under scripts/, outside the package tree)."""
spec = importlib.util.spec_from_file_location("check_version_linearity", SCRIPT)
module = importlib.util.module_from_spec(spec) # type: ignore[arg-type]
assert spec is not None and spec.loader is not None
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module

Expand Down Expand Up @@ -79,6 +79,22 @@ def test_version_linearity_fails_when_changelog_missing(tmp_path: Path, script)
assert "CHANGELOG.md not found" in message


def test_version_linearity_fails_on_malformed_pyproject(tmp_path: Path, script) -> None:
(tmp_path / "pyproject.toml").write_text('[project\nversion = "1.0.0"\n')
(tmp_path / "CHANGELOG.md").write_text("# Changelog\n\n## [1.0.0] - 2026-04-28\n")
code, message = script.check(tmp_path)
assert code == 1
assert "invalid pyproject.toml" in message


def test_version_linearity_fails_when_pyproject_lacks_version(tmp_path: Path, script) -> None:
(tmp_path / "pyproject.toml").write_text('[project]\nname = "x"\n')
(tmp_path / "CHANGELOG.md").write_text("# Changelog\n\n## [1.0.0] - 2026-04-28\n")
code, message = script.check(tmp_path)
assert code == 1
assert "[project].version" in message


def test_latest_changelog_version_picks_first_versioned_header(script) -> None:
text = """# Changelog

Expand Down
Loading