Add workflow to label PRs awaiting workflow approval#8383
Conversation
Adds a scheduled workflow (every 15 minutes) and supporting composite
action that reconciles a 'needs-approval' label on open PRs based on
whether they have workflow runs in the 'action_required' state.
This makes it easy to discover and filter PRs that require a maintainer
with write access to approve workflow execution (typically PRs from
first-time contributors or forks), via:
is:pr is:open label:needs-approval
The reconciliation is idempotent: the label is added when a PR has any
action_required run and removed once those runs are approved (or the
PR is closed).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The previous implementation looked up PRs for each action_required
workflow run via 'repos/{repo}/commits/{sha}/pulls', which returns
any open PR whose branch contains that commit - including PRs whose
older commits had action_required runs that were never approved but
whose newer commits have since been approved.
Result: PRs were falsely flagged as 'needs-approval' for stale runs
on superseded commits. Dry-run against microsoft/BCApps reported 5
PRs of which 3 (#7410, #7843, #8313) had zero action_required runs
on their current head.
Fix: build a {head_sha -> PR number} map from the open PRs API and
only flag a PR when an action_required run matches its *current*
head SHA. This is also simpler (no per-run API call) and correctly
handles fork PRs (head_sha is identical to the PR's head commit
SHA for both pull_request and pull_request_target events).
After fix, dry-run flags exactly the 5 PRs that truly have unrun
workflows on their current head.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fixed false positives in head SHA matching (86399b2). Issue found during review: The original logic used Example false positive (PR #7410): Had no Fix: Build a Verified: Dry-run against |
- Separate stderr capture in Invoke-GhApi to prevent warnings/notices from corrupting JSON output (review #1) - Add --paginate to all gh api calls and switch to NDJSON jq filters (one value per line) so multi-page responses parse correctly. Note: --slurp cannot be combined with --jq so we cannot use that pattern (review #2, #3) - Add timeout-minutes: 10 to the SyncLabel job (review #4) - Pass action inputs (label, whatIf) via environment variables instead of direct GitHub Actions expression interpolation into the pwsh run block, eliminating the script-injection vector (review #5) Not addressed: - review #6 claimed actions/checkout v6.0.2 does not exist; verified via GitHub API that this SHA is tagged v6.0.2, matching the convention used by every other workflow in this repo. Kept as-is for consistency. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Ensure-Label now distinguishes 404 (label missing) from other errors (rate limit / 5xx / network); only the former triggers label creation. Other errors propagate instead of being masked as missing-label. - Map head SHA -> list of PR numbers (instead of a single number) so that if two open PRs share a head commit (e.g. same commit pushed to two branches with PRs to different bases), both get labelled when the workflow runs against that SHA are action_required. Not addressed: - "Workflow runs query lacks --paginate": false positive; --paginate is already present on line 94 since the previous commit (59afae0). - "Checkout pinned to non-existent v6.0.2": duplicate of iteration-1 review #6; already verified via API that the SHA is correctly tagged v6.0.2 and matches the convention used throughout this repo. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Looks like a workaround to an annoying issue. @mazhelez, @aholstrup1, is this something we would want, or should we look at the underlying annoyance? |
This has been discussed before. We have very few people (MS internal) that has write access to the REPO. So are allowed to run the build. Please either approve this, or relax that requirement. Last time i believe relaxing it was rejected. |
Summary
Adds a scheduled workflow that automatically labels open PRs whose GitHub Actions workflow runs are in the
action_requiredstate — i.e. waiting for a maintainer with write access to click Approve and run.This lets us easily find PRs that need a manual approval click via:
…or:
How it works
cron: '*/15 * * * *'+workflow_dispatch(with optionalwhatIfdry-run input). Mirrors the pattern inCleanUpStalePRChecks.yaml.needs-approvallabel exists (creates it if missing, color#FBCA04).status=action_requiredfrom the Actions API.commits/{sha}/pullssince fork-PR workflow runs have an emptypull_requestsarray).if: github.repository_owner == 'microsoft'so forks don't run it.actions/checkout, composite action under.github/actions/, GitHub step summary.Files
.github/workflows/LabelPRsAwaitingApproval.yaml— workflow (schedule + manual).github/actions/LabelPRsAwaitingApproval/action.yaml— composite action wrapper.github/actions/LabelPRsAwaitingApproval/action.ps1— reconciliation logicValidation
Dry-run against
microsoft/BCApps(using-WhatIf) successfully:action_requiredworkflow runsPermissions
The workflow requests minimum required scopes:
actions: read— list action_required runscontents: read— checkout the composite actionissues: write+pull-requests: write— manage the labelUses
github.token— no additional secrets needed.Caveats / future enhancements
workflow_run: types: [completed]for near-instant labelling.AB#637233