| name | check-pr |
| description | Dùng khi user runs `/check-pr` hoặc nói 'check PR', 'verify CI', 'kiểm tra PR', 'ready to merge?'. Monitor CI via scripts (`scripts/check-ci.sh`), run local E2E + unit tests if Docker / JAVA_HOME available, output verdict (✅ ready / ❌ fix needed / ⚠️ conditional). |
| user-invocable | true |
| argument-hint | [PR-number|branch-name] |
/check-pr — Monitor CI & Verify PR Quality
Usage
/check-pr 207 # Check PR #207
/check-pr wave/3 # Check branch wave/3
/check-pr # Check current branch
Rules
- MCP-first — dùng GitHub MCP nếu connected (
claude mcp list), gh CLI làm fallback. Chi tiết: .claude/rules/mcp-first-with-fallback.md
- LUÔN dùng scripts — không chạy
gh run list trực tiếp nếu có script
- E2E verify ở local — Docker phải up, chạy
./scripts/test-api-e2e.sh
- CI monitor bằng script hoặc MCP — GitHub MCP
list_workflow_runs hoặc bash scripts/check-ci.sh [branch]
- Cleanup bằng script —
bash scripts/cleanup-ci-runs.sh
Step 1: Identify Target
PR_NUMBER=$ARGUMENTS
BRANCH=$(gh pr view $PR_NUMBER --json headRefName --jq '.headRefName')
BRANCH=$ARGUMENTS
BRANCH=$(git branch --show-current)
Step 2: Monitor CI (bằng script)
bash scripts/check-ci.sh $BRANCH
bash scripts/check-ci.sh $BRANCH 15
Script location: scripts/check-ci.sh
Behavior: Poll mỗi 15s, hiển thị status, exit 0 nếu all pass, exit 1 nếu fail.
Lưu ý: Script check TẤT CẢ runs trên branch (kể cả cũ). Nếu có failure cũ → check timestamp để phân biệt.
Step 3: Analyze Failures (nếu CI fail)
FAILED_RUN=$(gh run list --branch $BRANCH --limit 5 \
--json databaseId,workflowName,conclusion \
--jq '.[] | select(.conclusion=="failure") | .databaseId' | head -1)
gh run view $FAILED_RUN --log-failed 2>/dev/null | tail -30
gh run view $FAILED_RUN --log-failed 2>/dev/null \
| grep -E "ERROR|FAIL|Compilation|cannot find|Tests run.*Failures: [1-9]|Tests run.*Errors: [1-9]" \
| head -10
Step 4: Local Verification (TRƯỚC khi merge)
4a. E2E Tests (nếu Docker running)
cd kitehub && ./scripts/status.sh --health 2>/dev/null
./scripts/wait-for-healthy.sh
./scripts/test-api-e2e.sh
4b. Unit Tests (nếu JAVA_HOME available)
cd kitehub && JAVA_HOME=/home/vkiet/jdk/jdk-21 ./mvnw clean test -pl kitehub-subscription -am -q
cd kiteclass/kiteclass-core && JAVA_HOME=/home/vkiet/jdk/jdk-21 ./mvnw clean test -q
4c. Frontend Build
cd kitehub/kitehub-frontend && pnpm build
cd kiteclass/kiteclass-frontend && pnpm build
Note: Nếu không thể chạy local → ghi nhận và rely on CI. KHÔNG block merge vì thiếu local test — CI là minimum.
Step 5: Output Report
## PR Check Report: #[number] ([branch])
### CI Status
- [ ] All workflows: ✅/❌ (via `scripts/check-ci.sh`)
- Failed: [list if any]
### Local Verification
- [ ] E2E tests: ✅/❌/⏭️ skipped (Docker: up/down)
- [ ] Unit tests: ✅/❌/⏭️ skipped (JAVA_HOME: set/unset)
- [ ] Frontend build: ✅/❌/⏭️ skipped
### Issues Found
[Any failures with root cause]
### Verdict
✅ Ready to merge
❌ Fix needed: [description]
⚠️ Conditional: CI pass but local not verified
Step 6: Merge (CHỈ khi verdict = ✅)
KHÔNG merge nếu verdict = ❌ hoặc ⚠️ chưa resolve.
6a. Phân biệt merge target
User nói "merge" → merge agent PRs vào WAVE BRANCH
User nói "merge wave → main" hoặc "merge vào main" → merge wave → main
KHÔNG BAO GIỜ tự suy diễn merge vào main
6b. Xác nhận user approve
LUÔN hỏi trước khi merge:
- PR → wave: "Merge 4 PRs vào wave/X?"
- Wave → main: "Wave check pass. Merge wave/X → main?"
- KHÔNG tự merge bất kỳ thứ gì mà không có confirm rõ ràng.
6c. Merge command
gh pr merge [number] --squash --delete-branch
gh pr merge [number] --squash --delete-branch
git checkout main && git pull
gh pr merge [number] --squash --delete-branch
6d. VIOLATION LOG (Wave 4, 2026-03-24)
User nói "merge" → agent merge cả wave/4 → main mà không hỏi.
Đúng ra: chỉ merge 4 PRs vào wave/4, rồi HỎI user trước khi wave/4 → main.
6c. Verify sau merge
git checkout [target-branch] && git pull
bash scripts/check-ci.sh [target-branch] 3
Step 7: Cleanup (sau merge)
git remote prune origin
rm -rf .claude/worktrees/agent-* 2>/dev/null
git worktree prune
echo "Stale branches:" && git branch -r | grep -v "main\|HEAD\|wave/" | wc -l
echo "Open PRs:" && gh pr list --state open --json number --jq 'length'
Integration với Wave Process
Per PR: /check-pr [PR-number] ← Sau agent tạo PR
Wave: /check-pr wave/X ← Sau merge tất cả PRs vào wave
Main: /check-pr main ← Sau merge wave → main
Full: /wave-completion-check [X] ← 6-level check
Gotchas
gh pr checks --json state returns null — use scripts/check-ci.sh or --json status instead; raw state field breaks polling loops silently (memory feedback_monitor_gh_pr_checks_no_state_field.md)
- Step 2 script picks up STALE failures —
scripts/check-ci.sh shows ALL runs on the branch including ancient ones; cross-check timestamps before declaring "CI red" (per Step 2 note in body)
- Stacked PR
--delete-branch trap — merging a stacked PR with --delete-branch auto-closes child PRs and they cannot be reopened (memory feedback_stacked_pr_delete_branch.md); for stacks merge parent without --delete-branch first, then re-target child
- "merge" never auto-promotes wave → main — Step 6 is explicit but easy to skip: user saying "merge" means agent PRs → wave branch ONLY; wave → main requires separate explicit confirmation (Wave 4 violation 2026-03-24 logged in §6d)
- Local skip ≠ block — if Docker down or
JAVA_HOME unset, mark E2E/unit ⏭️ skipped and rely on CI; verdict can still be ✅ Ready (per Step 4 note); do NOT downgrade to ❌ just because local couldn't run