fix: revert ADR edits and enforce immutable accepted records
CI & Release / Verify documentation (push) Skipped
CI & Release / Verify simulator (push) Skipped
CI & Release / Trivy scan (push) Skipped
CI & Release / Semantic Release (push) Skipped
CI & Release / Verify documentation (pull_request) Successful in 6s
CI & Release / Verify simulator (pull_request) Failing after 10s
CI & Release / Trivy scan (pull_request) Skipped
CI & Release / Semantic Release (pull_request) Skipped
CI & Release / Verify documentation (push) Skipped
CI & Release / Verify simulator (push) Skipped
CI & Release / Trivy scan (push) Skipped
CI & Release / Semantic Release (push) Skipped
CI & Release / Verify documentation (pull_request) Successful in 6s
CI & Release / Verify simulator (pull_request) Failing after 10s
CI & Release / Trivy scan (pull_request) Skipped
CI & Release / Semantic Release (pull_request) Skipped
Restore docs/adr to main; add check_adrs.py CI gate so existing ADR-*.md files cannot be modified — supersede with a new numbered ADR instead.
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Reject modifications to accepted Architecture Decision Records."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
ADR_PREFIX = "docs/adr/ADR-"
|
||||
|
||||
|
||||
def _git(*args: str) -> str:
|
||||
return subprocess.check_output(
|
||||
["git", *args],
|
||||
cwd=ROOT,
|
||||
text=True,
|
||||
stderr=subprocess.DEVNULL,
|
||||
).strip()
|
||||
|
||||
|
||||
def _exists_on(base: str, path: str) -> bool:
|
||||
try:
|
||||
_git("cat-file", "-e", f"{base}:{path}")
|
||||
return True
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
|
||||
def find_modified_adrs(base: str) -> list[str]:
|
||||
try:
|
||||
diff_out = _git("diff", "--name-only", f"{base}...HEAD", "--", "docs/adr/")
|
||||
except subprocess.CalledProcessError:
|
||||
return []
|
||||
|
||||
modified: list[str] = []
|
||||
for rel in diff_out.splitlines():
|
||||
if not rel.startswith(ADR_PREFIX) or not rel.endswith(".md"):
|
||||
continue
|
||||
if _exists_on(base, rel):
|
||||
modified.append(rel)
|
||||
return sorted(modified)
|
||||
|
||||
|
||||
def run_check(base: str = "origin/main") -> int:
|
||||
modified = find_modified_adrs(base)
|
||||
if modified:
|
||||
print("Immutable ADR violation — accepted records cannot be edited:")
|
||||
for path in modified:
|
||||
print(f" error: {path}")
|
||||
print(
|
||||
"\nReversal or refinement → new ADR-NNNN file. "
|
||||
"Never edit an existing ADR-*.md."
|
||||
)
|
||||
return 1
|
||||
|
||||
print(f"ADR immutability OK (base {base})")
|
||||
return 0
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument(
|
||||
"--base",
|
||||
default="origin/main",
|
||||
help="Git ref to compare against (default: origin/main)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
sys.exit(run_check(base=args.base))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user