From 6728bd424508f349b6a145ec84b4abdb3ea405da Mon Sep 17 00:00:00 2001 From: Myasnikov Daniil Date: Wed, 29 Jul 2026 18:35:14 +0500 Subject: [PATCH] fix(ci): don't clobber a fork PR's green "E2E Tests" on a label event MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same defect as the e2e-report fix, on the fork path. main's `labeled` pull_request trigger produces a "Pull Request" run whose `plan` guard discards every label but full-e2e, so every job skips and nothing is built. workflow_run still fires for it, and `resolve` then reddened the required status down either branch: a non-success conclusion fails closed, and a `success` conclusion falls through to the missing-pr-patch check, which also fails closed. Labelling an already-green open fork PR therefore turned its E2E Tests red until the next push. Detect that shape directly — the triggering run's `Plan build` job concluded `skipped` — and return without posting anything. Statuses are per-SHA and an unposted required status stays "Expected", which blocks the merge, so declining to post can only preserve a verdict some real run reached, never invent one. A fork that edits the workflow to force this path leaves its head SHA with no status at all, i.e. not mergeable. The job already holds the actions:read scope the job lookup needs. Signed-off-by: Myasnikov Daniil --- .github/workflows/e2e-fork.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/e2e-fork.yaml b/.github/workflows/e2e-fork.yaml index 56d633bb6..ab082aa98 100644 --- a/.github/workflows/e2e-fork.yaml +++ b/.github/workflows/e2e-fork.yaml @@ -108,6 +108,27 @@ jobs: core.setOutput('should_run', 'false'); }; + // Discarded label event: pull-requests.yaml triggers on `labeled` but + // its `plan` guard discards every label other than full-e2e, so such a + // run skips every job and builds nothing. Post NOTHING and stop — + // deciding here would overwrite an already-green status with red (via + // the CONCLUSION check or the missing-pr-patch check below) every time + // anyone labels an open fork PR. Fail-closed: statuses are per-SHA and + // an unposted required status stays "Expected", which blocks the merge, + // so declining to post can only ever preserve a verdict a real run + // reached — never invent one. A fork editing the workflow to force this + // path just leaves its head SHA with no status, i.e. not mergeable. + const jobs = await github.paginate( + github.rest.actions.listJobsForWorkflowRun, + { owner, repo, run_id: RUN_ID, per_page: 100 }, + ); + const plan = jobs.find(j => j.name === 'Plan build'); + if (plan && plan.conclusion === 'skipped') { + console.log(`Triggering run ${RUN_ID} skipped 'Plan build' (discarded label event) — leaving "E2E Tests" untouched.`); + core.setOutput('should_run', 'false'); + return; + } + // Fork build did not succeed → fail the required status (fail-closed). if (CONCLUSION !== 'success') { await decide('failure', `Pull Request workflow concluded '${CONCLUSION}'; e2e not run`);