Compare commits

...

1 Commits

Author SHA1 Message Date
Robert Resch 576d4dd7c9 Enhance requirements check to embed commit SHA as a clickable link in comments 2026-06-15 14:29:26 +00:00
5 changed files with 31 additions and 33 deletions
+5 -4
View File
@@ -1,4 +1,4 @@
# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"e2211304306ff1e9b9a5b6fd1dd16eb989688e2456f8320340108d7aa5520a5b","body_hash":"0665c72fe4b0a14b3a0b396dc293ce78235771fe15ebc894662fece33b189135","compiler_version":"v0.79.6","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
# gh-aw-metadata: {"schema_version":"v4","frontmatter_hash":"7b142e96e0f8b454cdcc9c0c25070cf9a52c44d83a6b1fbc3ad6725b6567337c","body_hash":"3894ded07d5934ac5f29d160ffb1f9115cf72b6da8a7e453a4d4f69e8641a48e","compiler_version":"v0.79.6","strict":true,"agent_id":"copilot","engine_versions":{"copilot":"1.0.60"}}
# gh-aw-manifest: {"version":1,"secrets":["COPILOT_GITHUB_TOKEN","GH_AW_GITHUB_MCP_SERVER_TOKEN","GH_AW_GITHUB_TOKEN","GITHUB_TOKEN"],"actions":[{"repo":"actions/checkout","sha":"df4cb1c069e1874edd31b4311f1884172cec0e10","version":"v6.0.3"},{"repo":"actions/download-artifact","sha":"3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c","version":"v8.0.1"},{"repo":"actions/github-script","sha":"3a2844b7e9c422d3c10d287c895573f7108da1b3","version":"v9.0.0"},{"repo":"actions/setup-node","sha":"48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e","version":"v6.4.0"},{"repo":"actions/upload-artifact","sha":"043fb46d1a93c77aae656e7c1c64a875d1fc6a0a","version":"v7.0.1"},{"repo":"github/gh-aw-actions/setup","sha":"v0.79.6","version":"v0.79.6"}],"containers":[{"image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2","digest":"sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6","pinned_image":"ghcr.io/github/gh-aw-firewall/agent:0.27.2@sha256:f88e5b17b6b7a600117bc121114d6ce2155c88c983c0c939c5df884f730fa1d6"},{"image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2","digest":"sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4","pinned_image":"ghcr.io/github/gh-aw-firewall/api-proxy:0.27.2@sha256:ee39841d980878ebbb87592903b06d31a1af500c71525c9616f7e8e2a27041a4"},{"image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2","digest":"sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591","pinned_image":"ghcr.io/github/gh-aw-firewall/squid:0.27.2@sha256:2e3a717e5f19a654cd9a2263beb52012b56bcb68562ec5ae2e42f9d156b49591"},{"image":"ghcr.io/github/gh-aw-mcpg:v0.3.25","digest":"sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa","pinned_image":"ghcr.io/github/gh-aw-mcpg:v0.3.25@sha256:c10331ad17668ef89f38f5e356678788a40b0cd5fef96e8f92e1d9c1de47cbaa"},{"image":"ghcr.io/github/github-mcp-server:v1.1.2","digest":"sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c","pinned_image":"ghcr.io/github/github-mcp-server:v1.1.2@sha256:30197479d8036c7811892bc07e06f9a05c9ef3cdd79bc59f256d50647f95788c"}]}
# ___ _ _
# / _ \ | | (_)
@@ -1500,11 +1500,12 @@ jobs:
echo "Artifact has no head_sha; running the agent."
exit 0
fi
# Recover the commit recorded in the most recent requirements-check comment.
# Recover the commit recorded in the most recent requirements-check
# comment from the "Checked at commit" link
PRIOR=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--jq '.[] | select(.body | contains("<!-- requirements-check -->")) | .body' \
| grep -oE '<!-- requirements-check-sha: [0-9a-f]{7,40} -->' \
| grep -oE '[0-9a-f]{7,40}' | tail -1 || true)
| grep -oiE '/commit/[0-9a-f]{40}' \
| grep -oiE '[0-9a-f]{40}' | tail -1 || true)
if [ -z "${PRIOR}" ]; then
echo "No previous comment with a recorded commit; running the agent."
exit 0
+6 -7
View File
@@ -51,11 +51,12 @@ jobs:
echo "Artifact has no head_sha; running the agent."
exit 0
fi
# Recover the commit recorded in the most recent requirements-check comment.
# Recover the commit recorded in the most recent requirements-check
# comment from the "Checked at commit" link
PRIOR=$(gh api --paginate "repos/${GITHUB_REPOSITORY}/issues/${PR}/comments" \
--jq '.[] | select(.body | contains("<!-- requirements-check -->")) | .body' \
| grep -oE '<!-- requirements-check-sha: [0-9a-f]{7,40} -->' \
| grep -oE '[0-9a-f]{7,40}' | tail -1 || true)
| grep -oiE '/commit/[0-9a-f]{40}' \
| grep -oiE '[0-9a-f]{40}' | tail -1 || true)
if [ -z "${PRIOR}" ]; then
echo "No previous comment with a recorded commit; running the agent."
exit 0
@@ -188,10 +189,8 @@ Then stop. Do not improvise a verdict.
Replace every placeholder with the resolved value and emit
`rendered_comment` via `add_comment`. Preserve the leading
`<!-- requirements-check -->` marker and the
`<!-- requirements-check-sha: … -->` marker that follows it — the next
run reads the recorded commit from it to decide whether anything changed.
The PR target is already wired; do not pass `item_number`.
`<!-- requirements-check -->` marker. The PR target is already wired;
do not pass `item_number`.
## Check instructions
+5 -9
View File
@@ -12,11 +12,8 @@ agent will refuse to resolve the new kind.
from .models import CheckKind, CheckRunResult, CheckStatus, PackageChange
MARKER = "<!-- requirements-check -->"
# Hidden marker carrying the PR head commit the checks ran against. The agentic
# stage's gate job parses it from the previous comment to decide whether any
# tracked requirement file changed since then; if not, the agent is skipped.
SHA_MARKER_PREFIX = "<!-- requirements-check-sha:"
HEADER = "## Check requirements"
REPO_URL = "https://github.com/home-assistant/core"
# Column / bullet labels per check kind, in display order.
_CHECK_DISPLAY: tuple[tuple[CheckKind, str], ...] = (
@@ -116,13 +113,12 @@ def _details_block(pkg: PackageChange) -> str:
def _intro(result: CheckRunResult) -> str:
"""Marker(s), header, and the optional visible commit line."""
markers = MARKER
"""Marker, header, and the optional commit line the gate reads back."""
parts: list[str] = []
if result.head_sha:
markers = f"{MARKER}\n{SHA_MARKER_PREFIX} {result.head_sha} -->"
parts.append(f"Checked at commit `{result.head_sha[:7]}`.")
return "\n\n".join([f"{markers}\n{HEADER}", *parts])
commit = f"[`{result.head_sha[:7]}`]({REPO_URL}/commit/{result.head_sha})"
parts.append(f"Checked at commit {commit}.")
return "\n\n".join([f"{MARKER}\n{HEADER}", *parts])
def render_comment(result: CheckRunResult) -> str:
@@ -46,12 +46,13 @@ def test_main_writes_artifact(
),
)
sha = "abc1234def5678abc1234def5678abc1234def56"
exit_code = main_mod.main(
[
"--pr-number",
"42",
"--head-sha",
"abc1234def5678",
sha,
"--diff",
str(diff_file),
"--output",
@@ -62,11 +63,11 @@ def test_main_writes_artifact(
payload = json.loads(output_file.read_text(encoding="utf-8"))
assert payload["pr_number"] == 42
assert payload["head_sha"] == "abc1234def5678"
assert payload["head_sha"] == sha
assert payload["packages"][0]["name"] == "pkg"
assert (
"<!-- requirements-check-sha: abc1234def5678 -->"
in (payload["rendered_comment"])
f"https://github.com/home-assistant/core/commit/{sha}"
in payload["rendered_comment"]
)
captured = capsys.readouterr()
@@ -74,8 +74,8 @@ def test_render_empty_change_set() -> None:
assert "No tracked requirement changes detected" in rendered
def test_render_embeds_head_sha_marker_and_visible_line() -> None:
"""A head SHA produces the hidden marker (for the gate) and a visible line."""
def test_render_embeds_head_sha_as_commit_link() -> None:
"""A head SHA renders a commit link whose URL carries the full SHA."""
pkg = PackageChange(
name="pkg",
old_version="1.0.0",
@@ -83,18 +83,19 @@ def test_render_embeds_head_sha_marker_and_visible_line() -> None:
repo_url="https://github.com/x/pkg",
checks={CheckKind.CI_UPLOAD: _pass("ok")},
)
sha = "abc1234def5678"
sha = "abc1234def5678abc1234def5678abc1234def56"
rendered = render_comment(CheckRunResult(pr_number=1, head_sha=sha, packages=[pkg]))
assert f"<!-- requirements-check-sha: {sha} -->" in rendered
assert "Checked at commit `abc1234`." in rendered
# The visible marker must still lead so add_comment dedup keeps working.
# Short SHA shown to humans, full SHA recoverable from the link URL.
assert (
f"Checked at commit [`abc1234`]"
f"(https://github.com/home-assistant/core/commit/{sha})."
) in rendered
assert rendered.startswith("<!-- requirements-check -->\n")
def test_render_without_head_sha_omits_marker() -> None:
"""With no head SHA, neither the hidden marker nor the visible line appears."""
def test_render_without_head_sha_omits_commit_line() -> None:
"""With no head SHA, the commit line is absent entirely."""
rendered = render_comment(CheckRunResult(pr_number=1))
assert "requirements-check-sha" not in rendered
assert "Checked at commit" not in rendered