Skip to content

feat: add lightweight Gemini advisory PR review workflow#125

Open
Aaravanand00 wants to merge 1 commit intohyperledger-identus:mainfrom
Aaravanand00:feat/gemini-pr-review-bot-v3-lite
Open

feat: add lightweight Gemini advisory PR review workflow#125
Aaravanand00 wants to merge 1 commit intohyperledger-identus:mainfrom
Aaravanand00:feat/gemini-pr-review-bot-v3-lite

Conversation

@Aaravanand00
Copy link
Copy Markdown

Summary

This adds a simple Gemini-based review workflow for pull requests.
It gives quick, automated feedback on code changes to help spot potential issues or improvements. The feedback is advisory only and does not block merging.

What it does

  1. Runs on pull requests
  2. Reviews code changes (ignores docs/config files)
  3. Posts a short, non-blocking review comment
  4. Can also be triggered manually using /gemini-review

Notes

  1. Designed to be lightweight and low-noise
  2. Keeps things simple and easy to remove or adjust if needed
  3. Does not replace normal code review

Introduces a non-blocking Gemini AI review system that fetches diffs per file, handles pagination, and provides actionable feedback as advisory comments.

Signed-off-by: Aaravanand00 <aaravanand5749@gmail.com>
Copilot AI review requested due to automatic review settings April 22, 2026 09:09
@sonarqubecloud
Copy link
Copy Markdown

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a lightweight GitHub Actions workflow plus a Node.js script to generate an advisory PR review using Gemini and post the result back to the pull request.

Changes:

  • Introduces a new PR/command-triggered GitHub Actions workflow for Gemini advisory reviews.
  • Adds a Node.js script that fetches PR diffs via GitHub API, calls Gemini, and posts the advisory feedback to the PR.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
.github/workflows/gemini-pr-review.yml New workflow that triggers on PR activity and /gemini-review comments, sets permissions, and runs the reviewer script.
.github/scripts/gemini-pr-review.js New script that fetches PR file patches, filters/truncates diffs, calls Gemini with a structured prompt, and posts the advisory review.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +45 to +48
const isIgnored = filename.endsWith('.md') ||
filename.endsWith('.txt') ||
filename.startsWith('.github/');

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The diff filtering currently ignores any file under .github/ (filename.startsWith('.github/')). That will exclude code changes in .github/scripts and other non-config logic stored under .github/, which conflicts with the stated goal of ignoring only docs/config. Consider narrowing the ignore list to specific paths (e.g., .github/workflows/, .github/dependabot.yml) or excluding only known non-code extensions, so actionable code in .github/ can still be reviewed.

