Skip to content

ci(e2e): reconcile ambiguous workflow-dispatch failures without duplicate runs #7593

Description

@apurvvkumaria

Parent epic: #7140

Related but distinct work:

Problem

The PR E2E controller treats every failed workflow_dispatch response as proof that no child run exists. That is not sufficient for network errors, HTTP 5xx responses, and malformed success responses because the POST may have been accepted even though the controller did not receive valid run details.

In gate run 30210723677, the POST returned HTTP 500:

Failed to run workflow dispatch

The coordination check was completed as Run could not start, all evidence steps were skipped, and no E2E child was ultimately visible. This false red blocked #7589 even though ordinary CI had passed.

GitHub documents a successful dispatch with return_run_details as HTTP 200 containing the run ID and URLs. GitHub does not document conditional or idempotent requests for this unsafe POST, so blindly repeating it can create duplicate workflow runs.

Required behavior

Model dispatch as three outcomes:

  1. Accepted with authenticated run details.
  2. Definitively rejected.
  3. Acceptance unknown.

For an unknown outcome:

  • Do not immediately send a second POST.
  • Poll a bounded workflow-run inventory using the already-generated UUID correlation.
  • Require the exact workflow path, run title, main workflow SHA, branch, event, first attempt, creation window, and canonical run URL.
  • Revalidate the exact PR head/base and controller check before adopting a run.
  • If exactly one matching child appears, adopt its run ID and continue the normal state/check publication path.
  • If no child appears, terminalize the old check with a versioned dispatch-not-observed recovery receipt.
  • Permit later same-diff recovery only through a fresh controller check ID and fresh correlation after the old check is terminal and its correlation has been rechecked.
  • If multiple or malformed matches appear, fail closed as reconciliation-required and never authorize any candidate.
  • Preserve the child workflow's exact check-ID/run-URL authentication boundary.

Record bounded diagnostics including HTTP status, GitHub request ID when available, correlation ID, and reconciliation result. Do not log tokens or dispatch input values.

Acceptance criteria

  • A normal HTTP 200 response follows the existing path without polling.
  • A definitive 4xx rejection performs no reconciliation POST retry.
  • HTTP 500, network-response loss, timeout, and malformed accepted responses enter read-only reconciliation.
  • A delayed single exact match is adopted, publishes one exact child URL, and sends only one POST.
  • Zero matches produce a retryable, immutable receipt rather than generic Run could not start.
  • Same-diff recovery creates a fresh check/correlation only after the prior check is terminal and the old correlation is rechecked.
  • A late original child cannot authenticate against the terminal old check.
  • Multiple matches, stale matches, wrong workflow/SHA/title/attempt, changed PR head/base, or failed inventory reads fail closed.
  • Automatic, protected internal, and fork-approval paths preserve their existing authorization rules.
  • The hosted-runner-loss retry budget and ci(e2e): reconcile successful same-diff reruns with immutable PR gate checks #7206 failed-job-rerun lineage are unchanged.
  • Tests prove accepted-but-response-lost, delayed visibility, no-child, multiple-child, malformed-success, late-child, and changed-identity cases.
  • Operator documentation explains the distinction between dispatch transport failure and runner loss.

Likely implementation area

  • tools/e2e/pr-e2e-gate.mts
  • A focused dispatch-reconciliation module and tests
  • test/pr-e2e-gate-lifecycle.test.ts
  • test/pr-e2e-gate-retry-history.test.ts
  • test/e2e/README.md

No semantic change to .github/workflows/e2e.yaml should be necessary; its exact run-URL authentication remains the security boundary.

Metadata

Metadata

Assignees

Labels

area: ciCI workflows, checks, release automation, or GitHub Actionsarea: e2eEnd-to-end tests, nightly failures, or validation infrastructure

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions