fix(ci): resolve fork PRs in the E2E evidence publisher
The publisher read the PR number from the CI run's pull_requests payload. GitHub keeps that payload empty for fork runs, so the job printed 'No pull request is associated' and stopped on every fork PR. Resolve the PR from the run's head owner, branch, and SHA instead. The SHA match skips runs that a newer push superseded. A fork PR also has no CI review comment, because the live poller skips forks. The publisher now logs this and exits clean instead of raising; the evidence stays in the workflow artifact.
This commit is contained in:
@@ -44,12 +44,21 @@ jobs:
|
||||
GH_SESSION_TOKEN: ${{ secrets.GH_IMAGE_SESSION_TOKEN }}
|
||||
SOURCE_REPO: ${{ github.repository }}
|
||||
SOURCE_RUN_ID: ${{ github.event.workflow_run.id }}
|
||||
HEAD_OWNER: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
HEAD_BRANCH: ${{ github.event.workflow_run.head_branch }}
|
||||
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
PR_NUMBER=$(gh api "repos/$SOURCE_REPO/actions/runs/$SOURCE_RUN_ID" --jq '.pull_requests[0].number // empty')
|
||||
# The run's own ``pull_requests`` payload is always empty for a
|
||||
# fork PR, so resolve the PR from its head reference instead.
|
||||
# The head-SHA match skips runs that a newer push superseded.
|
||||
PR_NUMBER=$(gh api -X GET "repos/$SOURCE_REPO/pulls" \
|
||||
-f head="$HEAD_OWNER:$HEAD_BRANCH" -f state=open \
|
||||
--jq '.[] | select(.head.sha == $ENV.HEAD_SHA) | .number' \
|
||||
| head -n1)
|
||||
if [ -z "$PR_NUMBER" ]; then
|
||||
echo "No pull request is associated with CI run $SOURCE_RUN_ID."
|
||||
echo "No open pull request has head $HEAD_OWNER:$HEAD_BRANCH at $HEAD_SHA (CI run $SOURCE_RUN_ID)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ def _find_review_comment(comments: object) -> dict[str, Any] | None:
|
||||
return None
|
||||
|
||||
|
||||
def _wait_for_review_comment(token: str, source_repo: str, pr_number: str) -> dict[str, Any]:
|
||||
def _wait_for_review_comment(token: str, source_repo: str, pr_number: str) -> dict[str, Any] | None:
|
||||
"""Wait briefly for GitHub's comment API to expose the completed marker."""
|
||||
request = urllib.request.Request(
|
||||
f"{API_BASE}/repos/{source_repo}/issues/{pr_number}/comments?per_page=100",
|
||||
@@ -221,7 +221,7 @@ def _wait_for_review_comment(token: str, source_repo: str, pr_number: str) -> di
|
||||
return comment
|
||||
if attempt + 1 < COMMENT_LOOKUP_ATTEMPTS:
|
||||
time.sleep(COMMENT_LOOKUP_DELAY_SECONDS)
|
||||
raise ValueError("CI review comment with E2E evidence marker is missing")
|
||||
return None
|
||||
|
||||
|
||||
def upload_evidence(
|
||||
@@ -280,6 +280,15 @@ def publish(
|
||||
print("No inline E2E evidence to publish.")
|
||||
return False
|
||||
comment = _wait_for_review_comment(token, source_repo, pr_number)
|
||||
if comment is None:
|
||||
# A fork PR gets no CI review comment (the live poller needs a
|
||||
# write token there), so there is no marker to patch. The
|
||||
# evidence stays available in the workflow artifact.
|
||||
print(
|
||||
f"PR #{pr_number} has no CI review comment with an E2E evidence "
|
||||
"marker; the evidence stays in the workflow artifact."
|
||||
)
|
||||
return False
|
||||
try:
|
||||
attachment_urls = upload_evidence(
|
||||
files, evidence_dir, source_repo, session_token
|
||||
|
||||
@@ -179,6 +179,32 @@ def test_publish_marks_evidence_upload_failure_in_pr_comment(tmp_path, monkeypat
|
||||
]
|
||||
|
||||
|
||||
def test_publish_skips_when_no_review_comment_exists(tmp_path, monkeypatch, capsys):
|
||||
monkeypatch.setattr(
|
||||
_mod,
|
||||
"load_evidence",
|
||||
lambda evidence_dir: (
|
||||
[_mod.EvidenceFile("shot.png", "new screenshot: shot.png")],
|
||||
{},
|
||||
),
|
||||
)
|
||||
monkeypatch.setattr(_mod, "_wait_for_review_comment", lambda *args: None)
|
||||
monkeypatch.setattr(
|
||||
_mod,
|
||||
"upload_evidence",
|
||||
lambda *args: (_ for _ in ()).throw(AssertionError("must not upload")),
|
||||
)
|
||||
|
||||
assert _mod.publish(
|
||||
"github-token",
|
||||
"NousResearch/hermes-agent",
|
||||
tmp_path,
|
||||
"83202",
|
||||
"image-token",
|
||||
) is False
|
||||
assert "no CI review comment" in capsys.readouterr().out
|
||||
|
||||
|
||||
def test_find_review_comment_requires_the_evidence_marker():
|
||||
pending = "<!-- hermes-ci-review-bot -->\n<!-- hermes-e2e-evidence:start -->\npending\n<!-- hermes-e2e-evidence:end -->"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user