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: