From 51672daa8819048895af28b1808c8832766188ba Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Fri, 13 Feb 2026 10:03:13 +0900 Subject: [PATCH 1/4] Add pr-review job to pull-request workflow Co-authored-by: Cursor --- .github/workflows/pull-request.yml | 56 ++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index b569b28..aabb1fd 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -59,3 +59,59 @@ jobs: - uses: actions/checkout@v3 - name: REUSE Compliance Check uses: fsfe/reuse-action@v1 + + pr-review: + runs-on: ubuntu-latest + continue-on-error: true + permissions: + contents: read + pull-requests: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Get diff + id: diff + run: | + git diff "${{ github.event.pull_request.base.sha }}" "${{ github.event.pull_request.head.sha }}" -- . > diff.txt + echo "size=$(wc -c < diff.txt)" >> $GITHUB_OUTPUT + - name: Skip if no code change + id: skip + run: | + if [ "${{ steps.diff.outputs.size }}" -lt 5 ]; then + echo "skip=true" >> $GITHUB_OUTPUT + else + echo "skip=false" >> $GITHUB_OUTPUT + fi + - name: Request review from service + id: review + if: steps.skip.outputs.skip != 'true' + env: + SERVICE_URL: ${{ secrets.PR_REVIEW_SERVICE_URL }} + run: | + echo '{"pr_title": ${{ toJSON(github.event.pull_request.title) }}, "pr_body": ${{ toJSON(github.event.pull_request.body) }}}' > meta.json + jq -n --rawfile diff diff.txt --slurpfile m meta.json '$m[0] + {diff: $diff}' > payload.json + BODY=$(curl -sf --max-time 660 -X POST "${SERVICE_URL}/review" \ + -H "Content-Type: application/json" \ + -d @payload.json \ + | jq -r .body) || true + echo "## πŸ€– LLM 리뷰 μš”μ•½" > review_body.md + echo "" >> review_body.md + echo "${BODY:-리뷰 생성에 μ‹€νŒ¨ν–ˆκ±°λ‚˜ 응닡이 λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€.}" >> review_body.md + - name: Post review comment + if: steps.skip.outputs.skip != 'true' && success() + uses: peter-evans/create-or-update-comment@v4 + with: + token: ${{ secrets.TOKEN || secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + body-path: review_body.md + edit-mode: replace + - name: Comment when no code change + if: steps.skip.outputs.skip == 'true' + uses: peter-evans/create-or-update-comment@v4 + with: + token: ${{ secrets.TOKEN || secrets.GITHUB_TOKEN }} + issue-number: ${{ github.event.pull_request.number }} + body: "## πŸ€– LLM 리뷰 μš”μ•½\n\n이 PRμ—λŠ” 리뷰할 μ½”λ“œ 변경이 μ—†μŠ΅λ‹ˆλ‹€." + edit-mode: replace From da55b8d39cfa4025357f80dc005f258ed2b3e904 Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Fri, 13 Feb 2026 11:25:44 +0900 Subject: [PATCH 2/4] Add error message --- .github/workflows/pull-request.yml | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index aabb1fd..1dafae3 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -92,13 +92,27 @@ jobs: run: | echo '{"pr_title": ${{ toJSON(github.event.pull_request.title) }}, "pr_body": ${{ toJSON(github.event.pull_request.body) }}}' > meta.json jq -n --rawfile diff diff.txt --slurpfile m meta.json '$m[0] + {diff: $diff}' > payload.json - BODY=$(curl -sf --max-time 660 -X POST "${SERVICE_URL}/review" \ + RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 660 -X POST "${SERVICE_URL}/review" \ -H "Content-Type: application/json" \ - -d @payload.json \ - | jq -r .body) || true + -d @payload.json) || true + HTTP_BODY=$(echo "$RESPONSE" | head -n -1) + HTTP_CODE=$(echo "$RESPONSE" | tail -n 1) + BODY=$(echo "$HTTP_BODY" | jq -r '.body // empty' 2>/dev/null) + ERR_MSG=$(echo "$HTTP_BODY" | jq -r '.error // .message // .detail // empty' 2>/dev/null) echo "## πŸ€– LLM 리뷰 μš”μ•½" > review_body.md echo "" >> review_body.md - echo "${BODY:-리뷰 생성에 μ‹€νŒ¨ν–ˆκ±°λ‚˜ 응닡이 λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€.}" >> review_body.md + if [ -n "$BODY" ]; then + echo "$BODY" >> review_body.md + else + echo "리뷰 생성에 μ‹€νŒ¨ν–ˆκ±°λ‚˜ 응닡이 λΉ„μ–΄ μžˆμŠ΅λ‹ˆλ‹€." >> review_body.md + if [ -n "$ERR_MSG" ]; then + echo "" >> review_body.md + echo "**μ—λŸ¬ λ©”μ‹œμ§€:** $ERR_MSG" >> review_body.md + elif [ -n "$HTTP_CODE" ] && [ "$HTTP_CODE" -ge 400 ]; then + echo "" >> review_body.md + echo "**HTTP μƒνƒœ:** $HTTP_CODE" >> review_body.md + fi + fi - name: Post review comment if: steps.skip.outputs.skip != 'true' && success() uses: peter-evans/create-or-update-comment@v4 From 9a59817f8f1b84271fb982c413cf4d90984b1cc8 Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Fri, 13 Feb 2026 11:44:22 +0900 Subject: [PATCH 3/4] =?UTF-8?q?ci(pr-review):=20timeout=2015=EB=B6=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .github/workflows/pull-request.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 1dafae3..469f5b9 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -87,12 +87,13 @@ jobs: - name: Request review from service id: review if: steps.skip.outputs.skip != 'true' + timeout-minutes: 15 env: SERVICE_URL: ${{ secrets.PR_REVIEW_SERVICE_URL }} run: | echo '{"pr_title": ${{ toJSON(github.event.pull_request.title) }}, "pr_body": ${{ toJSON(github.event.pull_request.body) }}}' > meta.json jq -n --rawfile diff diff.txt --slurpfile m meta.json '$m[0] + {diff: $diff}' > payload.json - RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 660 -X POST "${SERVICE_URL}/review" \ + RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 900 -X POST "${SERVICE_URL}/review" \ -H "Content-Type: application/json" \ -d @payload.json) || true HTTP_BODY=$(echo "$RESPONSE" | head -n -1) From 2a5d6d817ff15ae0e35ca0e23111b928d924207e Mon Sep 17 00:00:00 2001 From: Soim Kim Date: Fri, 13 Feb 2026 13:49:01 +0900 Subject: [PATCH 4/4] =?UTF-8?q?ci(pr-review):=20timeout=20=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=20=EC=99=84=ED=99=94=20(=EC=8A=A4=ED=85=9D=206?= =?UTF-8?q?=EC=8B=9C=EA=B0=84,=20curl=20=EC=A0=9C=ED=95=9C=20=EC=97=86?= =?UTF-8?q?=EC=9D=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- .github/workflows/pull-request.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 469f5b9..d6e10dd 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -87,13 +87,13 @@ jobs: - name: Request review from service id: review if: steps.skip.outputs.skip != 'true' - timeout-minutes: 15 + timeout-minutes: 360 env: SERVICE_URL: ${{ secrets.PR_REVIEW_SERVICE_URL }} run: | echo '{"pr_title": ${{ toJSON(github.event.pull_request.title) }}, "pr_body": ${{ toJSON(github.event.pull_request.body) }}}' > meta.json jq -n --rawfile diff diff.txt --slurpfile m meta.json '$m[0] + {diff: $diff}' > payload.json - RESPONSE=$(curl -s -w "\n%{http_code}" --max-time 900 -X POST "${SERVICE_URL}/review" \ + RESPONSE=$(curl -s -w "\n%{http_code}" -X POST "${SERVICE_URL}/review" \ -H "Content-Type: application/json" \ -d @payload.json) || true HTTP_BODY=$(echo "$RESPONSE" | head -n -1)