Repository navigation
ci: label open PRs with who owes the next move - #598
Conversation
Adds repo-review-state.yml, which keeps awaiting-maintainer / awaiting-author on every open PR, plus needs-rebase when GitHub reports the branch as conflicting. The open PR list then says who is blocked on whom, and "label:awaiting-maintainer" is the review queue. Only the maintainer and the PR author move the labels. People reporting test results on someone else's PR are ignored, otherwise a drive-by comment would pull a PR back into the queue. Events keep it current; the daily run recomputes every open PR from scratch, so a missed webhook, a hand-edited label, or a PR older than this workflow all correct themselves. Drafts and closed PRs carry none of the three labels. workflow_dispatch takes a dry_run input that only logs what it would change.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fc3b624951
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| pull_request_review: | ||
| types: [submitted] |
There was a problem hiding this comment.
Reconcile fork reviews through a write-capable event
For PRs from forks under GitHub's default token policy, this pull_request_review run has its requested write scopes downgraded to read-only, as described in GitHub's workflow-permissions documentation. A maintainer submitting a review therefore reaches issues.addLabels or removeLabel without permission and fails, leaving the previous turn label in place until another write-capable event or the nightly schedule runs.
Useful? React with 👍 / 👎.
| const classify = (login, association) => { | ||
| if (isMaintainerSide(association)) return AWAITING_AUTHOR; | ||
| if (login === author) return AWAITING_MAINTAINER; | ||
| return null; // third party: does not move the labels |
There was a problem hiding this comment.
Prioritize the PR author before maintainer association
When a repository owner, member, or collaborator authors a PR, their comments satisfy both conditions, but the maintainer-side check wins and marks the PR awaiting-author. This inverts the intended state after an internal contributor responds on their own PR; check login === author before the association-based classification.
Useful? React with 👍 / 👎.
| issue_comment: | ||
| types: [created] | ||
| pull_request_review: | ||
| types: [submitted] | ||
| pull_request_target: | ||
| types: [opened, reopened, synchronize, ready_for_review, converted_to_draft, closed] |
There was a problem hiding this comment.
Trigger reconciliation for inline review replies
When the author or maintainer replies directly in an existing diff thread, GitHub emits pull_request_review_comment, not issue_comment or a newly submitted review; GitHub documents it as the event for comments on a PR diff. Although whoseTurn reads these comments, none of the configured triggers runs for the reply, so the turn label remains stale until the nightly reconciliation.
Useful? React with 👍 / 👎.
| const lastCommit = commits[commits.length - 1]; | ||
| note(lastCommit?.commit?.committer?.date, AWAITING_MAINTAINER); |
There was a problem hiding this comment.
Record push activity instead of the commit's embedded date
When a synchronize event moves the PR head to an existing or deliberately backdated commit, commit.committer.date can predate the latest maintainer response because it is commit metadata rather than the time the commit was pushed. Sorting by this value then leaves awaiting-author even though the workflow's stated rule says every push must switch to awaiting-maintainer; the synchronize occurrence needs to be represented using actual push/event activity.
Useful? React with 👍 / 👎.
…t the push event Three fixes from review: - A maintainer's own PR matched the association check before the author check, so their comments read as "we answered" and labelled it awaiting-author. Author wins now; it is still their change to push. - Replies inside an existing diff thread raise pull_request_review_comment, which was not a trigger, so whoseTurn() read them but nothing ran until the nightly pass. - A push is taken from the event rather than from the new head commit's embedded date, which can predate the last reply after a rebase or a cherry-pick and leave the PR on awaiting-author.
|
Took three of the four, in 6d281af. Author before association - right, and it was wrong on this very PR: before the fix #598 computed as pull_request_review_comment - right, that trigger was missing. Push time vs committer date - right in principle: a rebase or cherry-pick can carry a date older than the last reply. A push is now taken from the event itself rather than derived from the head commit, so synchronize/opened/reopened/ready_for_review go straight to Fork token on pull_request_review - not taking this one. The read-only downgrade applies to Dry run against the current open list, unchanged apart from #598: |
Keeps
awaiting-maintainer/awaiting-authoron every open PR, plusneeds-rebasewhen GitHub reports the branch as conflicting.is:open label:awaiting-maintaineris then the review queue.Who moves the labels. Only the maintainer and the PR author. Anyone else commenting - people reporting test results on someone else's PR, which happens a lot here - is ignored, so a drive-by comment doesn't pull a PR back into the queue. A push always means
awaiting-maintainer: there is new code to look at, whoever pushed it. Drafts and closed PRs carry none of the three labels.Why both events and a schedule. The events keep it current; the nightly run recomputes every open PR from scratch, so a missed webhook, a hand-edited label or a PR older than this workflow all heal by themselves. It also back-fills the current open PRs on the first run.
No checkout, so
pull_request_targethas nothing to execute from the fork.Dry-run of the same logic against the repo as it stands:
The three labels already exist.
workflow_dispatchtakes adry_runinput that only logs what it would change - worth one run with it on after merging, sinceworkflow_dispatchandscheduleonly work from the default branch.