From 880c0184cb65a2731b9f10d57473e3fb7edebb8c Mon Sep 17 00:00:00 2001 From: Bryant Date: Mon, 20 Jul 2026 19:53:50 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=90=9B=20(scripts):=20Make=20check=5F?= =?UTF-8?q?readme=5Fversion=20--check=20flag=20meaningful?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parsed args were discarded, so --check was a no-op: audit() ran unconditionally and drift always forced exit 1 regardless of the flag. Read args.check so --check gates (exit 1 on drift, the CI mode) while a bare invocation reports drift but exits 0 for informational runs. Refs AAASM-4942 --- scripts/check_readme_version.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/check_readme_version.py b/scripts/check_readme_version.py index 4f618529..9e17875b 100644 --- a/scripts/check_readme_version.py +++ b/scripts/check_readme_version.py @@ -69,9 +69,12 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument( "--check", action="store_true", - help="Audit only and exit non-zero on drift (the CI-gate mode).", + help=( + "Exit non-zero on drift (the CI-gate mode). Without it, drift is " + "reported but the exit code stays 0 for informational, non-gating runs." + ), ) - parser.parse_args(argv) + args = parser.parse_args(argv) root = _repo_root() drift = audit(root / "pyproject.toml", root / "README.md") @@ -84,7 +87,7 @@ def main(argv: list[str] | None = None) -> int: "the README sample to match. See ADR 0013.", file=sys.stderr, ) - return 1 + return 1 if args.check else 0 print("README sample-output version is in sync with the pyproject.toml anchor.") return 0 From 1f65cd924e44bc6a356579bd09cfc1ddaf21c5a0 Mon Sep 17 00:00:00 2001 From: Bryant Date: Mon, 20 Jul 2026 19:54:20 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=85=20(scripts):=20Add=20regression?= =?UTF-8?q?=20tests=20for=20check=5Freadme=5Fversion=20--check=20gating?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pin the two distinct modes so --check can't regress to a no-op: --check exits 1 on drift while a bare run reports drift but exits 0. Refs AAASM-4942 --- test/unit/test_check_readme_version.py | 59 ++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 test/unit/test_check_readme_version.py diff --git a/test/unit/test_check_readme_version.py b/test/unit/test_check_readme_version.py new file mode 100644 index 00000000..c1d50ef5 --- /dev/null +++ b/test/unit/test_check_readme_version.py @@ -0,0 +1,59 @@ +"""Regression tests for ``scripts/check_readme_version.py``. + +AAASM-4942: the ``--check`` flag used to be a no-op — its parsed value was +discarded and drift always forced a non-zero exit. These tests pin the two +distinct modes so the flag can't silently regress back to a single mode: +``--check`` gates (exit 1 on drift) while the default reports drift but exits 0. +""" + +from __future__ import annotations + +import importlib.util +from pathlib import Path +from types import ModuleType + +import pytest + +_SCRIPT = Path(__file__).resolve().parents[2] / "scripts" / "check_readme_version.py" + + +def _load_module() -> ModuleType: + spec = importlib.util.spec_from_file_location("check_readme_version", _SCRIPT) + 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 + + +def _write_tree(root: Path, *, anchor: str, sample: str) -> None: + (root / "pyproject.toml").write_text(f'[project]\nversion = "{anchor}"\n', encoding="utf-8") + (root / "README.md").write_text(f"aasm --version # e.g. aasm {sample}\n", encoding="utf-8") + + +@pytest.fixture +def script(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> tuple[ModuleType, Path]: + module = _load_module() + monkeypatch.setattr(module, "_repo_root", lambda: tmp_path) + return module, tmp_path + + +def test_check_exits_nonzero_on_drift(script: tuple[ModuleType, Path]) -> None: + module, root = script + _write_tree(root, anchor="0.0.1rc6", sample="9.9.9-STALE") + + assert module.main(["--check"]) == 1 + + +def test_default_reports_drift_but_exits_zero(script: tuple[ModuleType, Path]) -> None: + module, root = script + _write_tree(root, anchor="0.0.1rc6", sample="9.9.9-STALE") + + assert module.main([]) == 0 + + +def test_both_modes_pass_when_in_sync(script: tuple[ModuleType, Path]) -> None: + module, root = script + _write_tree(root, anchor="0.0.1rc6", sample="0.0.1rc6") + + assert module.main(["--check"]) == 0 + assert module.main([]) == 0