From 9b205680ee7674154459699cb5d70f1e879ac683 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Thu, 12 Mar 2026 15:59:25 -0700 Subject: [PATCH] feat(dev-infra): add PR review agent skill This commit introduces an AI agent skill for reviewing pull requests against the Angular repository. It establishes guidelines for ensuring code cleanliness, performance, testing, API design, and payload size. It supports performing reviews through both the GitHub CLI (remote) and local editing, factoring in package-specific guidelines (e.g., router) and prioritizing user approval before posting comments. By checking existing comments first, the agent can avoid duplicate reviews. This provides the AI agent with a reproducible workflow for providing constructive, manual PR feedback. --- .gemini/skills/pr_review/SKILL.md | 95 +++++++++++++++++++ .gemini/skills/pr_review/reference/router.md | 7 ++ .../scripts/determine_review_type.sh | 31 ++++++ .../pr_review/scripts/get_pr_comments.sh | 28 ++++++ .../pr_review/scripts/post_inline_comment.sh | 44 +++++++++ .../pr_review/scripts/reply_pr_comment.sh | 30 ++++++ 6 files changed, 235 insertions(+) create mode 100644 .gemini/skills/pr_review/SKILL.md create mode 100644 .gemini/skills/pr_review/reference/router.md create mode 100755 .gemini/skills/pr_review/scripts/determine_review_type.sh create mode 100755 .gemini/skills/pr_review/scripts/get_pr_comments.sh create mode 100755 .gemini/skills/pr_review/scripts/post_inline_comment.sh create mode 100755 .gemini/skills/pr_review/scripts/reply_pr_comment.sh diff --git a/.gemini/skills/pr_review/SKILL.md b/.gemini/skills/pr_review/SKILL.md new file mode 100644 index 000000000000..5c6ff93ce65e --- /dev/null +++ b/.gemini/skills/pr_review/SKILL.md @@ -0,0 +1,95 @@ +--- +name: PR Review +description: Guidelines and tools for reviewing pull requests in the Angular repository. +--- + +# PR Review Guidelines + +When reviewing a pull request for the `angular` repository, follow these essential guidelines to ensure high-quality contributions: + +1. **Context & Ecosystem**: + - Keep in mind that this is the core Angular framework. Changes here can impact millions of developers. + - Be mindful of backwards compatibility. Breaking changes require strict approval processes and deprecation periods. + +2. **Key Focus Areas**: + - **Comprehensive Reviews**: You **MUST always** perform a deep, comprehensive review of the _entire_ pull request. If the user asks you to look into a specific issue, file, or area of concern, you must investigate that specific area _in addition to_ reviewing the rest of the PR's substantive changes. Do not terminate your review after addressing only the user's focal point. + - **Package-Specific Guidelines**: Check if there are specific guidelines for the package being modified in the `reference/` directory (e.g., `reference/router.md`). Always prioritize these rules for their respective packages. + - **Commit Messages**: Evaluate the quality of commit messages. They should explain the _why_ behind the change, not just the _what_. Someone should be able to look at the commit history years from now and clearly understand the context and reasoning for the change. + - **Code Cleanliness**: Ensure the code is readable, maintainable, and follows Angular's project standards. + - **Performance**: Look out for code that might negatively impact runtime performance or bundle size, particularly in hot paths like change detection or rendering. + - **Testing**: Ensure all new logic has comprehensive tests, including edge cases. **Do NOT run tests locally** as part of your review process. CI handles this automatically, and running tests locally is redundant and inefficient. + - **API Design**: Ensure new public APIs are well-designed, consistent with existing APIs, and properly documented. + - **Payload Size**: Pay attention to the impact of changes on the final client payload size. + +3. **Execution Workflow**: + Determine the appropriate review method. If the user explicitly asks for a `local` or `remote` review in their request, that takes precedence. Otherwise, use `.agent/skills/pr_review/scripts/determine_review_type.sh ` to determine if the review should be `local` or `remote`. + + **Common Review Practices (Applies to both Local and Remote)** + - **Preparation & Checklist**: + - First, create a task list (e.g., in `task.md`) that you can easily reference containing **all** the review requirements from the "Key Focus Areas" section (Commit Messages, Performance, Testing, etc.), along with any specific review notes or requests from the user. + - Before doing an in-depth review, expand this list into more detailed items of what you plan to explore and verify in the PR. + - As you conduct the review, check off items in this list, adding your assessment or findings underneath each item. + - At the end of your review, refer back to the checklist to ensure every single requirement was completely verified. + - **Fetch PR Metadata Safely**: When you need to read the PR description or context, do NOT use `gh pr view ` by itself, as its default GraphQL query may fail due to lack of `read:org` and `read:discussion` token scopes. Instead, use `read_url_content` on the PR URL or use `gh pr view --json title,body,state,author`. + - **Check Existing Comments First**: Before formulating feedback, use the `get_pr_comments.sh` script to fetch existing comments on the PR. Review this feedback to avoid duplicate comments, and incorporate its insights into your own review process. + - **Constructive Feedback**: Provide clear, actionable, and polite feedback. Explain the _why_ behind your suggestions or edits. Do **NOT** leave inline comments purely to praise, agree with, or acknowledge a correct implementation detail, as this clutters the review. If you want to praise the PR, do so in the single general PR comment. + + **A. Local Code Review (If the PR is owned by the author requesting the review)** + - **Checkout**: Check out the PR branch locally (if it doesn't already exist, fetch it). + - **Review & Edit**: Execute the review directly on the code. Instead of adding inline PR comments for suggestions, format the codebase or apply the edits directly to the files. + - **Feedback**: Summarize the review findings and the concrete changes you made in a message to the user, referencing the completed items from your checklist. + - **Do NOT Commit or Push**: Leave the changes uncommitted in the working directory so the user can easily review the pending edits locally. Let the user know the changes are ready for their review, but do not ask for approval to push. + - **Resolve Comments**: Once the user confirms the changes are good and should be committed/pushed, respond to the existing comments as 'resolved'. Use `.agent/skills/pr_review/scripts/reply_pr_comment.sh ` to post a reply stating that the issue was addressed. + + **B. Remote Code Review (For all other PRs)** + - **Prefer Inline Comments**: Whenever your feedback relates to specific lines of code in the PR diff, strongly prefer posting inline comments using the `.agent/skills/pr_review/scripts/post_inline_comment.sh` script instead of a general PR review comment. This provides much better context for the author. + - **Require User Approval Before Posting**: Prepare your review comments and present them to the user, alongside a summary of your completed checklist. **Do NOT** post comments to the PR using scripts or the `gh` CLI without explicitly asking the user for permission first. Only post the review after the user approves. + - **Prefix Agent Comments**: To make it clear when comments are generated and posted by an AI agent rather than a human user, **always** prefix your review comments with `AGENT: `. + +## Available Scripts + +### `determine_review_type.sh` + +Determines whether to use the Local or Remote review workflow by checking if the currently authenticated GitHub user via the `gh` CLI matches the author of the pull request. + +**Usage:** + +```bash +.agent/skills/pr_review/scripts/determine_review_type.sh +``` + +### `get_pr_comments.sh` + +Fetches all existing inline comments on a PR using the GitHub API. This is crucial for reviewing other contributors' feedback and avoiding duplicate comments. It outputs JSON containing the `id`, `path`, `line`, `body`, and `user` for each comment. + +**Usage:** + +```bash +.agent/skills/pr_review/scripts/get_pr_comments.sh +``` + +### `reply_pr_comment.sh` + +Replies to an existing PR comment thread. This is useful for marking comments as resolved after addressing them in a local code review. Note that the `COMMENT_ID` must be the ID of the top-level comment in the thread. + +**Usage:** + +```bash +.agent/skills/pr_review/scripts/reply_pr_comment.sh +``` + +### `post_inline_comment.sh` + +The GitHub CLI `gh pr review` command does not natively support adding inline comments to specific lines of code via its standard flags. This script wraps the GitHub API to provide that functionality. + +**Usage:** + +```bash +.agent/skills/pr_review/scripts/post_inline_comment.sh +``` + +**Example:** + +```bash +.agent/skills/pr_review/scripts/post_inline_comment.sh 12345 "packages/core/src/render3/instructions/element.ts" 42 "AGENT: Consider the performance implications here." +``` diff --git a/.gemini/skills/pr_review/reference/router.md b/.gemini/skills/pr_review/reference/router.md new file mode 100644 index 000000000000..2d0569af9247 --- /dev/null +++ b/.gemini/skills/pr_review/reference/router.md @@ -0,0 +1,7 @@ +# Router PR Review Guidelines + +When reviewing pull requests that modify the Angular Router (`packages/router`), pay special attention to the following: + +- **Timing Sensitivity**: The router is extremely sensitive to timing changes. Any changes that alter the asynchronous timing of navigations, resolvers, or guards are almost always breaking changes and must be scrutinized carefully. +- **Testing Practices**: Tests should usually use the `RouterTestingHarness`. Many existing tests are older and do not use this harness. Do not blindly follow the shape of existing tests when writing or reviewing new ones; encourage the use of modern testing utilities. +- **Feature Justification**: Changes to router core code should be well-justified. Consider whether the change is proven to be a core developer ask, such as resolving a highly upvoted GitHub issue or addressing a critical bug. diff --git a/.gemini/skills/pr_review/scripts/determine_review_type.sh b/.gemini/skills/pr_review/scripts/determine_review_type.sh new file mode 100755 index 000000000000..b1e40fb049b2 --- /dev/null +++ b/.gemini/skills/pr_review/scripts/determine_review_type.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +# determine_review_type.sh +# Determines if the PR should be reviewed locally or remotely based on author. + +if [ -z "$1" ]; then + echo "Usage: determine_review_type.sh " + exit 1 +fi + +PR_NUMBER=$1 + +# Get current authenticated user +CURRENT_USER=$(gh api user -q .login 2>/dev/null) +if [ $? -ne 0 ]; then + echo "Error: Could not determine current GitHub user. Are you logged in to gh?" + exit 1 +fi + +# Get PR author +PR_AUTHOR=$(gh pr view "$PR_NUMBER" --json author -q .author.login 2>/dev/null) +if [ $? -ne 0 ]; then + echo "Error: Could not retrieve PR information for $PR_NUMBER." + exit 1 +fi + +if [ "$CURRENT_USER" = "$PR_AUTHOR" ]; then + echo "local" +else + echo "remote" +fi diff --git a/.gemini/skills/pr_review/scripts/get_pr_comments.sh b/.gemini/skills/pr_review/scripts/get_pr_comments.sh new file mode 100755 index 000000000000..99a15424c1bc --- /dev/null +++ b/.gemini/skills/pr_review/scripts/get_pr_comments.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# get_pr_comments.sh +# Fetches existing inline comments on a PR to avoid duplicate reviews. +# Usage: ./get_pr_comments.sh + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +PR_NUMBER="$1" + +# Ensure gh cli is installed +if ! command -v gh &> /dev/null; then + echo "Error: gh CLI could not be found. Please install and authenticate." + exit 1 +fi + +# Get the current repository (e.g., angular/angular) +REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) + +# Fetch comments +gh api \ + --paginate \ + -H "Accept: application/vnd.github+json" \ + "/repos/${REPO}/pulls/${PR_NUMBER}/comments" \ + --jq '.[] | {id: .id, path: .path, line: .line, body: .body, user: .user.login}' diff --git a/.gemini/skills/pr_review/scripts/post_inline_comment.sh b/.gemini/skills/pr_review/scripts/post_inline_comment.sh new file mode 100755 index 000000000000..f20992f7d2c6 --- /dev/null +++ b/.gemini/skills/pr_review/scripts/post_inline_comment.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash + +# post_inline_comment.sh +# Adds an inline comment to a specific line in a PR via the GitHub API. +# Usage: ./post_inline_comment.sh + +if [ "$#" -lt 4 ]; then + echo "Usage: $0 " + exit 1 +fi + +PR_NUMBER="$1" +FILE_PATH="$2" +LINE="$3" +BODY="$4" + +# Ensure gh cli is installed +if ! command -v gh &> /dev/null; then + echo "Error: gh CLI could not be found. Please install and authenticate." + exit 1 +fi + +# Get the current repository (e.g., angular/angular) +REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) + +echo "Posting inline comment to PR #${PR_NUMBER} on ${FILE_PATH}:${LINE}..." + +# Post the comment using the GitHub Pull Request Reviews API +gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "/repos/${REPO}/pulls/${PR_NUMBER}/reviews" \ + -f event="COMMENT" \ + -f comments[][path]="${FILE_PATH}" \ + -F comments[][line]="${LINE}" \ + -f comments[][body]="${BODY}" + +if [ $? -eq 0 ]; then + echo "Comment posted successfully!" +else + echo "Failed to post comment." + exit 1 +fi diff --git a/.gemini/skills/pr_review/scripts/reply_pr_comment.sh b/.gemini/skills/pr_review/scripts/reply_pr_comment.sh new file mode 100755 index 000000000000..2d98cfe30aeb --- /dev/null +++ b/.gemini/skills/pr_review/scripts/reply_pr_comment.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash + +# reply_pr_comment.sh +# Replies to an existing PR comment thread. Note: COMMENT_ID must be the ID of the top-level comment in the thread you are replying to. + +if [ "$#" -lt 3 ]; then + echo "Usage: reply_pr_comment.sh " + exit 1 +fi + +PR_NUMBER="$1" +COMMENT_ID="$2" +BODY="$3" + +# Ensure gh cli is installed +if ! command -v gh &> /dev/null; then + echo "Error: gh CLI could not be found. Please install and authenticate." + exit 1 +fi + +# Get the current repository (e.g., angular/angular) +REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner) + +# Reply to the thread using the provided comment ID +gh api \ + --silent \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + "/repos/${REPO}/pulls/${PR_NUMBER}/comments/${COMMENT_ID}/replies" \ + -f body="$BODY"