GitLab MR レビューコメントへの対応
概要
GitLab MR 上のインラインレビューコメントは、ディスカッション(ファイルと行に紐づいたスレッド)として存在します。取得(位置情報の取得)→修正→返信→解決までの一連の処理は glab api を通じて実行します。このスキルは実証済みのコマンドシーケンスを提供します。注意点として、一見適切に見えるコマンド (glab mr view --comments) はコメントのテキストを取得できますが、ファイルや行の位置情報が含まれないため、各コメントが何を指しているかを特定できません。
必須の背景知識: 判断部分には superpowers:receiving-code-review を使用します。各コメントを技術的に厳密に評価し、修正を適用する前にそのコメントが正しいことを確認してください。このスキルは GitLab の操作手順のみをカバーします。
セットアップ
MR=511 # MR の iid
PROJ="<group>%2F<subgroup>%2F<project>" # URLエンコードされたフルパス
API="projects/$PROJ/merge_requests/$MR"
パスを URL エンコードします (/ → %2F)。不明な場合は glab repo view で確認できます。
1. 位置情報を含むコメントを取得する
glab mr view $MR --comments は行番号を含まないため、インラインコメントには使用しないでください。Discussions API を叩き、position をパースします。--paginate は必須です。このエンドポイントは1ページあたり20スレッドを返し、--paginate なしだと残りのスレッドがエラーもなく破棄されます。既に解決済みのスレッドはスキップします:
glab api --paginate --output ndjson "$API/discussions" | python3 -c '
import sys, json
for line in sys.stdin:
d = json.loads(line)
n = d["notes"][0]
if n.get("system") or n.get("resolved"): continue
p = n.get("position") or {}
print(d["id"], "|", n["author"]["username"], "|", n["body"])
if p: print(" ->", p.get("new_path"), "new_line:", p.get("new_line"), "old_line:", p.get("old_line"))
'
new_line= 現在の(変更後の)ファイルの行 → コメントを解釈する際に参照する行です。- 変更された行に対するコメントには
old_lineとnew_lineの両方が含まれます。new_path+new_lineを基準にしてください。 positionがない → 一般(インラインではない)コメントです。
2. 各 new_path:new_line のコードを読み、修正する
指定された行のファイルを開き、コメントが文脈の中で意味をなすようにします。評価した後でのみ修正を適用してください(receiving-code-review を参照)。1つのレビュー修正コミットとしてコミットし、プッシュします:
git add <files>
git commit -m "fix(<scope>): <内容> のレビューに対応" # Conventional Commits、チケットIDは本文に
git fetch origin <target> && git rebase origin/<target>
git push --force-with-lease # リベースが何も変更しなかった場合のみ、通常の `git push` で十分
3. 各スレッドに返信し、解決する
ディスカッションの notes エンドポイントに投稿すると、自動的にスレッドに返信されます(in_reply_to_id は不要です)。その後、PUT で resolved=true を設定します:
DISC="<手順1で取得したディスカッションID>"
glab api -X POST "$API/discussions/$DISC/notes" -f "body=対応しました: <変更内容>."
glab api -X PUT "$API/discussions/$DISC?resolved=true"
glab をシェル関数でラップしないでください。パーミッションの許可ルールはリテラルコマンドのみに一致するため、各スレッドに対して両方の呼び出しを完全な形で記述してください。
返信の作成
変更内容とその理由のみに留めてください。レビュワーが知りたいのは差分であり、調査プロセスではありません。
- 修正を適用した場合: 1〜2文。変更内容、対象行以外に広げた変更、コミットSHA。
対応しました。ブロックスタイルをすべてのコンポーネントに適用しました(この行だけでなく6つすべて)。レンダリング結果に変更はありません。f6511f29 - 異議がある場合、または判断を先送りする場合: 最初に決定的な事実、次に選択肢、最後にレビュワーに判断を委ねます。最大でも2つの短い段落に収めてください。余談、3つ目の補足的な主張、「議論を歓迎します」といった結びは削除してください。
- 自分自身の修正の経緯を説明したり、レビュワーのコメントをそのまま繰り返したりしないでください。
解決するスレッド
実際に対応を完了したスレッドのみを解決してください。
- 変更を適用した場合 → 返信 + 解決。
- 質問に回答し、その回答で決着がついた場合 → 返信 + 解決。
- 自分では決定できない事項(ターゲット環境、スコープ、優先度)→ 返信するが、解決しないでください。レビュワーがまだ判断する必要があるスレッドを解決すると、軽く扱っていると受け取られ、レビュワーのレビューリストから外れてしまいます。
クイックリファレンス
| 手順 | コマンド |
|---|---|
| インラインコメントとその位置を一覧表示 | glab api --paginate --output ndjson "$API/discussions" → .notes[].position.{new_path,new_line,old_line} をパース |
| スレッドに返信 | glab api -X POST "$API/discussions/<id>/notes" -f "body=..." |
| スレッドを解決 | glab api -X PUT "$API/discussions/<id>?resolved=true" |
よくある間違い
- インラインコメントに
glab mr view --commentsを使用する: テキストのみでファイル/行が得られず、コメントの位置を特定できません。Discussions API を使用してください。 - 存在しない
glab mr note resolveをでっち上げる: 解決はglab api -X PUT ".../discussions/<id>?resolved=true"で行います。 new_lineではなくold_lineを読む: 変更行へのコメントの場合、現在のコードはnew_lineにあります。--paginateを忘れる: 20スレッドを超えると、Discussions API は最初のページのみを返し、残りは静かに破棄されます。- リベース後の単なる
--force:--force-with-leaseを使用してください。これにより、レビュワーがその間にプッシュしたコミットが上書きされるのを防ぎます。 - コメントを盲目的に適用する: まず評価してください(receiving-code-review)。実際に変更した内容を返信し、その後解決します。
- スレッド一覧表示時にディスカッションIDを切り詰める: API は完全な40文字のIDを必要とします。8文字のプレフィックスでは
404 Discussion Not Foundが返されます。d["id"]をそのまま出力してください。 - 返信で過剰に説明する: 「返信の作成」を参照してください。説明は MR の説明やチケットに記述すべきです。
- 先送りにした判断を解決する: レビュワーがまだ選択する必要がある場合は、スレッドを開いたままにしてください。