fix(install): verify a tagless checkout's commit-only source stamp
The source completion tail stamps baseVersion from the checkout's reachable release tag, which is null on a PR checkout, and the bootstrap verifier demanded a non-null baseVersion, so install.sh protocol failed on every upstream PR. It now requires the stamp and commit == HEAD, the identity the runtime actually reports.
This commit is contained in:
@@ -17,7 +17,8 @@ checkout it describes:
|
||||
* ``pinnedBranch`` equals the repo's checked-out branch (or ``--expect-branch``)
|
||||
* ``completedAt`` parses as an ISO-8601 UTC timestamp
|
||||
* the install carries its source identity stamp — ``install-stamp.json``
|
||||
with a ``baseVersion`` whose ``commit`` matches the installed checkout HEAD
|
||||
whose ``commit`` matches the installed checkout HEAD (``baseVersion`` is
|
||||
null when no release tag is reachable)
|
||||
|
||||
Usage:
|
||||
|
||||
@@ -145,31 +146,31 @@ def verify_stamp(stamp_path: Path, repo: Path, expect_commit: str | None, expect
|
||||
_fail(errors, f"pinnedBranch {branch!r} != checked-out branch {actual!r}")
|
||||
|
||||
# The install must carry its source identity stamp, and that stamp must
|
||||
# tell the truth about the checkout: baseVersion present, commit == HEAD.
|
||||
base_version, canonical_commit = _read_install_stamp(repo)
|
||||
if not base_version:
|
||||
_fail(errors, f"no baseVersion in {repo}/install-stamp.json — the install carries no source identity stamp")
|
||||
elif canonical_commit and head and canonical_commit != head:
|
||||
# tell the truth about the checkout: commit == HEAD. baseVersion is null
|
||||
# when no release tag is reachable (a PR checkout), exactly as the runtime
|
||||
# reports it.
|
||||
present, canonical_commit = _read_install_stamp(repo)
|
||||
if not present:
|
||||
_fail(errors, f"no {repo}/install-stamp.json — the install carries no source identity stamp")
|
||||
elif not canonical_commit:
|
||||
_fail(errors, f"{repo}/install-stamp.json names no commit")
|
||||
elif head and canonical_commit != head:
|
||||
_fail(errors, f"canonical stamp commit {canonical_commit[:12]} != installed HEAD {head[:12]}")
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def _read_install_stamp(repo: Path) -> tuple[str | None, str | None]:
|
||||
"""Read baseVersion + commit from the INSTALL repo's install-stamp.json."""
|
||||
def _read_install_stamp(repo: Path) -> tuple[bool, str | None]:
|
||||
"""Read whether the INSTALL repo's install-stamp.json exists, and its commit."""
|
||||
stamp_path = repo / "install-stamp.json"
|
||||
try:
|
||||
stamp = json.loads(stamp_path.read_text(encoding="utf-8-sig"))
|
||||
except (OSError, ValueError):
|
||||
return None, None
|
||||
return False, None
|
||||
if not isinstance(stamp, dict):
|
||||
return None, None
|
||||
base_version = stamp.get("baseVersion")
|
||||
return False, None
|
||||
commit = stamp.get("commit")
|
||||
return (
|
||||
base_version if isinstance(base_version, str) and base_version else None,
|
||||
commit if isinstance(commit, str) and commit else None,
|
||||
)
|
||||
return True, commit if isinstance(commit, str) and commit else None
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
@@ -82,8 +82,10 @@ def _install_repo(tmp_path: Path) -> Path:
|
||||
({"completedAt": "not-a-time"}, [], "ISO-8601"),
|
||||
({"completedAt": "2026-08-30T12:00:00+01:00"}, [], "not UTC"),
|
||||
({"missing": "stamp"}, [], "cannot read stamp"),
|
||||
({"missing": "version"}, [], "no baseVersion"),
|
||||
({"missing": "version"}, [], "no source identity stamp"),
|
||||
({"canonicalCommit": "c" * 40}, [], "canonical"),
|
||||
# A checkout with no reachable release tag honestly stamps a null base.
|
||||
({"canonicalBase": None}, [], None),
|
||||
])
|
||||
def test_verifier_cli(tmp_path, changes, expect, error):
|
||||
repo = _install_repo(tmp_path)
|
||||
@@ -94,9 +96,10 @@ def test_verifier_cli(tmp_path, changes, expect, error):
|
||||
path.write_text(json.dumps(stamp), encoding="utf-8")
|
||||
if changes.get("missing") == "version":
|
||||
(repo / "install-stamp.json").unlink()
|
||||
if "canonicalCommit" in changes:
|
||||
if "canonicalCommit" in changes or "canonicalBase" in changes:
|
||||
canonical = json.loads((repo / "install-stamp.json").read_text(encoding="utf-8"))
|
||||
canonical["commit"] = changes["canonicalCommit"]
|
||||
canonical["commit"] = changes.get("canonicalCommit", canonical["commit"])
|
||||
canonical["baseVersion"] = changes.get("canonicalBase", canonical["baseVersion"])
|
||||
(repo / "install-stamp.json").write_text(json.dumps(canonical), encoding="utf-8")
|
||||
if not error:
|
||||
expect = ["--expect-commit", stamp["pinnedCommit"], "--expect-branch", "main"]
|
||||
|
||||
Reference in New Issue
Block a user