diff --git a/.github/scripts/check_approval_drift.py b/.github/scripts/check_approval_drift.py
index 7202eb9eac..739aba06c5 100644
--- a/.github/scripts/check_approval_drift.py
+++ b/.github/scripts/check_approval_drift.py
@@ -123,12 +123,15 @@ def audit_pr(
if not reviewed_head:
latest = approvals[-1]
reviewer = (latest.get("user") or {}).get("login", "?")
- approved_on = _short(latest.get("commit_id"))
+ approved_sha = latest.get("commit_id")
+ approved_on = _short(approved_sha)
+ merged_head = _short(head_sha)
+ diff_link = _compare_link(repo, approved_sha, head_sha, merged_head)
return (
"changed-after-approval",
(
f"last approval by @{reviewer} was on {approved_on}, but merged "
- f"head was {_short(head_sha)} — commits landed after review"
+ f"head was {diff_link} — commits landed after review"
),
)
@@ -139,6 +142,19 @@ def _short(sha: object) -> str:
return str(sha)[:9] if sha else "?"
+def _compare_link(
+ repo: str, base: object, head: object, label: str
+) -> str:
+ """Markdown link to the GitHub compare page between *base* and *head*.
+
+ Falls back to plain text if either SHA is missing so the report never
+ breaks on a sparse API response.
+ """
+ if not base or not head:
+ return label
+ return f"[{label}](https://github.com/{repo}/compare/{base}...{head})"
+
+
def main() -> int:
token = os.environ.get("GITHUB_TOKEN") or os.environ.get("GH_TOKEN")
repo = resolve_repo()
diff --git a/.github/scripts/check_dependency_diff.py b/.github/scripts/check_dependency_diff.py
index b61c271538..e049aeb269 100644
--- a/.github/scripts/check_dependency_diff.py
+++ b/.github/scripts/check_dependency_diff.py
@@ -138,11 +138,27 @@ def main() -> int:
if before[n]["version"] != after[n]["version"]
}
+ # First-party openhands-* packages are version-bumped on every release;
+ # exclude them from the external-dep count but still surface them below.
+ def _is_openhands(name: str) -> bool:
+ return name.lower().startswith("openhands-")
+
+ bumped_external = {
+ n: v for n, v in bumped.items() if not _is_openhands(n)
+ }
+ bumped_openhands = {
+ n: v for n, v in bumped.items() if _is_openhands(n)
+ }
+
report.add(f"Baseline: `{baseline}`")
report.add(
- f"Added: **{len(added)}**, bumped: **{len(bumped)}**, "
+ f"Added: **{len(added)}**, bumped: **{len(bumped_external)}**, "
f"removed: **{len(removed)}**."
)
+ if bumped_openhands:
+ report.add(
+ f"_(plus {len(bumped_openhands)} internal `openhands-*` bump(s))_"
+ )
report.add("")
# --- non-registry sources on new/changed packages (supply-chain surface) --
@@ -199,11 +215,17 @@ def main() -> int:
for name in sorted(added):
report.add(f"- `{name}=={added[name]['version']}`")
report.add("\n")
- if bumped:
+ if bumped_external:
report.add("Bumped dependencies
\n")
- for name in sorted(bumped):
- old, new = bumped[name]
- report.add(f"- `{name}`: {old} → {new}")
+ for name in sorted(bumped_external):
+ old_v, new_v = bumped_external[name]
+ report.add(f"- `{name}`: {old_v} → {new_v}")
+ report.add("\n ")
+ if bumped_openhands:
+ report.add("Internal `openhands-*` bumps
\n")
+ for name in sorted(bumped_openhands):
+ old_v, new_v = bumped_openhands[name]
+ report.add(f"- `{name}`: {old_v} → {new_v}")
report.add("\n ")
sys.stdout.write(report.render())
diff --git a/.github/scripts/security_scan_common.py b/.github/scripts/security_scan_common.py
index 2238863e00..fac274966a 100644
--- a/.github/scripts/security_scan_common.py
+++ b/.github/scripts/security_scan_common.py
@@ -149,7 +149,7 @@ def warn(self, reason: str) -> None:
def render(self) -> str:
if self.blocking:
- status = f"❌ {len(self.blocking)} blocking finding(s)"
+ status = f"❌ {len(self.blocking)} finding(s)"
elif self.warnings:
status = f"⚠️ {len(self.warnings)} warning(s), nothing blocking"
else: