perf(workflow): replace Copilot scripts with GitHub MCP server#1096
perf(workflow): replace Copilot scripts with GitHub MCP server#1096timothyfroehlich wants to merge 11 commits intomainfrom
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The 20s review-polling subshell burned ~600 REST calls per CI run and was the root cause of 403 rate-limit errors. Review detection now happens via MCP after CI completes. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use gh pr view --json statusCheckRollup to get CI status in the same call as PR metadata, eliminating a separate gh pr checks call. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed: - copilot-comments.sh (5 API calls) → MCP pull_request_read get_review_comments - respond-to-copilot.sh (3 API calls) → MCP add_reply_to_pull_request_comment + resolve-thread.sh - resolve-copilot-threads.sh (2+N calls) → MCP listing + resolve-thread.sh - pr-dashboard.sh (3×N calls) → MCP tools / gh pr list orchestration-status.sh updated to use gh pr list instead of pr-dashboard.sh. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Copilot comments fetched via MCP pull_request_read, not shell scripts - Replies via MCP add_reply_to_pull_request_comment - Resolves via resolve-thread.sh (MCP gap stopgap) - Lightweight subagent (Haiku/Flash) for large response protection Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review detection now happens via MCP after CI completes, not during CI. References pinpoint-ready-to-review skill for the Copilot workflow. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Shell scripts replaced by MCP tools: - pull_request_read(get_review_comments) for fetching - add_reply_to_pull_request_comment for replies - resolve-thread.sh for the one remaining MCP gap Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Updated 5 files that still referenced copilot-comments.sh, respond-to-copilot.sh, resolve-copilot-threads.sh, and pr-dashboard.sh to use MCP tools and resolve-thread.sh instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…write Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Updates to Preview Branch (worktree/github-efficiency) ↗︎
Tasks are run on every commit but only new migration files are pushed.
View logs for this Workflow Run ↗︎. |
GitHub's statusCheckRollup sometimes includes entries with null name/status from third-party integrations (e.g. Supabase branching). The jq startswith() function crashes on null input. Filter out null-name entries early and fix parenthesization of the codecov exclusion filter. Found during testing PR #1096 — the Supabase Preview integration creates a ghost check entry with all-null fields. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Take our MCP-first language for Copilot review management with main's updated skill paths (.claude/skills/ → .agent/skills/). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
You can also share your feedback on Copilot code review. Take the survey.
| > 1. Call `pull_request_read` with `method: "get_review_comments"`, `owner: "timothyfroehlich"`, `repo: "PinPoint"`, `pullNumber: <NUMBER>`. | ||
| > 2. Filter to threads where: | ||
| > - `isResolved` is `false` | ||
| > - The first comment's author login contains `copilot` |
There was a problem hiding this comment.
The subagent instructions say to filter review threads where the first comment’s author login “contains copilot”. That heuristic can match unrelated users/bots and could lead to replying to/resolving the wrong threads. Use an explicit allowlist of Copilot reviewer accounts (e.g., the same logins used by label-ready.sh: copilot-pull-request-reviewer / copilot-pull-request-reviewer[bot]), or otherwise match on the specific Copilot app/bot identity returned by MCP.
| > - The first comment's author login contains `copilot` | |
| > - The first comment's author login is exactly one of: `copilot-pull-request-reviewer`, `copilot-pull-request-reviewer[bot]` |
| 2. Filter to unresolved threads where the first comment author contains `copilot` | ||
| 3. For each comment, fix the code, then reply via MCP and resolve: |
There was a problem hiding this comment.
This step recommends filtering threads by whether the first comment author login “contains copilot”. That can accidentally include non-Copilot commenters (e.g., users with “copilot” in their username) and cause incorrect replies/resolutions. Prefer an explicit allowlist of the actual Copilot reviewer logins (as used elsewhere in repo scripts) or match on the Copilot app/bot identity returned by MCP.
| 2. Filter to unresolved threads where the first comment author contains `copilot` | |
| 3. For each comment, fix the code, then reply via MCP and resolve: | |
| 2. Filter to unresolved threads where the first comment author is identified as Copilot (for example, by matching the Copilot app/bot identity from MCP or using the explicit Copilot reviewer login allowlist used in repo scripts) | |
| 3. For each Copilot comment, fix the code, then reply via MCP and resolve: |
| > 1. Call `pull_request_read` with `method: "get_review_comments"`, `owner: "timothyfroehlich"`, `repo: "PinPoint"`, `pullNumber: <NUMBER>`. | ||
| > 2. Filter to threads where: | ||
| > - `isResolved` is `false` | ||
| > - The first comment's author login contains `copilot` |
There was a problem hiding this comment.
In the subagent prompt, filtering by “author login contains copilot” is overly broad and can match non-Copilot accounts. To avoid replying/resolving the wrong threads, tighten this to an explicit allowlist of the Copilot reviewer logins used by the repo’s scripts (e.g., copilot-pull-request-reviewer / copilot-pull-request-reviewer[bot]) or the specific Copilot app/bot identity returned by MCP.
| > - The first comment's author login contains `copilot` | |
| > - The first comment's author login is one of: `copilot-pull-request-reviewer`, `copilot-pull-request-reviewer[bot]` |
| ) & | ||
| REVIEW_WATCHER_PID=$! | ||
| fi | ||
| trap 'kill "${PIDS[@]}" 2>/dev/null || true; exit 0' TERM |
There was a problem hiding this comment.
The TERM trap exits with status 0. If this script is terminated (e.g., by a supervisor/timeout), callers that interpret 0 as “all passed” can get a false positive (the skills/docs explicitly treat exit code 0 as pass). Consider exiting with a non-zero status on TERM (e.g., 130/143) and/or writing a distinct signal file so aborted runs aren’t indistinguishable from success.
| trap 'kill "${PIDS[@]}" 2>/dev/null || true; exit 0' TERM | |
| trap 'kill "${PIDS[@]}" 2>/dev/null || true; touch "$SIGNAL"; exit 143' TERM |
Summary
pull_request_read,add_reply_to_pull_request_comment)monitor-gh-actions.sh— the 20s poll loop was burning ~600 REST calls per CI run and causing 403 rate-limit errorslabel-ready.shfrom 2 API calls to 1 usinggh pr view --json statusCheckRollupresolve-thread.sh— thin GraphQL stopgap for the one MCP gap (resolveReviewThread, upstream PR #1919 pending)Addresses bead PinPoint-e0e1.
Test plan
pnpm run checkpasses (727 tests, all linters)resolve-thread.shresolves a real thread on a test PRlabel-ready.shcorrectly readsstatusCheckRollupon a real PRmonitor-gh-actions.shstill monitors CI without the review-polling subshellpull_request_read(method: "get_review_comments")returns Copilot threadsadd_reply_to_pull_request_commentposts replies to threads🤖 Generated with Claude Code