Skip to content

Commit 43d75b8

Browse files
authored
Merge pull request #765 from 2chanhaeng/get-switch
Add `get-reviews` agent skill
2 parents 667c8bf + d5acf08 commit 43d75b8

3 files changed

Lines changed: 430 additions & 0 deletions

File tree

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
---
2+
name: get-reviews
3+
description: >-
4+
This skill is utilized when fetching reviews from GitHub pull requests.
5+
Get the reviews, organize, and help to resolve them.
6+
argument-hint: "Provide the number of the pull request to get the reviews."
7+
---
8+
9+
<!-- deno-fmt-ignore-file -->
10+
11+
Get reviews from GitHub pull requests
12+
=====================================
13+
14+
This skill is utilized when requesting reviews from GitHub pull requests.
15+
16+
1. Get the reviews.
17+
2. Organize the reviews.
18+
3. Help to resolve the reviews.
19+
20+
21+
Get the reviews
22+
---------------
23+
24+
To get the reviews from a GitHub pull request, you can use the GitHub API.
25+
Check the [`gh` CLI tool][gh] is installed and authenticated.
26+
`gh auth status` can be used to check the authentication status.
27+
If `gh` isn't installed, try installing it by `apt install gh`.
28+
If authentication is not set up, tell the contributor to run `gh auth login`
29+
to authenticate with GitHub.
30+
31+
Use the GraphQL API to fetch the reviews for a specific pull request.
32+
Check [fetch\_reviews.sh](./fetch_reviews.sh) to fetch the reviews
33+
and save them in a JSON file:
34+
35+
- Fill the variables in the command and run the command to fetch the reviews:
36+
37+
~~~~ bash
38+
# Omit the new lines
39+
PR_NUMBER= NUMBER_OF_PR_COMMENTS= NUMBER_OF_REVIEWS= \
40+
NUMBER_OF_THREADS= NUMBER_OF_COMMENTS_PER_THREAD= LAST_CURSOR= \
41+
bash .agents/skills/get-reviews/fetch_reviews.sh
42+
~~~~
43+
44+
45+
- `PR_NUMBER`: The number of the pull request to fetch reviews from.
46+
- `NUMBER_OF_PR_COMMENTS`: The number of PR comments to fetch.
47+
- `NUMBER_OF_REVIEWS`: The number of reviews to fetch.
48+
- `NUMBER_OF_THREADS`: The number of review threads to fetch.
49+
- `NUMBER_OF_COMMENTS_PER_THREAD`:
50+
The number of comments per review thread to fetch.
51+
- `LAST_CURSOR`: The cursor for incremental fetches. Optional.
52+
53+
- For incremental fetches, save `pageInfo.endCursor` from the previous
54+
fetch and pass it as `after: $LAST_CURSOR` (a base64 cursor, not a
55+
review thread node ID) so the query returns only new review threads.
56+
57+
- Use `jq` to filter the reviews and information if necessary.
58+
59+
The fetched JSON files in *plans/{PR\_NUMBER}/fetched/* contain the raw data
60+
of PR comments, reviews, and review threads (with `pullRequestReview`
61+
back-references on thread comments). When more context is needed later
62+
(e.g., to resolve which review a thread belongs to, or to check the original
63+
body of a comment), refer back to these files instead of re-fetching.
64+
65+
[gh]: https://cli.github.com/
66+
67+
68+
Organize the reviews
69+
--------------------
70+
71+
After fetching the PR and its reviews, organize the reviews.
72+
[*plans* directory in the root](../../../plans/) is a good place to store them.
73+
*plans/* is already ignored in `.gitignore`, so don't check that it is ignored.
74+
75+
- *plans/{PR\_NUMBER}/index.md*: The main file for the PR.
76+
- The body of the PR
77+
- *plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}.md*: The file for each review
78+
which is not resolved.
79+
- After applying or dismissing the review, move the file to
80+
*plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*.
81+
- If the review file is too long, move the content to
82+
*plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/index.md*, and separate the
83+
content into multiple files in the same directory. In this case, after
84+
resolving the review, move the whole directory to
85+
*plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}/*.
86+
- *plans/{PR\_NUMBER}/reviews/resolved/{REVIEW\_ID}.md*: The file for each
87+
review which is resolved.
88+
89+
**Don't use the first comment of the review thread as the review ID.**
90+
The ID of the review thread starts with “PRRT\_”.
91+
Use the first comment ID of the review thread only on the link.
92+
93+
Review threads aren't the only place that asks for changes. A PR-level
94+
comment (in `comments` of the fetched JSON, whose ID starts with “IC\_”)
95+
or the body of a review (in `reviews` of the fetched JSON, whose ID starts
96+
with “PRR\_”) can also point out things to fix. When such a comment or
97+
review body requests modifications, organize it as its own review file
98+
alongside the review-thread files, using the same directory layout and
99+
naming rules:
100+
101+
- Use the node ID of the PR comment (“IC\_…”) or the review (“PRR\_…”)
102+
as the `{REVIEW\_ID}` in the file path.
103+
- If a PR comment or review body only contains approval, general
104+
impressions, questions without a modification request, or other content
105+
with nothing to fix, skip it and do not create a file for it.
106+
- If only a part of a longer PR comment or review body requests changes,
107+
create a file only for that request and quote the relevant excerpt in
108+
the file so the context is preserved.
109+
110+
The format of review files should be as [review.md](./review.md).
111+
Read the review and draft the format based on the relevant information.
112+
The files should be written in the contributor's language. But the title of
113+
the item in the file (e.g., “Summary”, “Judgement”, “Plans”) should be in
114+
English for consistency.
115+
116+
Empty the space between the “Title” and the “Summary” sections.
117+
118+
All related information with the review should be stored in
119+
*plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}.md* or the files in
120+
*plans/{PR\_NUMBER}/reviews/{REVIEW\_ID}/*.
121+
122+
After organizing the reviews, show the links to the files to the contributor.
123+
124+
125+
Help to resolve the reviews
126+
---------------------------
127+
128+
The agent's role in this step is to *help* the contributor resolve the reviews,
129+
not to resolve them on the agent's own authority. The final judgement always
130+
belongs to the contributor; the agent's job is to surface the information needed
131+
to decide, and then to carry out whatever the contributor decides.
132+
133+
For each unresolved review, give the contributor what they need to judge it,
134+
rather than judging on their behalf:
135+
136+
- Add relative links to the code or documentation the review points at.
137+
- Summarize the relevant facts, the trade-offs, and any available options.
138+
- Where the facts are clear, the agent may include a *suggested* judgement,
139+
but it must be clearly marked as a suggestion and never substitute for the
140+
contributor's decision.
141+
142+
Let the contributor read the review files, decide the judgement and the plans
143+
for each review, and update the review files if necessary. Do not apply or
144+
dismiss anything until the contributor has decided. After the contributor
145+
decides the judgement and the plans, apply or dismiss the reviews based on the
146+
files.
147+
148+
Categorize the reviews and the plans, and apply them at once by category.
149+
After applying the review, use [`/commit` skill](../commit/SKILL.md) to commit
150+
the changes. The commit message should include the related review links:
151+
152+
`https://github.com/fedify-dev/fedify/pull/{PR_NUMBER}#discussion_r{REVIEW_THREAD.COMMENTS[0].DATABASE_ID}`
153+
154+
Because these changes are produced with agent assistance, the commit message
155+
must also carry the `Assisted-by: AGENT_NAME:MODEL_VERSION` trailer required by
156+
[*AI_POLICY.md*](../../../AI_POLICY.md), in addition to the review links.
157+
158+
After committing the changes, update the review file to include the commit hash
159+
and the comment section. If the review is dismissed, update the review file to
160+
include the reason for dismissing and the comment section.
161+
162+
If the `Comments` are written only in the contributor's language, provide an
163+
English translation and have the contributor review it. If they are written in
164+
both languages, check for any discrepancies between the two. If differences
165+
exist between the two versions, review them based on the facts and revise
166+
the English version to match the content in the contributor's language.
167+
168+
Post all review comments in English, even if the file written in the
169+
contributor's native language. The comments should be polite and constructive.
170+
171+
Before pushing commits, posting comments, or marking any review as resolved,
172+
the contributor must verify the actual applied changes and the relevant
173+
test/check results (e.g., `mise run check` and the related tests). Per
174+
[*AI_POLICY.md*](../../../AI_POLICY.md), AI-created work must be fully verified
175+
with human use; do not post comments or mark reviews resolved for changes whose
176+
correctness is only hypothetical. The agent prepares everything for this
177+
verification but leaves the verification itself to the contributor.
178+
179+
After resolving the reviews, pushing commits, posting comments, and updating
180+
the reviews as resolved, move the review files to
181+
*plans/{PR\_NUMBER}/reviews/resolved*. Before moving the files, check status and
182+
comments of the PR from GitHub. Use [fetch\_reviews.sh](./fetch_reviews.sh),
183+
but instead of fetching all reviews and attributes, fetch only the necessary
184+
attributes to check the review status and comments.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
: "${PR_NUMBER:?PR_NUMBER is required}"
5+
: "${NUMBER_OF_PR_COMMENTS:?NUMBER_OF_PR_COMMENTS is required}"
6+
: "${NUMBER_OF_REVIEWS:?NUMBER_OF_REVIEWS is required}"
7+
: "${NUMBER_OF_THREADS:?NUMBER_OF_THREADS is required}"
8+
: "${NUMBER_OF_COMMENTS_PER_THREAD:?NUMBER_OF_COMMENTS_PER_THREAD is required}"
9+
10+
PR_PATH="plans/$PR_NUMBER"
11+
FETCHED_PATH="$PR_PATH/fetched"
12+
mkdir -p "$FETCHED_PATH"
13+
TIMESTAMP=$(date +"%m%d%H%M")
14+
FETCHED_FILE="$FETCHED_PATH/$TIMESTAMP.json"
15+
gh api graphql -f query='query(
16+
$owner: String!,
17+
$repo: String!,
18+
$number: Int!,
19+
$prComments: Int!,
20+
$reviews: Int!,
21+
$threads: Int!,
22+
$comments: Int!,
23+
$after: String
24+
) {
25+
repository(owner: $owner, name: $repo) {
26+
pullRequest(number: $number) {
27+
comments(first: $prComments) {
28+
nodes {
29+
id
30+
databaseId
31+
author { login }
32+
body
33+
url
34+
createdAt
35+
}
36+
}
37+
reviews(first: $reviews) {
38+
nodes {
39+
id
40+
databaseId
41+
author { login }
42+
body
43+
state
44+
url
45+
createdAt
46+
}
47+
}
48+
reviewThreads(first: $threads, after: $after) {
49+
pageInfo {
50+
hasNextPage
51+
endCursor
52+
}
53+
nodes {
54+
id
55+
isResolved
56+
isOutdated
57+
path
58+
line
59+
comments(first: $comments) {
60+
nodes {
61+
id
62+
databaseId
63+
author { login }
64+
body
65+
url
66+
createdAt
67+
pullRequestReview {
68+
id
69+
databaseId
70+
}
71+
}
72+
}
73+
}
74+
}
75+
}
76+
}
77+
}' \
78+
-F owner=fedify-dev \
79+
-F repo=fedify \
80+
-F number="$PR_NUMBER" \
81+
-F prComments="$NUMBER_OF_PR_COMMENTS" \
82+
-F reviews="$NUMBER_OF_REVIEWS" \
83+
-F threads="$NUMBER_OF_THREADS" \
84+
-F comments="$NUMBER_OF_COMMENTS_PER_THREAD" \
85+
${LAST_CURSOR:+-F after="$LAST_CURSOR"} \
86+
| jq . > "$FETCHED_FILE"
87+
88+
echo "Fetched reviews and comments are saved to $FETCHED_FILE"

0 commit comments

Comments
 (0)