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
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"command": "uv run python -m pytest tests/e2e -x -q",
"ran_at": 1788607604,
"exit_code": 0,
"commit": "827aa4770e160cb96d1bf4864d61c14f8abc31ba",
"branch": "claude/ofpf-attestation-guard-split-r7m2"
}
21 changes: 21 additions & 0 deletions internals/checks/src/checks/attestation_guard/commit_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""The commit bodies over a range, for the attestation-guard check (#1043).

Shells out for exactly this one piece of data, so the decision logic in
`decide.py` stays subprocess-free and unit-testable.
"""

from __future__ import annotations

import subprocess


def commit_messages(base_sha: str, head_sha: str, runner=subprocess.run) -> str:
# Raw bodies (`%B`), scanned for the bypass line without git's trailer
# parser, so the bypass works from any line of any commit in the range.
result = runner(
["git", "log", "--format=%B", f"{base_sha}..{head_sha}"],
capture_output=True,
text=True,
check=True,
)
return result.stdout
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from unittest import mock

from checks.attestation_guard.commit_messages import commit_messages


def describe_commit_messages():
def returns_raw_bodies_via_the_two_dot_range():
runner = mock.Mock(return_value=mock.Mock(stdout="fix: x\n"))
assert commit_messages("base", "head", runner=runner) == "fix: x\n"
runner.assert_called_once_with(
["git", "log", "--format=%B", "base..head"],
capture_output=True,
text=True,
check=True,
)
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""Thin git subprocess wrappers for the attestation-guard check (#1043).
"""The paths a range deletes, for the attestation-guard check (#1043).

Each shells out for exactly one piece of data, so the decision logic in
Shells out for exactly this one piece of data, so the decision logic in
`decide.py` stays subprocess-free and unit-testable.
"""

Expand All @@ -21,15 +21,3 @@ def deleted_files(base_sha: str, head_sha: str, runner=subprocess.run) -> list[s
check=True,
)
return [line for line in result.stdout.splitlines() if line]


def commit_messages(base_sha: str, head_sha: str, runner=subprocess.run) -> str:
# Raw bodies (`%B`), scanned for the bypass line without git's trailer
# parser, so the bypass works from any line of any commit in the range.
result = runner(
["git", "log", "--format=%B", f"{base_sha}..{head_sha}"],
capture_output=True,
text=True,
check=True,
)
return result.stdout
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from unittest import mock

from checks.attestation_guard.git_ops import commit_messages, deleted_files
from checks.attestation_guard.deleted_files import deleted_files


def describe_deleted_files():
Expand All @@ -22,15 +22,3 @@ def parses_stdout_into_lines():
def drops_blank_lines():
runner = mock.Mock(return_value=mock.Mock(stdout="a.json\n\n"))
assert deleted_files("base", "head", runner=runner) == ["a.json"]


def describe_commit_messages():
def returns_raw_bodies_via_the_two_dot_range():
runner = mock.Mock(return_value=mock.Mock(stdout="fix: x\n"))
assert commit_messages("base", "head", runner=runner) == "fix: x\n"
runner.assert_called_once_with(
["git", "log", "--format=%B", "base..head"],
capture_output=True,
text=True,
check=True,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""The per-file annotation for one wrongly-deleted receipt (#1043)."""

from __future__ import annotations


def deletion_annotation(path: str) -> str:
"""The per-file annotation naming one wrongly-deleted receipt."""
return (
f"::error file={path}::{path} is an e2e attestation receipt. "
"Receipts are append-only; this PR deletes it."
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from checks.attestation_guard.deletion_annotation import deletion_annotation


def describe_deletion_annotation():
def names_the_file_and_the_append_only_rule():
line = deletion_annotation("packages/ts/e2e-attestations/a.json")
assert line.startswith("::error file=packages/ts/e2e-attestations/a.json::")
assert "packages/ts/e2e-attestations/a.json is an e2e attestation receipt" in line
assert "Receipts are append-only; this PR deletes it." in line
24 changes: 6 additions & 18 deletions internals/checks/src/checks/attestation_guard/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,18 @@

from __future__ import annotations

from checks.attestation_guard import git_ops
from checks.attestation_guard.decide import (
deleted_receipts,
has_allow_line,
near_miss_lines,
)
from checks.attestation_guard.report import report


def verdict(deleted, messages: str, base_sha: str) -> int:
"""0 when a well-formed bypass line is present, else 1 with diagnostics."""
if has_allow_line(messages):
print("allow-receipt-deletion line present; permitting receipt deletion.")
return 0
report(deleted, near_miss_lines(messages), base_sha)
return 1
from checks.attestation_guard.commit_messages import commit_messages
from checks.attestation_guard.decide import deleted_receipts
from checks.attestation_guard.deleted_files import deleted_files
from checks.attestation_guard.verdict import verdict


def run(
base_sha: str,
head_sha: str,
*,
deleted_files=git_ops.deleted_files,
commit_messages=git_ops.commit_messages,
deleted_files=deleted_files,
commit_messages=commit_messages,
) -> int:
deleted = deleted_receipts(deleted_files(base_sha, head_sha))
if not deleted:
Expand Down
21 changes: 9 additions & 12 deletions internals/checks/src/checks/attestation_guard/gate_test.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import inspect
from unittest import mock

import pytest

from checks.attestation_guard.gate import run, verdict
from checks.attestation_guard.gate import run


def _run(deleted, *, messages="fix: a thing\n"):
Expand Down Expand Up @@ -80,15 +81,11 @@ def reads_commit_messages_over_the_same_range():
messages.assert_called_once_with("b1", "h1")


def describe_verdict():
def reports_every_deleted_receipt(capsys):
rc = verdict(
["a/e2e-attestations/x.json", "b/e2e-attestations/y.json"], "fix: x", "sha"
def defaults_to_the_git_wrappers_each_in_its_own_module():
defaults = inspect.signature(run).parameters
assert defaults["deleted_files"].default.__module__ == (
"checks.attestation_guard.deleted_files"
)
assert defaults["commit_messages"].default.__module__ == (
"checks.attestation_guard.commit_messages"
)
assert rc == 1
assert capsys.readouterr().out.count("::error file=") == 2

def does_not_report_when_bypassed(capsys):
rc = verdict(["a/e2e-attestations/x.json"], "allow-receipt-deletion: why", "sha")
assert rc == 0
assert "::error file=" not in capsys.readouterr().out
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""The annotation for a bypass line that was attempted but misspelled (#1043)."""

from __future__ import annotations


def near_miss_annotation(line: str) -> str:
"""The annotation naming a bypass line that was attempted but misspelled."""
return (
f"::error::{line!r} is not the bypass line. The exact form is "
"'allow-receipt-deletion: <reason>', reason required."
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from checks.attestation_guard.near_miss_annotation import near_miss_annotation


def describe_near_miss_annotation():
def quotes_the_line_and_gives_the_exact_form():
line = near_miss_annotation("skip-receipt-deletion: y")
assert line == (
"::error::'skip-receipt-deletion: y' is not the bypass line. "
"The exact form is 'allow-receipt-deletion: <reason>', reason required."
)
19 changes: 3 additions & 16 deletions internals/checks/src/checks/attestation_guard/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

from __future__ import annotations

from checks.attestation_guard.deletion_annotation import deletion_annotation
from checks.attestation_guard.near_miss_annotation import near_miss_annotation

_ADVICE = (
"::error::A receipt records that another branch's e2e suite ran, and "
"nothing can regenerate a merged branch's. Restore them and re-attest only "
Expand All @@ -21,22 +24,6 @@ def restore_command(deleted, base_sha: str) -> str:
return f"git checkout {base_sha} -- {' '.join(deleted)}"


def deletion_annotation(path: str) -> str:
"""The per-file annotation naming one wrongly-deleted receipt."""
return (
f"::error file={path}::{path} is an e2e attestation receipt. "
"Receipts are append-only; this PR deletes it."
)


def near_miss_annotation(line: str) -> str:
"""The annotation naming a bypass line that was attempted but misspelled."""
return (
f"::error::{line!r} is not the bypass line. The exact form is "
"'allow-receipt-deletion: <reason>', reason required."
)


def report(deleted, near_misses, base_sha: str) -> None:
"""Print one annotation per deleted receipt, then how to undo them."""
for path in deleted:
Expand Down
24 changes: 1 addition & 23 deletions internals/checks/src/checks/attestation_guard/report_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
from checks.attestation_guard.report import (
deletion_annotation,
near_miss_annotation,
report,
restore_command,
)
from checks.attestation_guard.report import report, restore_command


def describe_restore_command():
Expand All @@ -13,23 +8,6 @@ def names_the_base_sha_and_every_path():
)


def describe_deletion_annotation():
def names_the_file_and_the_append_only_rule():
line = deletion_annotation("packages/ts/e2e-attestations/a.json")
assert line.startswith("::error file=packages/ts/e2e-attestations/a.json::")
assert "packages/ts/e2e-attestations/a.json is an e2e attestation receipt" in line
assert "Receipts are append-only; this PR deletes it." in line


def describe_near_miss_annotation():
def quotes_the_line_and_gives_the_exact_form():
line = near_miss_annotation("skip-receipt-deletion: y")
assert line == (
"::error::'skip-receipt-deletion: y' is not the bypass line. "
"The exact form is 'allow-receipt-deletion: <reason>', reason required."
)


def describe_report():
def annotates_every_deleted_receipt_with_its_own_file(capsys):
report(["packages/ts/e2e-attestations/a.json"], [], "abc123")
Expand Down
20 changes: 20 additions & 0 deletions internals/checks/src/checks/attestation_guard/verdict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"""The attestation-guard verdict once a receipt deletion is known (#1043).

Split from the orchestration so the bypass decision reads on its own: the
deletion is already established here, and all that remains is whether a
well-formed bypass line excuses it.
"""

from __future__ import annotations

from checks.attestation_guard.decide import has_allow_line, near_miss_lines
from checks.attestation_guard.report import report


def verdict(deleted, messages: str, base_sha: str) -> int:
"""0 when a well-formed bypass line is present, else 1 with diagnostics."""
if has_allow_line(messages):
print("allow-receipt-deletion line present; permitting receipt deletion.")
return 0
report(deleted, near_miss_lines(messages), base_sha)
return 1
35 changes: 35 additions & 0 deletions internals/checks/src/checks/attestation_guard/verdict_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from checks.attestation_guard.verdict import verdict


def describe_verdict():
def reports_every_deleted_receipt(capsys):
rc = verdict(
["a/e2e-attestations/x.json", "b/e2e-attestations/y.json"], "fix: x", "sha"
)
assert rc == 1
assert capsys.readouterr().out.count("::error file=") == 2

def names_the_restore_command_with_the_base_sha(capsys):
assert verdict(["a/e2e-attestations/x.json"], "fix: x", "abc123") == 1
out = capsys.readouterr().out
assert "git checkout abc123 -- a/e2e-attestations/x.json" in out

def passes_and_says_so_when_a_bypass_line_is_present(capsys):
rc = verdict(["a/e2e-attestations/x.json"], "allow-receipt-deletion: why", "sha")
assert rc == 0
assert "permitting receipt deletion" in capsys.readouterr().out

def does_not_report_when_bypassed(capsys):
rc = verdict(["a/e2e-attestations/x.json"], "allow-receipt-deletion: why", "sha")
assert rc == 0
assert "::error file=" not in capsys.readouterr().out

def names_a_near_miss_bypass_line(capsys):
rc = verdict(["a/e2e-attestations/x.json"], "skip-receipt-deletion: y", "sha")
assert rc == 1
out = capsys.readouterr().out
assert "'skip-receipt-deletion: y' is not the bypass line" in out

def reports_no_near_miss_when_the_messages_hold_none(capsys):
assert verdict(["a/e2e-attestations/x.json"], "fix: x", "sha") == 1
assert "is not the bypass line" not in capsys.readouterr().out
15 changes: 15 additions & 0 deletions internals/checks/src/checks/platforms_mirror/as_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
"""A comment-free object literal as JSON.

TypeScript's bare keys and trailing commas are the only two things left between
a stripped `PLATFORMS` array and something `json` will decode.
"""

from __future__ import annotations

import re


def as_json(text: str) -> str:
"""`text` with bare object keys quoted and trailing commas dropped."""
keyed = re.sub(r"([{,]\s*)([A-Za-z_$][\w$]*)\s*:", r'\1"\2":', text)
return re.sub(r",(\s*[}\]])", r"\1", keyed)
28 changes: 28 additions & 0 deletions internals/checks/src/checks/platforms_mirror/as_json_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""Colocated unit tests for the JSON normalizer (isolation -- pure text in,
text out).
"""

from checks.platforms_mirror.as_json import as_json


def describe_as_json():
def it_quotes_a_bare_object_key():
assert as_json('{nodePlatform: "linux"}') == '{"nodePlatform": "linux"}'

def it_quotes_every_key_after_a_comma():
assert as_json('{a: 1, b: 2}') == '{"a": 1, "b": 2}'

def it_quotes_a_key_holding_a_dollar_sign_or_underscore():
assert as_json("{_a$b: 1}") == '{"_a$b": 1}'

def it_drops_a_trailing_comma_before_a_brace():
assert as_json('{"a": 1,}') == '{"a": 1}'

def it_drops_a_trailing_comma_before_a_bracket():
assert as_json('["a",]') == '["a"]'

def it_keeps_the_whitespace_that_followed_a_dropped_comma():
assert as_json('{"a": 1,\n}') == '{"a": 1\n}'

def it_leaves_an_already_quoted_key_alone():
assert as_json('{"a": 1}') == '{"a": 1}'
6 changes: 1 addition & 5 deletions internals/checks/src/checks/platforms_mirror/gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,10 @@
from .parse import ParseError
from .problems import problems
from .python_table import python_table
from .read import read
from .typescript_table import typescript_table


def read(path: str) -> str:
with open(path, encoding="utf-8") as handle:
return handle.read()


def run(
python_path: str,
typescript_path: str,
Expand Down
Loading