From d5470988b26909a22ebd7b3d35607c14bc5726c8 Mon Sep 17 00:00:00 2001 From: Parth Shethia <166938062+ParthShethia25@users.noreply.github.com> Date: Mon, 14 Sep 2026 16:33:29 +0530 Subject: [PATCH] fix(ng-dev/pr): require enforced statuses to be passing, not just present `assertEnforcedStatuses` matched each required status by name and type only, so a required check that was skipped, cancelled or failing satisfied the validation as long as an entry with the configured name existed on the pull request. The information needed to catch this was already available and discarded: `getStatusesForPullRequest` normalizes `SKIPPED`, `CANCELLED`, `TIMED_OUT` and `FAILURE` to `PullRequestStatus.FAILING`. `assertPassingCi` does not cover the gap either, because GitHub reports `statusCheckRollup.state` as `SUCCESS` when checks are skipped, so a skipped required check currently passes both validations. Check the normalized status of each matched entry and report required statuses that are present but not passing. --- .../validation/assert-enforced-statuses.ts | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/ng-dev/pr/common/validation/assert-enforced-statuses.ts b/ng-dev/pr/common/validation/assert-enforced-statuses.ts index 2d97387ea1..e3dc854ed6 100644 --- a/ng-dev/pr/common/validation/assert-enforced-statuses.ts +++ b/ng-dev/pr/common/validation/assert-enforced-statuses.ts @@ -7,7 +7,11 @@ */ import {PullRequestConfig} from '../../config/index.js'; -import {getStatusesForPullRequest, PullRequestFromGithub} from '../fetch-pull-request.js'; +import { + getStatusesForPullRequest, + PullRequestFromGithub, + PullRequestStatus, +} from '../fetch-pull-request.js'; import {createPullRequestValidation, PullRequestValidation} from './validation-config.js'; /** Assert the pull request has passing enforced statuses. */ @@ -25,10 +29,15 @@ class Validation extends PullRequestValidation { const {statuses} = getStatusesForPullRequest(pullRequest); const missing: string[] = []; + const notPassing: string[] = []; for (const enforced of config.requiredStatuses) { - if (!statuses.some((s) => s.name === enforced.name && s.type === enforced.type)) { + const status = statuses.find((s) => s.name === enforced.name && s.type === enforced.type); + + if (status === undefined) { missing.push(enforced.name); + } else if (status.status !== PullRequestStatus.PASSING) { + notPassing.push(enforced.name); } } @@ -37,5 +46,11 @@ class Validation extends PullRequestValidation { `Required statuses are missing on the pull request (${missing.join(', ')}).`, ); } + + if (notPassing.length > 0) { + throw this._createError( + `Required statuses are not passing on the pull request (${notPassing.join(', ')}).`, + ); + } } }