-
Notifications
You must be signed in to change notification settings - Fork 0
ci: PR 생성 시 codex/claude 자동 코드리뷰 워크플로우 추가 #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| export PATH="$HOME/.local/bin:$PATH" | ||
|
|
||
| REVIEW_FILE="/tmp/claude-review-${PR_NUMBER}.json" | ||
|
|
||
| PROMPT_FILE=$(mktemp /tmp/claude-review-prompt.XXXXXX.txt) | ||
| trap 'rm -f "$PROMPT_FILE"' EXIT | ||
|
|
||
| cat > "$PROMPT_FILE" <<PROMPT_EOF | ||
| You are reviewing PR #${PR_NUMBER} in the sandbox-load-test repository. | ||
|
|
||
| Steps: | ||
| 1. Read ALL CLAUDE.md/AGENTS.md files to understand project conventions. | ||
| 2. Run: git diff origin/${BASE_REF}...HEAD --name-only (get changed files) | ||
| 3. Run: git diff origin/${BASE_REF}...HEAD (get the full diff with line numbers) | ||
| 4. Read the changed files to understand context. | ||
| 5. Write a thorough code review in Korean. | ||
|
|
||
| 6. Write the review to ${REVIEW_FILE} in this exact JSON format. | ||
| The 'body' field must use this exact markdown structure: | ||
|
|
||
| { | ||
| "body": "## 🤖 eottabom-claude-review\n\n### 📊 종합 평가\n\n| 항목 | 평가 |\n|------|------|\n| ✅ Correctness | <가능 / 불가 + 한 줄 이유> |\n| 🔁 Regression Risk | <🔴 매우 높음 / 🟡 보통 / 🟢 낮음 + 한 줄 이유> |\n| ⚠️ Risky Changes | <있음: 내용 요약 / 없음> |\n| 🧪 Missing Tests | <있음: 내용 요약 / 없음> |\n\n### 📝 상세 리뷰\n\n<상세 리뷰 내용을 마크다운으로 작성. 파일명, 라인, 근거를 구체적으로>", | ||
| "event": "COMMENT", | ||
| "comments": [ | ||
| { | ||
| "path": "relative/path/to/file.java", | ||
| "line": <line number in the new version of the file>, | ||
| "side": "RIGHT", | ||
| "body": "<specific inline comment in Korean>" | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| 7. Post the review: | ||
| gh api /repos/eottabom/sandbox-load-test/pulls/${PR_NUMBER}/reviews --method POST --input ${REVIEW_FILE} | ||
|
|
||
| Rules: | ||
| - Only add inline comments on lines that exist in the diff (added or changed lines on the RIGHT side). | ||
| - The 'line' must be the actual line number in the current file, not the diff position. | ||
| - If there are no specific inline findings, use an empty array for 'comments'. | ||
| - If there are no findings at all, still post a summary saying so. | ||
| - Write everything in Korean. | ||
| PROMPT_EOF | ||
|
|
||
| claude --dangerously-skip-permissions --verbose --output-format stream-json < "$PROMPT_FILE" | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| export PATH="$HOME/.local/bin:$PATH" | ||
| : "${RUNNER_WORKDIR:?RUNNER_WORKDIR env var must be set}" | ||
|
|
||
| REVIEW_FILE="/tmp/codex-review-${PR_NUMBER}.json" | ||
|
|
||
| PROMPT_FILE=$(mktemp /tmp/codex-review-prompt.XXXXXX.txt) | ||
| trap 'rm -f "$PROMPT_FILE"' EXIT | ||
|
|
||
| cat > "$PROMPT_FILE" <<PROMPT_EOF | ||
| You are reviewing PR #${PR_NUMBER} in the sandbox-load-test repository. | ||
|
|
||
| Steps: | ||
| 1. Read all AGENTS.md/CLAUDE.md files to understand project conventions. | ||
| 2. Run: git diff origin/${BASE_REF}...HEAD --name-only (get changed files) | ||
| 3. Run: git diff origin/${BASE_REF}...HEAD (get the full diff with line numbers) | ||
| 4. Read the changed files to understand context. | ||
| 5. Write a thorough code review in Korean. | ||
|
|
||
| 6. Write the review to ${REVIEW_FILE} in this exact JSON format. | ||
| The 'body' field must use this exact markdown structure: | ||
| { | ||
| "body": "## 🤖 eottabom-codex-review\n\n### 📊 종합 평가\n\n| 항목 | 평가 |\n|------|------|\n| ✅ Correctness | <가능 / 불가 + 한 줄 이유> |\n| 🔁 Regression Risk | <🔴 매우 높음 / 🟡 보통 / 🟢 낮음 + 한 줄 이유> |\n| ⚠️ Risky Changes | <있음: 내용 요약 / 없음> |\n| 🧪 Missing Tests | <있음: 내용 요약 / 없음> |\n\n### 📝 상세 리뷰\n\n<상세 리뷰 내용을 마크다운으로 작성. 파일명, 라인, 근거를 구체적으로>", | ||
| "event": "COMMENT", | ||
| "comments": [ | ||
| { | ||
| "path": "relative/path/to/file.java", | ||
| "line": <line number in the new version of the file>, | ||
| "side": "RIGHT", | ||
| "body": "<specific inline comment in Korean>" | ||
| } | ||
| ] | ||
| } | ||
|
|
||
| 7. Post the review: | ||
| gh api /repos/eottabom/sandbox-load-test/pulls/${PR_NUMBER}/reviews --method POST --input ${REVIEW_FILE} | ||
|
|
||
| Rules: | ||
| - Only add inline comments on lines that exist in the diff (added or changed lines on the RIGHT side). | ||
| - The 'line' must be the actual line number in the current file, not the diff position. | ||
| - If there are no specific inline findings, use an empty array for 'comments'. | ||
| - If there are no findings at all, still post a summary saying so. | ||
| - Write everything in Korean. | ||
| PROMPT_EOF | ||
|
|
||
| codex exec \ | ||
| -C "$RUNNER_WORKDIR" \ | ||
| --dangerously-bypass-approvals-and-sandbox \ | ||
| - < "$PROMPT_FILE" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,136 @@ | ||
| name: 🤖 PR Auto Review | ||
|
|
||
| on: | ||
| pull_request: | ||
| types: [opened, ready_for_review] | ||
|
|
||
| permissions: | ||
| contents: read | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| claude-review: | ||
| if: | | ||
| github.event.pull_request.draft == false && | ||
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association) | ||
| timeout-minutes: 30 | ||
| concurrency: | ||
| group: claude-review-pr-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
| runs-on: [self-hosted, macOS, X64] | ||
| env: | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| BASE_REF: ${{ github.event.pull_request.base.ref }} | ||
|
|
||
| defaults: | ||
| run: | ||
| working-directory: ${{ vars.RUNNER_WORKDIR }} | ||
|
|
||
| steps: | ||
| - name: Checkout PR head | ||
| env: | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| run: | | ||
| git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/eottabom/sandbox-load-test.git" | ||
| git fetch origin "refs/pull/${PR_NUMBER}/head" | ||
| git checkout --detach FETCH_HEAD | ||
| git reset --hard FETCH_HEAD | ||
| test "$(git rev-parse HEAD)" = "$HEAD_SHA" | ||
| git remote set-url origin "https://github.com/eottabom/sandbox-load-test.git" | ||
|
|
||
| - name: Check Claude login status | ||
| id: claude_auth | ||
| env: | ||
| HOME: ${{ vars.RUNNER_HOME }} | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| export PATH="$HOME/.local/bin:$PATH" | ||
| if claude auth status 2>/dev/null | jq -e '.loggedIn == true' >/dev/null; then | ||
| echo "logged_in=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "logged_in=false" >> "$GITHUB_OUTPUT" | ||
| gh pr comment "$PR_NUMBER" --repo eottabom/sandbox-load-test --body "⚠️ **eottabom-review-bot** self-hosted 러너의 \`claude\` CLI 로그인 세션이 만료되어 자동 리뷰를 실행할 수 없습니다. 러너 머신에서 \`claude /login\`으로 재로그인해 주세요." | ||
| fi | ||
|
|
||
| - name: Run Claude review | ||
| if: steps.claude_auth.outputs.logged_in == 'true' | ||
| env: | ||
| HOME: ${{ vars.RUNNER_HOME }} | ||
| CI: "" | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| unset CI | ||
| unset GITHUB_ACTIONS | ||
| unset GITHUB_TOKEN | ||
| set +e | ||
| set -o pipefail | ||
| bash "${{ vars.RUNNER_WORKDIR }}/.github/scripts/claude-review-run.sh" 2>&1 | \ | ||
| jq --unbuffered -r ' | ||
| if .type == "assistant" then | ||
| (.message.content // [])[] | | ||
| if .type == "text" then .text | ||
| elif .type == "tool_use" then "[tool:\(.name)] \(.input | tostring | .[0:200])" | ||
| else empty end | ||
| elif .type == "tool_result" then | ||
| " → \((.content // [])[] | select(.type == "text") | .text | .[0:300])" | ||
| elif .type == "result" then | ||
| "\n=== \(.subtype) ===" | ||
| else empty end | ||
| ' 2>/dev/null | ||
| rc="${PIPESTATUS[0]}" | ||
| set -e | ||
| exit "$rc" | ||
|
|
||
| codex-review: | ||
| if: | | ||
| github.event.pull_request.draft == false && | ||
| contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.pull_request.author_association) | ||
| timeout-minutes: 30 | ||
| concurrency: | ||
| group: codex-review-pr-${{ github.event.pull_request.number }} | ||
| cancel-in-progress: true | ||
| runs-on: [self-hosted, macOS, X64] | ||
| env: | ||
| PR_NUMBER: ${{ github.event.pull_request.number }} | ||
| BASE_REF: ${{ github.event.pull_request.base.ref }} | ||
|
|
||
| defaults: | ||
| run: | ||
| working-directory: ${{ vars.RUNNER_WORKDIR }} | ||
|
|
||
| steps: | ||
| - name: Checkout PR head | ||
| env: | ||
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | ||
| run: | | ||
| git remote set-url origin "https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/eottabom/sandbox-load-test.git" | ||
| git fetch origin "refs/pull/${PR_NUMBER}/head" | ||
| git checkout --detach FETCH_HEAD | ||
| git reset --hard FETCH_HEAD | ||
| test "$(git rev-parse HEAD)" = "$HEAD_SHA" | ||
| git remote set-url origin "https://github.com/eottabom/sandbox-load-test.git" | ||
|
|
||
| - name: Check Codex login status | ||
| id: codex_auth | ||
| env: | ||
| HOME: ${{ vars.RUNNER_HOME }} | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| run: | | ||
| export PATH="$HOME/.local/bin:$PATH" | ||
| if codex login status 2>/dev/null | grep -qi "logged in"; then | ||
| echo "logged_in=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "logged_in=false" >> "$GITHUB_OUTPUT" | ||
| gh pr comment "$PR_NUMBER" --repo eottabom/sandbox-load-test --body "⚠️ **eottabom-review-bot** self-hosted 러너의 \`codex\` CLI 로그인 세션이 만료되어 자동 리뷰를 실행할 수 없습니다. 러너 머신에서 \`codex login\`으로 재로그인해 주세요." | ||
| fi | ||
|
|
||
| - name: Run Codex review | ||
| if: steps.codex_auth.outputs.logged_in == 'true' | ||
| env: | ||
| HOME: ${{ vars.RUNNER_HOME }} | ||
| CI: "" | ||
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||
| RUNNER_WORKDIR: ${{ vars.RUNNER_WORKDIR }} | ||
| run: | | ||
| unset CI | ||
| bash "${{ vars.RUNNER_WORKDIR }}/.github/scripts/codex-review-run.sh" |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.