Copilot uses AI. Check for mistakes.
Comment on lines +109 to +129
const response = await fetchWithTimeout(`https://api.github.com/repos/${repo}/pulls/${prNumber}/reviews`, {
method: 'POST',
headers: {
Authorization: `token ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
body: commentBody,
event: 'COMMENT'
}),
});

if (!response.ok) {
console.warn('Pull Request Review API failed, falling back to Issue Comment API.');
await postFallbackComment(repo, prNumber, token, commentBody);
} else {
console.log('Advisory review posted successfully.');
}
} catch (err) {
console.error('Failed to post review:', err.message);
await postFallbackComment(repo, prNumber, token, commentBody);
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

postReview always creates a new PR review via the Reviews API. On synchronize (and on repeated /gemini-review runs) this will generate multiple advisory reviews and can clutter the PR timeline. Consider de-duping by using the Issues Comments API as the primary mechanism (you already have update-or-create logic in postFallbackComment) or by checking for an existing bot review/comment and updating/replacing it instead of posting a new one each run.

Suggested change
const response = await fetchWithTimeout(`https://api.github.com/repos/${repo}/pulls/${prNumber}/reviews`, {
method: 'POST',
headers: {
Authorization: `token ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
body: commentBody,
event: 'COMMENT'
}),
});
if (!response.ok) {
console.warn('Pull Request Review API failed, falling back to Issue Comment API.');
await postFallbackComment(repo, prNumber, token, commentBody);
} else {
console.log('Advisory review posted successfully.');
}
} catch (err) {
console.error('Failed to post review:', err.message);
await postFallbackComment(repo, prNumber, token, commentBody);
await postFallbackComment(repo, prNumber, token, commentBody);
console.log('Advisory review comment upserted successfully.');
} catch (err) {
console.error('Failed to post advisory review comment:', err.message);

Copilot uses AI. Check for mistakes.
Comment on lines +155 to +159
if (!GITHUB_TOKEN || !GEMINI_API_KEY || !REPO || !GITHUB_EVENT_PATH) {
console.error('Required environment variables are missing.');
process.exit(1);
}

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For forked PRs (and other contexts), GEMINI_API_KEY won't be available; currently the script exits with code 1 when env vars are missing, which will mark the workflow run as failed and add noise even though the review is intended to be advisory. Consider treating missing GEMINI_API_KEY as a graceful skip (log and exit 0), while still failing only on genuinely unexpected errors when the secret is configured.

Suggested change
if (!GITHUB_TOKEN || !GEMINI_API_KEY || !REPO || !GITHUB_EVENT_PATH) {
console.error('Required environment variables are missing.');
process.exit(1);
}
if (!GITHUB_TOKEN || !REPO || !GITHUB_EVENT_PATH) {
console.error('Required GitHub environment variables are missing.');
process.exit(1);
}
if (!GEMINI_API_KEY) {
console.log('Skipping Gemini PR review: GEMINI_API_KEY is not available in this context.');
process.exit(0);
}

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +8
name: Gemini Advisory PR Review

on:
pull_request:
types: [opened, synchronize, labeled]
issue_comment:
types: [created]

Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow doesn't set a top-level permissions: {} block. In this repo, other workflows explicitly set empty default permissions and then grant the minimum job-level permissions (e.g., .github/workflows/ci.yml:11, codeql.yml:23). Adding permissions: {} at the workflow level reduces the chance of accidentally inheriting broader defaults if GitHub changes defaults or the workflow is extended later.

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +40
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Run Gemini PR Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
run: node .github/scripts/gemini-pr-review.js
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: this workflow checks out the PR's code (actions/checkout default ref) and then executes a script from the checkout while GEMINI_API_KEY is provided as a secret. A PR author could modify .github/scripts/gemini-pr-review.js to exfiltrate the secret during the run. Use a trusted ref for checkout (e.g., the base branch/pull_request.base.sha), or avoid checkout entirely and run a trusted script (or move to pull_request_target with a safe checkout strategy).

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +39
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Run Gemini PR Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codebase convention/supply-chain hardening: other workflows in this repo pin actions to immutable SHAs and include a step-security/harden-runner step (e.g., .github/workflows/ci.yml, codeql.yml). Here actions/checkout@v4 and actions/setup-node@v4 are unpinned and there's no runner hardening, which weakens provenance/egress auditing. Consider adding the harden-runner step and pinning action versions to SHAs for consistency and security.

Suggested change
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Run Gemini PR Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GEMINI_API_KEY: ${{ secrets.GEMINI_API_KEY }}
- name: Harden runner
uses: step-security/harden-runner@c6295a65d1254861815972266d5933fd6e532bdf
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Setup Node.js
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8
with:
node-version: '20'
- name: Run Gemini PR Review
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GEMINI_API_KEY: ${{ secrets.GITHUB_TOKEN }}

Copilot uses AI. Check for mistakes.
Comment on lines +17 to +20
# Only run for pull requests or comments on pull requests
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request)
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operational/perf: for issue_comment events, the job runs for every PR comment and only exits later inside the Node script unless the comment contains /gemini-review. You can reduce wasted runner time by adding an additional workflow/job-level condition that checks the comment body (e.g., contains(github.event.comment.body, '/gemini-review')) when github.event_name == 'issue_comment'.

Suggested change
# Only run for pull requests or comments on pull requests
if: |
github.event_name == 'pull_request' ||
(github.event_name == 'issue_comment' && github.event.issue.pull_request)
# Only run for pull requests or comments on pull requests that request Gemini review
if: |
github.event_name == 'pull_request' ||
(
github.event_name == 'issue_comment' &&
github.event.issue.pull_request &&
contains(github.event.comment.body, '/gemini-review')
)

Copilot uses AI. Check for mistakes.
Comment on lines +168 to +176
} else if (GITHUB_EVENT_NAME === 'issue_comment') {
if (!event.issue.pull_request) return;
prNumber = event.issue.number;
const commentBody = event.comment.body || '';
if (commentBody.includes('/gemini-review')) {
triggerSource = 'Comment: /gemini-review';
} else {
return;
}
Copy link

Copilot AI Apr 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security/abuse risk: the issue_comment trigger runs with repository secrets, and currently anyone who can comment on a PR can trigger /gemini-review (including external contributors on fork PRs). Add an authorization check (e.g., event.comment.author_association in {MEMBER, OWNER, COLLABORATOR} or explicitly allow-listed users) before calling Gemini to prevent secret-backed API usage being triggered by untrusted actors.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants