diff --git a/.github/workflows/gemini-review.yml b/.github/workflows/gemini-review.yml new file mode 100644 index 0000000..3f8ba65 --- /dev/null +++ b/.github/workflows/gemini-review.yml @@ -0,0 +1,100 @@ +name: Gemini Code Reviewer + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: read + pull-requests: write + +jobs: + review: + runs-on: ubuntu-latest + env: + GEMINI_CLI_TRUST_WORKSPACE: "true" + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get PR Diff + id: diff + run: | + # 親コミットとの差分を取得 + git diff origin/${{ github.base_ref }}...HEAD > pr_diff.patch + echo "has_diff=true" >> $GITHUB_OUTPUT + + - name: Run Gemini Review + id: gemini + uses: google-github-actions/run-gemini-cli@v0 + with: + gemini_api_key: ${{ secrets.GEMINI_API_KEY }} + prompt: | + あなたは極めて優秀なシニアエンジニアです。 + 以下の git diff を分析し、問題のある箇所に対して行単位のレビューを行ってください。 + + 【出力フォーマット】 + 必ず以下の JSON 配列形式のみで出力してください(Markdownの装飾コードブロックを含めないでください)。 + 指摘がない場合は空配列 `[]` を返してください。 + + [ + { + "path": "ファイルパス", + "line": 変更後の該当行番号(整数), + "body": "指摘内容(1. 潜在的なバグ 2. 改善案)" + } + ] + + 【対象 Diff】 + $(cat pr_diff.patch) + + - name: Post Inline Review Comments + uses: actions/github-script@v7 + env: + GEMINI_RESPONSE: ${{ steps.gemini.outputs.response }} + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const rawResponse = process.env.GEMINI_RESPONSE || "[]"; + + // JSONのパース処理(```json などのコードブロックが含まれていた場合のクリーニング) + let cleaned = rawResponse.trim(); + if (cleaned.startsWith("```")) { + cleaned = cleaned.replace(/^```[a-z]*\n?/, "").replace(/\n?```$/, ""); + } + + let comments = []; + try { + comments = JSON.parse(cleaned); + } catch (e) { + console.error("JSONのパースに失敗しました:", e); + console.log("生レスポンス:", rawResponse); + return; + } + + if (!Array.isArray(comments) || comments.length === 0) { + console.log("指摘事項はありませんでした。"); + return; + } + + // GitHub Review APIを使ってインラインコメントを投稿 + const reviewComments = comments.map(c => ({ + path: c.path, + line: Number(c.line), + body: `🤖 **Gemini Review**\n\n${c.body}` + })); + + try { + await github.rest.pulls.createReview({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + event: 'COMMENT', + comments: reviewComments + }); + console.log(`${reviewComments.length} 件のインラインコメントを投稿しました。`); + } catch (error) { + console.error("レビューコメントの投稿に失敗しました:", error); + } \ No newline at end of file