Skip to main content

review-external-pr

Triage an external contributor's PR and prepare it for merge. Detects push permission, base branch, draft state, size, and history quality, then picks one of three paths (review-only, direct push to contributor branch, or a `reviews/` staging branch). Use when triaging or reviewing a community PR, deciding whether maintainer changes are needed, choosing a merge strategy (squash/merge/rebase), or merging an external contribution.

来源信息

仓库
microsoft/vscode-documentdb
最近来源活动
2026年5月26日 10:12
检测到的 SKILL.md 语言
英语
星标
33
Forks
22

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
review-external-pr
description
Triage an external contributor's PR and prepare it for merge. Detects push permission, base branch, draft state, size, and history quality, then picks one of three paths (review-only, direct push to contributor branch, or a `reviews/` staging branch). Use when triaging or reviewing a community PR, deciding whether maintainer changes are needed, choosing a merge strategy (squash/merge/rebase), or merging an external contribution.
# Review External PR Workflow A triage-first workflow for handling community PRs. The skill **inspects first, asks two questions, then executes**. It never creates branches preemptively. ## When to Use - A contributor PR is open and you want to review and merge it - Trigger phrases: "prepare this external PR", "review PR #N", "let's review this contribution", or invocation while the user is on a `pr/<owner>/<PR_NUMBER>` branch (created by `gh pr checkout`) - You want a recommendation on push path and merge strategy before doing anything ## Phase 1 — Triage (read-only, no prompts) ### Identify the PR Resolve, in order: 1. The PR number the user mentioned. 2. Current branch matches `pr/<owner>/<PR_NUMBER>` → extract `<PR_NUMBER>`. 3. `gh pr status` → active PR for current branch. ### Fetch metadata in one call ```bash gh pr view <PR_NUMBER> --json number,title,author,url,state,isDraft,\ headRefName,baseRefName,headRepositoryOwner,maintainerCanModify,\ mergeable,mergeStateStatus,additions,deletions,changedFiles,commits,labels ``` ### Derive signals | Signal | Rule | | --------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----- | -------------- | ---- | ------ | ----- | | `canPushToHead` | `headRepositoryOwner.login == "microsoft"` OR `maintainerCanModify` | | `baseBranch` | `baseRefName` (do **not** hardcode `main`) | | `isDraft` | warn if `true` | | `mergeable` | warn if `mergeable != "MERGEABLE"` (values: `MERGEABLE`, `CONFLICTING`, `UNKNOWN`) | | `mergeReady` | warn if `mergeStateStatus` is not `CLEAN` (other values: `DIRTY`, `BLOCKED`, `BEHIND`, `UNSTABLE`, `HAS_HOOKS`, `UNKNOWN`) | | `commitCount` | `commits.length` | | `messyHistory` | any `commits[].messageHeadline` (the first line of the commit message, returned by `gh pr view --json commits`) matches `/wip | fixup | address review | typo | merge( | $)/i` | | `changedLines` | `additions + deletions` | | `sizeBucket` | small ≤ 50 changed lines, medium ≤ 300, large > 300 (uses `changedLines`) | ### Squash recommendation | Condition | Recommend | | ------------------------------------------------- | ------------------------------------------------------- | | `commitCount == 1` | **No squash** (rebase or merge) — history already clean | | `commitCount ≤ 3` AND no messy subjects AND small | Ask, **default no squash** | | `commitCount > 3` OR messy subjects detected | **Squash** (default) | ### Print the triage report ``` PR #<PR_NUMBER> — <title> Author: <login> (<fork|same-repo>) Base: <baseBranch> State: <state>, <draft?>, mergeable=<mergeable>, mergeStateStatus=<mergeStateStatus> Push to head: <✅ allowed reason | ❌ blocked reason> Size: +<additions> / -<deletions> across <changedFiles> file(s), <commitCount> commit(s) History: <clean | messy: "<sample messageHeadline>"> Recommendation: • Path: <direct push | reviews/ branch | review-only> • Merge: <--squash | --merge | --rebase> (<reason>) ``` Stop here and present the report. ## Phase 2 — Two questions Ask **only** these. Pre-select the recommended option. ### Q1: Do you need to add changes before merging? - **No** → Path A (review & merge) - **Yes, small tweaks** → Path B (direct push) if `canPushToHead`, otherwise Path C - **Yes, heavy rework / contributor unresponsive** → Path C (`reviews/` staging branch) If `canPushToHead == false`, omit the "direct push" option and explain: _"Contributor disabled maintainer edits; we must use a `reviews/` branch."_ ### Q2: Merge strategy? Offer `--squash`, `--merge`, `--rebase` with the recommended option marked. Justify the default in one short sentence (e.g., _"4 commits including 'fix typo' — squash recommended"_). ## Phase 3 — Execute Run commands non-interactively, echoing each one. After merge, print a one-line summary with the merged commit/PR URL. ### Path A — Review & merge (no maintainer changes) ```bash gh pr checkout <PR_NUMBER> # optional, for local inspection # review, leave comments via the PR UI or `gh pr review` gh pr merge <PR_NUMBER> --<strategy> # against the PR's actual base ``` ### Path B — Direct push to the contributor's branch Requires `canPushToHead == true`. ```bash gh pr checkout <PR_NUMBER> # sets up a remote tracking the fork branch # make changes, commit git push # updates the existing PR in place gh pr merge <PR_NUMBER> --<strategy> ``` The existing PR updates in place; the contributor keeps authorship of their commits and maintainer commits are attributed to the maintainer. No second PR is needed. ### Path C — `reviews/` staging branch Use when push to head is blocked, or when the maintainer explicitly wants to isolate rework. **Branch slug sanitization** — derive `<slug>` from the PR title: 1. Lowercase. 2. Replace every run of non-`[a-z0-9]` characters with a single `-`. 3. Trim leading/trailing `-`. 4. Truncate to 30 characters; trim trailing `-` again if the cut left one. Example: `"fix(tree): sort _id_ index first / cleanup"` → `fix-tree-sort-id-index-first-c`. Full branch name: `reviews/<slug>-pr-<PR_NUMBER>`. ```bash git fetch origin git checkout -b reviews/<slug>-pr-<PR_NUMBER> origin/<baseBranch> git push -u origin reviews/<slug>-pr-<PR_NUMBER> ``` Retarget the contributor's PR: ```bash gh pr edit <PR_NUMBER> --base reviews/<slug>-pr-<PR_NUMBER> gh pr view <PR_NUMBER> --json baseRefName # verify ``` > ⚠️ `gh pr edit --base` may print a deprecation warning about Projects (classic). Cosmetic only — the base change succeeds. Merge the contributor's PR into the review branch: ```bash gh pr merge <PR_NUMBER> --<strategy> ``` Pull and create the finalization PR back to the original base: ```bash git checkout reviews/<slug>-pr-<PR_NUMBER> git pull origin reviews/<slug>-pr-<PR_NUMBER> gh pr create \ --base <baseBranch> \ --head reviews/<slug>-pr-<PR_NUMBER> \ --title "<original title> [reviewed]" \ --body "Finalizes review of @<author>'s contribution in #<PR_NUMBER>. Original PR: <PR_URL>" ``` Comment on the original PR: ```bash gh pr comment <PR_NUMBER> \ --body "Thanks for the contribution! Review continues in #<NEW_PR_NUMBER> where maintainer changes are finalized before merging to \`<baseBranch>\`." ``` ## Merge Strategy Reference | Strategy | When to use | | ---------- | -------------------------------------------------------------------------------------------------------------------- | | `--squash` | Default for messy/multi-commit external PRs. One revert undoes the change. Contributor still gets authorship credit. | | `--merge` | Large feature where individual commits are meaningful and worth preserving. | | `--rebase` | Single clean commit, or a series of clean atomic commits you want linear on the base. | ## Hard Rules - **Never** hardcode `main` as the base — always read `baseRefName`. - **Never** create a `reviews/` branch in Phase 1. - **Never** force-push to a contributor's branch. - If the PR is a **draft**, refuse to merge and report it back to the maintainer. - If `mergeable == "CONFLICTING"` or `mergeStateStatus != "CLEAN"`, stop and surface that before any merge command. ## Summary | Phase | What happens | Output | | ----- | ---------------------------------------------------------- | --------------------------- | | 1 | Read PR metadata, derive push capability + recommendations | Triage report | | 2 | Ask Q1 (path) and Q2 (merge strategy) | Decision | | 3 | Execute the chosen path with the chosen merge strategy | Merged PR / finalization PR |
在 GitHub 查看