···133133 pull_number
134134 })).data
135135136136- const approvals = new Set(
137137- (await github.paginate(github.rest.pulls.listReviews, {
136136+ const reviews = await github.paginate(github.rest.pulls.listReviews, {
138137 ...context.repo,
139138 pull_number
140140- }))
139139+ })
140140+141141+ const approvals = new Set(
142142+ reviews
141143 .filter(review => review.state == 'APPROVED')
142144 .map(review => review.user?.id)
143145 )
···169171 [ 'NONE', 'FIRST_TIMER', 'FIRST_TIME_CONTRIBUTOR' ].includes(pull_request.author_association),
170172 }
171173172172- const run_id = (await github.rest.actions.listWorkflowRuns({
174174+ const { id: run_id, conclusion } = (await github.rest.actions.listWorkflowRuns({
173175 ...context.repo,
174176 workflow_id: 'pr.yml',
175177 event: 'pull_request_target',
176178 exclude_pull_requests: true,
177179 head_sha: pull_request.head.sha
178178- })).data.workflow_runs[0]?.id ??
180180+ })).data.workflow_runs[0] ??
179181 // TODO: Remove this after 2025-09-17, at which point all eval.yml artifacts will have expired.
180182 (await github.rest.actions.listWorkflowRuns({
181183 ...context.repo,
···185187 status: 'success',
186188 exclude_pull_requests: true,
187189 head_sha: pull_request.head.sha
188188- })).data.workflow_runs[0]?.id
190190+ })).data.workflow_runs[0] ?? {}
189191190192 // Newer PRs might not have run Eval to completion, yet.
191193 // Older PRs might not have an eval.yml workflow, yet.
192194 // In either case we continue without fetching an artifact on a best-effort basis.
193195 log('Last eval run', run_id ?? '<n/a>')
196196+197197+ if (conclusion === 'success') {
198198+ Object.assign(prLabels, {
199199+ // We only set this label if the latest eval run was successful, because if it was not, it
200200+ // *could* have requested reviewers. We will let the PR author fix CI first, before "escalating"
201201+ // this PR to "needs: reviewer".
202202+ // Since the first Eval run on a PR always sets rebuild labels, the same PR will be "recently
203203+ // updated" for the next scheduled run. Thus, this label will still be set within a few minutes
204204+ // after a PR is created, if required.
205205+ // Note that a "requested reviewer" disappears once they have given a review, so we check
206206+ // existing reviews, too.
207207+ '9.needs: reviewer':
208208+ !pull_request.draft &&
209209+ pull_request.requested_reviewers.length == 0 &&
210210+ reviews.length == 0,
211211+ })
212212+ }
194213195214 const artifact = run_id && (await github.rest.actions.listWorkflowRunArtifacts({
196215 ...context.repo,