Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions .github/workflows/auto_assign_reviewer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Auto-assign Code Review

on:
pull_request:
types: [opened, ready_for_review]

permissions:
contents: read
pull-requests: write

concurrency:
group: auto-assign-review-${{ github.event.pull_request.number }}
cancel-in-progress: false

jobs:
assign:
runs-on: ubuntu-latest
# Self-authored PRs (opened by openlibrary-bot itself) are excluded here --
# GitHub rejects requesting a PR's own author as a reviewer (422). Those are
# handled directly by code_review_action.yml's own opened/ready_for_review
# trigger instead, bypassing the reviewer-request mechanism entirely.
if: >
!github.event.pull_request.draft &&
github.event.pull_request.user.login != 'openlibrary-bot'
steps:
- name: Request openlibrary-bot as reviewer if not already present
uses: actions/github-script@v9
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const prNumber = context.payload.pull_request.number;

const { data: requested } = await github.rest.pulls.listRequestedReviewers({
owner, repo, pull_number: prNumber,
});
if (requested.users.some((u) => u.login === 'openlibrary-bot')) {
core.info(`PR #${prNumber} already has openlibrary-bot requested -- skipping.`);
return;
}

const reviews = await github.paginate(github.rest.pulls.listReviews, {
owner, repo, pull_number: prNumber, per_page: 100,
});
if (reviews.some((r) => r.user.login === 'openlibrary-bot')) {
core.info(`PR #${prNumber} already has an openlibrary-bot review -- skipping.`);
return;
}

await github.rest.pulls.requestReviewers({
owner, repo, pull_number: prNumber,
reviewers: ['openlibrary-bot'],
});
core.info(`Requested openlibrary-bot as reviewer on PR #${prNumber}.`);
117 changes: 117 additions & 0 deletions .github/workflows/code_review_action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: Code Review Action

on:
pull_request:
types: [review_requested, opened, ready_for_review]
issue_comment:
types: [created]
workflow_dispatch:
inputs:
pr_number:
description: "Debug: manually run the code review trigger on a specific existing PR"
required: true
type: string

permissions:
contents: read
pull-requests: write
issues: write

concurrency:
group: code-review-${{ github.event.pull_request.number || github.event.issue.number || inputs.pr_number }}
cancel-in-progress: false

jobs:
respond:
runs-on: ubuntu-latest
# Placeholder scaffold for #13163 -- trigger wiring only, no review logic yet.
#
# Three trigger paths:
# 1. review_requested with openlibrary-bot as the reviewer -- covers both a
# human manually requesting it, and auto_assign_reviewer.yml's automated
# request. No staff-login check here: requesting *any* reviewer already
# requires write/triage access on GitHub's side, so this isn't an open door.
# 2. opened / ready_for_review where the PR's own author is openlibrary-bot --
# GitHub rejects requesting a PR's own author as a reviewer (422), so a
# self-authored PR can never reach this workflow via path 1. This is the
# direct substitute for "add openlibrary-bot as a reviewer on its own PR",
# which is not literally possible.
# 3. issue_comment @-mention on a PR -- open to any commenter, including
# external contributors with only read access, so this path keeps an
# explicit staff allowlist (mirrors pr_autoresponder.yml / issue_enrichment.md).
#
# Draft PRs never trigger a review, on any path -- enforced again defensively
# inside the job itself (see Step 1), since issue_comment's payload has no
# PR draft field to check at the `if:` level.
if: >
github.event_name == 'workflow_dispatch' ||
(
github.event_name == 'pull_request' &&
!github.event.pull_request.draft &&
(
github.event.requested_reviewer.login == 'openlibrary-bot' ||
github.event.pull_request.user.login == 'openlibrary-bot'
)
) || (
github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '@openlibrary-bot') &&
github.event.comment.user.login != 'openlibrary-bot' &&
contains(fromJSON('["mekarpeles","cdrini","jimchamp","hornc","scottbarnes","seabelis","RayBB","lokesh"]'), github.event.comment.user.login)
)
steps:
- name: Acknowledge trigger (placeholder -- no review logic yet)
uses: actions/github-script@v9
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const prNumber = context.eventName === 'workflow_dispatch'
? Number(context.payload.inputs.pr_number)
: (context.payload.pull_request
? context.payload.pull_request.number
: context.payload.issue.number);

// Defensive draft check -- issue_comment's payload has no PR draft
// field, and this also re-confirms the pull_request-path checks
// above in case GitHub's payload state lagged the actual PR state.
const { data: pr } = await github.rest.pulls.get({
owner, repo, pull_number: prNumber,
});
if (pr.draft) {
core.info(`PR #${prNumber} is a draft -- skipping.`);
return;
}

// Idempotency: this workflow can be reached by multiple overlapping
// paths (e.g. opened -> auto-assign -> review_requested), so guard
// against posting more than one placeholder.
const comments = await github.paginate(github.rest.issues.listComments, {
owner, repo, issue_number: prNumber, per_page: 100,
});
if (comments.some((c) => (c.body || '').includes('<!-- ol-pr-review-bot -->'))) {
core.info(`PR #${prNumber} already has a placeholder comment -- skipping.`);
return;
}

let trigger;
if (context.eventName === 'workflow_dispatch') {
trigger = 'a manual debug dispatch';
} else if (context.eventName === 'issue_comment') {
trigger = 'an @-mention';
} else if (pr.user.login === 'openlibrary-bot') {
trigger = 'its own PR being opened (self-authored, cannot request itself as reviewer)';
} else {
trigger = 'a reviewer request';
}

await github.rest.issues.createComment({
owner, repo, issue_number: prNumber,
body: [
`👀 Code review was requested via ${trigger}, but the automated reviewer isn't built yet — tracked in #13163.`,
'',
'This comment only confirms the trigger fired correctly. No review was performed.',
'',
'<!-- ol-pr-review-bot -->',
].join('\n'),
});