feat(ci): AI Action to review contributor pull requests - #70
Merged
Conversation
When someone other than the repository owner opens or updates a PR, analyze the diff with an OpenAI-compatible LLM and upsert review suggestions as a PR comment. Uses pull_request_target safely by only fetching the diff via the API (no untrusted checkout/exec). Co-authored-by: Haozheng Li <emiya@emiya.com.cn>
Strengthen workflow and script filters so bot authors (login ends with [bot], user.type Bot, or known bot names) never trigger LLM review. Co-authored-by: Haozheng Li <emiya@emiya.com.cn>
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Paginate issue comments so existing marked reviews are updated instead of duplicated.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Adds an automated GitHub Action that analyzes eligible contributor PRs with an OpenAI-compatible LLM and updates a single review comment.
Changes:
- Adds the PR review workflow.
- Adds Python logic for diff analysis and comment management.
- Filters owner, bot, and draft PRs.
File summaries
| File | Review summary |
|---|---|
scripts/ci/ai_pr_review.py |
Moderate issue: paginate issue comments to reliably find and update existing reviews. |
.github/workflows/pr-ai-review.yml |
Workflow configuration reviewed; no final comments. |
Review details
Suppressed comments (4)
.github/workflows/pr-ai-review.yml:31
- These checks use
github.actor, which is the user or bot that caused the event, not the pull request author. A human-authored PR synchronized by an automation bot (for example, a formatting or branch-update workflow) will therefore be skipped even thoughpull_request.useris human andis_bot_author()would allow it. Gate only ongithub.event.pull_request.userto match the documented author-based bot filtering.
&& github.actor != 'dependabot[bot]'
&& !endsWith(github.actor, '[bot]')
scripts/ci/ai_pr_review.py:183
- The final fallback treats any comment containing the marker as this action's comment, including a human-authored comment that can be created before the workflow runs. The update can then overwrite that comment (or fail if the token cannot edit it) instead of updating the action's own comment. Restrict the match to the authenticated workflow bot rather than returning the first marker-bearing comment.
if AI_PR_REVIEW_MARKER in body:
return int(comment["id"])
scripts/ci/ai_pr_review.py:50
- This new bot-classification gate has no automated tests, although the repository's Python CI runs a substantial pytest suite. Add unit tests covering
user.type == Bot,[bot]logins, known bot aliases, and human authors so the defense-in-depth skip behavior cannot regress silently.
def is_bot_author(login: str, user_type: str | None = None) -> bool:
name = (login or "").strip().lower()
if not name:
return False
if (user_type or "").lower() == "bot":
return True
if name.endswith("[bot]"):
return True
return name in KNOWN_BOT_LOGINS
scripts/ci/ai_pr_review.py:170
- This request is hard-coded to the first 100 issue comments. If a PR already has more than 100 comments before the first review run, the marker can be on a later page; subsequent synchronize events will not find it and will create another review comment instead of updating the existing one. Follow the API pagination links (or otherwise search all pages) before creating a comment.
url = f"{api_base}/repos/{owner}/{repo}/issues/{pr_number}/comments?per_page=100"
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
|
|
||
| def find_existing_comment(api_base: str, token: str, owner: str, repo: str, pr_number: int) -> int | None: | ||
| url = f"{api_base}/repos/{owner}/{repo}/issues/{pr_number}/comments?per_page=100" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a GitHub Action that automatically analyzes PR diffs and posts review suggestions when someone other than the repository owner opens or updates a PR.
What was added
.github/workflows/pr-ai-review.yml— triggers onpull_request_target(opened/synchronize/reopened/ready_for_review)scripts/ci/ai_pr_review.py— fetches PR metadata + diff via GitHub API, calls an OpenAI-compatible LLM, and upserts a single PR commentBehavior
*[bot]login oruser.type == Bot), draft PRsif+ script-levelis_bot_author()both skip bots<!-- agentflow-ai-pr-review -->) instead of spammingRequired setup (after merge)
LLM_API_KEY(orOPENAI_API_KEY)LLM_BASE_URL(defaulthttps://api.openai.com/v1) — any OpenAI-compatible endpointLLM_MODEL(defaultgpt-4o-mini)Without the secret, the workflow warns and exits without failing the PR.
Test plan
LLM_API_KEY(and optionalLLM_BASE_URL/LLM_MODEL)