Imported from YAPP-Github/28th-Web-Team-3-FE (
.agents/skills/pr-create/SKILL.md). Install upstream withnpx skills add YAPP-Github/28th-Web-Team-3-FE --skill pr-create. Copyright stays with the author.
name: pr-create description: ์ฝ๋ ๋น๋ยทํ ์คํธ โ AI ๋ฆฌ๋ทฐ โ ํธ์ โ GitHub PR ์์ฑ๊น์ง ํ๋ฒ์ ์ฒ๋ฆฌ. "pr-create", "PR ๋ง๋ค์ด์ค", "๋ฆฌ๋ทฐํ๊ณ PR", "๋ฐฐํฌ ์ค๋น" ๋ฑ์ ์์ฒญ์ ์ฌ์ฉ. develop/main ๋ธ๋์น๋ก ๋จธ์งํ๋ PR์ ์ด ์คํฌ๋ก ์์ฑํ ๊ฒ. "์ฝ๋ฑ์คํํ ๊ตฌํ์ํค๊ณ PR", "codex dev" ๋ฑ ๊ตฌํ ์์ฒด๋ฅผ Codex์ ๋งก๊ธฐ๋ ์์ฒญ๋ ์ด ์คํฌ(๊ฐ๋ฐ ์์ ๋ชจ๋)๋ก ์ฒ๋ฆฌํ๋ค. argument-hint: [๋ธ๋์น] [๋ฆฌ๋ทฐ์ด] [--codex-dev "<์์ ์ค๋ช >"]
๋น๋ยทํ
์คํธ(vitest โ Playwright) โ next16-rn AI ๋ฆฌ๋ทฐ โ ํธ์ โ PR ์์ฑ์ ํ๋ฒ์ ์ฒ๋ฆฌํ๋ค.
develop -> main PR์ ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ก ์ฒ๋ฆฌํ๋ค.
์
ธ ์คํฌ๋ฆฝํธ ์์ โ ๊ฐ ๋จ๊ณ๋ฅผ ๋๊ตฌ ํธ์ถ๋ก ์คํํ๋ค.
์ธ์
$0: PR์ ์ฌ๋ฆด ๋ธ๋์น(head). ์๋ต ์ ํ์ฌ ๋ธ๋์น ์ฌ์ฉ.$1: ๋ฆฌ๋ทฐ์ด ์ด๋ฆ/ํธ๋ค (ํ๊ธยท์๋ฌธ). ์์ผ๋ฉด ํ์ ์๋ ์ง์ ๊ท์น(Step 7 ์ฐธ๊ณ ) ์ ์ฉ, ๊ทธ๋๋ ๋ชป ์ ํ๋ฉด ์ฌ์ฉ์์๊ฒ ๋ฌผ์ด๋ณผ ๊ฒ.
๋ฆด๋ฆฌ์ฆ ๋ชจ๋ (develop -> main)
head=develop, base=main์ธ PR์ ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ค. ์ฌ์ฉ์๊ฐ "dev -> main", "develop -> main",
"main ๋ฐฐํฌ PR", "๋ฆด๋ฆฌ์ฆ PR"์ฒ๋ผ ์์ฒญํ๋ฉด ์ด ๋ชจ๋๋ก ์งํํ๋ค.
- ๋ฒ ์ด์ค๋
main, ํค๋๋develop์ผ๋ก ๊ณ ์ ํ๋ค. ์์ ๋ฆด๋ฆฌ์ฆ ๋ธ๋์น๋ฅผ ๋ง๋ค์ง ์๋๋ค. - PR ์ ๋ชฉ์
release: vX.Y.Zํ์์ผ๋ก ํ๋ค. vX.Y.Z๋ ํ์ฌ ์ต์ tag๋ฅผ ํ์ธํ ๋ค ์ฌ์ฉ์์๊ฒ ์ ์ํ๋ค. ์๋ ๊ฒฐ์ ๊ธฐ์ค์ ๋ค์ ์์๋ค:- breaking change ๋๋ ๋ง์ด๊ทธ๋ ์ด์ ์ด ์์ผ๋ฉด major
feat์ปค๋ฐ์ด ์์ผ๋ฉด minor- ๊ทธ ์ธ
fix/perf/chore/docs/ci๋ฑ์ patch
- ์ต์ tag๊ฐ ์์ผ๋ฉด
v0.1.0์ ์ ์ํ๋ค. ์ด๋ฏธapps/native/app.config.ts์version์ฒ๋ผ ์ฑ ๋ฒ์ ์ด ๋ ํฌ๋ฉด ๊ทธ ๋ฒ์ ์ ์ฐ์ ์ ์ํ๋ค. - release note๋
git log origin/main..origin/develop --oneline๊ณผ diff๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๊ตญ์ด bullet๋ก ์์ฑํ๊ณ , PR ๋ณธ๋ฌธ## ๐ฌ ๊ธฐํ ์ฝ๋ฉํธ์ ์๋ ํ์์ผ๋ก ๋ฃ๋๋ค. - merge ํ tag๋ PR merge commit ๋๋ main์ merge ๊ฒฐ๊ณผ ์ปค๋ฐ์
vX.Y.Z๋ก ์์ฑํ๋ค. PR ์์ฑ ๋จ๊ณ์์๋ tag๋ฅผ ๋ง๋ค์ง ์๊ณ , PR ๋ณธ๋ฌธ์Merge ํ tag: vX.Y.Z๋ฅผ ๋ช ์ํ๋ค. - Expo/WebView ํ์ธ์ release note์ ํฌํจํ๋ค:
apps/native/.env.production์EXPO_PUBLIC_WEB_URL์ด Vercel production URL์ธ์ง ํ์ธapps/native/.env.production์EXPO_PUBLIC_API_URL์ด/api/๊น์ง ํฌํจํ๋์ง ํ์ธ- EAS production ํ๊ฒฝ์ ๋ฐ์ํ ๋ช
๋ น:
cd apps/native && eas env:push production --path .env.production
๋ฆด๋ฆฌ์ฆ PR์ ## ๐ฌ ๊ธฐํ ์ฝ๋ฉํธ ํ์:
### Release Notes
- <์ฌ์ฉ์ ์ํฅ์ด ์๋ ๋ณ๊ฒฝ>
- <๋ฒ๊ทธ ์์ ๋๋ ๋ด๋ถ ๊ฐ์ >
### Release Checklist
- [ ] Vercel production ๋ฐฐํฌ URL ํ์ธ: `<EXPO_PUBLIC_WEB_URL>`
- [ ] EAS production env ๋ฐ์: `cd apps/native && eas env:push production --path .env.production`
- [ ] WebView production URL smoke test
- [ ] Merge ํ tag ์์ฑ: `vX.Y.Z`
๊ฐ๋ฐ ์์ ๋ชจ๋ (Codex ๊ตฌํ โ Claude ๋ฆฌ๋ทฐ)
๊ธฐ๋ณธ ํ๋ฆ์ Claude๊ฐ ์ด๋ฏธ ๋ง๋ diff๋ฅผ ๊ฒ์ดํธยท๋ฆฌ๋ทฐ(Claude + Codex ๊ต์ฐจ)ยทPR๋ก ์ด์ด๊ฐ๋ค. ์ด ๋ชจ๋๋ ๊ทธ
๋ฐ๋๋ค โ Codex๊ฐ ๊ตฌํํ๊ณ , Claude๊ฐ ๋
๋ฆฝ์ ์ผ๋ก ๋ฆฌ๋ทฐํ๋ค. ๊ตฌํ ์์ฒด๋ฅผ Codex์ ๋งก๊ธฐ๊ณ ์ถ์ ๋ ์ด๋ค
("์ฝ๋ฑ์คํํ
์์ผ", "์ฝ๋ฑ์ค๋ก ๊ตฌํํด์ค", "opus ๋ง๊ณ codex๋ก", --codex-dev ์ธ์ ๋ฑ).
- ์ด ๋ชจ๋๋ Step 1๊ณผ Step 2 ์ฌ์ด(Step 1.5)์์๋ง ๋์ํ๋ค. ๋ธ๋์น๋ฅผ ๋จผ์ ํ์ ํด์ผ Codex์ ๋ณ๊ฒฝ์ด ์ฌ๋ฐ๋ฅธ ๋ธ๋์น์ ์์ธ๋ค.
- Step 5์ Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ๋ ์ด ๋ชจ๋์์ ์๋ตํ๋ค. Codex๊ฐ ์ด ์ฝ๋๋ฅผ Codex๊ฐ ๋ค์ ๋ณด๋ ๊ฑด ์ ๋ณด๊ฐ
์๋ค โ ์ด ๋ชจ๋์ ์กด์ฌ ์ด์ ์์ฒด๊ฐ Claude์ ๋
๋ฆฝ๋ ๋์ด๋ค.
next16-rn-reviewer๋ง ๋์คํจ์นํ๋ค. - PR ๋ณธ๋ฌธ์
## ๐ค AI ๋ฆฌ๋ทฐ์ ๋ชฉ์### Claude ๋ฆฌ๋ทฐ (Codex ๊ตฌํ)์ผ๋ก ๋ฐ๊ฟ ๊ตฌํยท๋ฆฌ๋ทฐ ์ฃผ์ฒด๋ฅผ ๋ช ์ํ๋ค. - ๊ทธ ์ธ Step 2~8(๋ํฐ ํธ๋ฆฌ ๊ฒ์ดํธ๋ถํฐ PR ์์ฑ๊น์ง)์ ๊ธฐ๋ณธ ํ๋ฆ๊ณผ ๋์ผํ๋ค โ Codex๊ฐ ๋ง๋ diff๋ ๋๊ฐ์ด ๋น๋ยทํ ์คํธ ๊ฒ์ดํธ๋ฅผ ํต๊ณผํด์ผ ํ๊ณ , ๐ด ๋ฆฌ๋ทฐ๋ฉด ๋๊ฐ์ด ๋ฉ์ถ๋ค.
Step 1.5: Codex์ ๊ตฌํ ์์ (์ด ๋ชจ๋์ผ ๋๋ง)
- ์ฌ์ฉ์๊ฐ ์ค ์์
์ค๋ช
์ ๊ทธ๋๋ก Task ๋๊ตฌ๋ก
codex:codex-rescue์๋ธ์์ด์ ํธ์ ์ ๋ฌํ๋ค. foreground๋ก ์คํํ ๊ฒ โ ์ดํ ๊ฒ์ดํธ๊ฐ Codex์ diff๋ฅผ ํ์๋ก ํ๋ฏ๋ก ์๋ฃ๋ฅผ ๊ธฐ๋ค๋ ค์ผ ํ๋ค (๋ฐฑ๊ทธ๋ผ์ด๋๋ก ๋์ง๊ณ ๋ค์ Step์ผ๋ก ๋์ด๊ฐ์ง ๋ง ๊ฒ). --write๋ codex-rescue ๊ธฐ๋ณธ๊ฐ์ด๋ผ ๋ฐ๋ก ์ง์ ํ์ง ์๋๋ค.--effortยท--model์ ์ฌ์ฉ์๊ฐ ๋ช ์ํ์ง ์๋ ํ ๋น์ ์ฝ๋ฑ์ค ๊ธฐ๋ณธ๊ฐ์ ์ด๋ค.- Codex ์์ ์ด ๋๋๋ฉด ์ํนํธ๋ฆฌ์ diff๊ฐ ์๊ธด๋ค. ๊ทธ๋๋ก Step 2(๋ํฐ ํธ๋ฆฌ ๊ฒ์ดํธ)๋ก ์งํ โ ๊ทธ diff๊ฐ ๊ณง Step 2๊ฐ ํ์ธํ "์ปค๋ฐ ์ ๋ ๋ณ๊ฒฝ"์ด๋ค.
- Codex๊ฐ ์๋ฌด ๋ณ๊ฒฝ๋ ๋ง๋ค์ง ์์๊ฑฐ๋(์ด๋ฏธ ๋ง์กฑํ๋ ์ํ ๋ฑ) ์คํจ๋ฅผ ๋ณด๊ณ ํ๋ฉด ์ฌ์ฉ์์๊ฒ ๊ทธ๋๋ก ์๋ฆฌ๊ณ ์ค๋จํ๋ค โ ๋น diff๋ก ๊ฒ์ดํธ๋ฅผ ํต๊ณผ์ํค์ง ์๋๋ค.
๊ฐ์ ์ฌ์ฉ ๊ท์น
develop๋๋main์ผ๋ก ๋จธ์งํ๋ PR์ ์ด ์คํฌ๋ก ์์ฑํ ๊ฒ.- ์ฌ์ฉ์๊ฐ ์ง์
git push+ PR ์๋ ์์ฑ์ ์์ฒญํด๋ ์ด ์คํฌ ์ฌ์ฉ์ ๊ถ์ฅํ ๊ฒ. - ๋น๋ยทํ ์คํธ ๊ฒ์ดํธ๊ฐ ๋นจ๊ฐ์์ด๋ฉด ์ ๋ PR์ ์์ฑ/์์ ํ์ง ์์ ๊ฒ.
- ํธ์ยทPR ์์ฑ ์ ๋ฐ๋์ ์ฌ์ฉ์ ์น์ธ์ ๋ฐ์ ๊ฒ.
์คํ ์ ์ฐจ
Step 0: GitHub CLI ํ์ธ (ํ์)
which gh๋ก ์ค์น ์ฌ๋ถ ํ์ธ.- ๋ฏธ์ค์น ์ ์ฆ์ ์ค๋จํ๊ณ ์๋ ์๋ด ํ์:
โ ๏ธ GitHub CLI(gh)๊ฐ ์ค์น๋์ด ์์ง ์์ต๋๋ค. ์ค์น ํ ๋ค์ ์๋ํด์ฃผ์ธ์.
[Mac] brew install gh
[Windows] winget install GitHub.cli ๋๋ scoop install gh
[์ค์น ํ ์ธ์ฆ]
gh auth login
gh auth status๋ก ์ธ์ฆ ์ํ ํ์ธ.- ๋ฏธ์ธ์ฆ ์
gh auth login์๋ด ํ ์ฆ์ ์ค๋จ. - ์ค์นยท์ธ์ฆ์ด ์๋ฃ๋์ง ์์ผ๋ฉด ์ดํ ๋จ๊ณ๋ก ์ ๋ ์งํํ์ง ์์ ๊ฒ.
- ์ปจํ
์คํธ ํ๋ณด:
- ๋ ํฌ =
gh repo view --json nameWithOwner -q .nameWithOwner - ํ์ฌ ๋ก๊ทธ์ธ =
gh api user -q .loginโME๋ก ์ ์ฅ (assignee ๋ฐ ๋ฆฌ๋ทฐ์ด ์ ์ธ์ฉ) - ๋ฒ ์ด์ค = ์ผ๋ฐ PR์
develop(.github/PULL_REQUEST_TEMPLATE.md๊ธฐ์ค), ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋main. ์๊ฒฉ์ ์์ผ๋ฉดgh repo view --json defaultBranchRef -q .defaultBranchRef.name๋ก ํด๋ฐฑ.
- ๋ ํฌ =
Step 1: ๋ธ๋์น ํ์
$0์ด ์ฃผ์ด์ก์ผ๋ฉด ๊ทธ๋๋ก, ์์ผ๋ฉด ํ์ฌ ๋ธ๋์น ์ฌ์ฉ.git fetch origin --prune.- ๋์ ๋ธ๋์น๋ก ์ ํ(
git switch <๋ธ๋์น>, ์์ผ๋ฉดgit switch -c <๋ธ๋์น>). - ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ฉด head๊ฐ
develop, base๊ฐmain์ธ์ง ํ์ธํ๋ค. ๋ค๋ฅด๋ฉด ์ฌ์ฉ์์๊ฒ ์๋ฆฌ๊ณ ์ค๋จํ๋ค. - ๊ฐ๋ฐ ์์ ๋ชจ๋(์ฌ์ฉ์๊ฐ ๊ตฌํ์ Codex์ ๋งก๊ธฐ๋ผ๊ณ ์์ฒญ,
--codex-dev์ธ์ ๋ฑ)๋ฉด Step 1.5๋ก ๊ฐ๋ค. ์๋๋ฉด ๋ฐ๋ก Step 2.
Step 2: ๋ณ๊ฒฝ์ฌํญ ํ์ธ (๋ํฐ ํธ๋ฆฌ ๊ฒ์ดํธ)
git status --short๋ก ์ปค๋ฐ ์ ๋ ๋ณ๊ฒฝ ํ์ธ โ ์์ผ๋ฉด ์ฌ์ฉ์์๊ฒ ์๋ฆฌ๊ณ ์ค๋จ(๋จผ์ ์ปค๋ฐ/์คํ์). ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ ํนํdevelop์ํนํธ๋ฆฌ๊ฐ ๊นจ๋ํด์ผ ํ๋ค.- ํฌํจ๋ ์ปค๋ฐ ๋ชฉ๋ก:
git log origin/<base>..HEAD --oneline. - ๋ณ๊ฒฝ ํ์ผ ํ์ โ lockfile ์ ์ธ๋ก ์ปจํ ์คํธ ๊ฒฝ๋ ์ ์ง:
git diff --stat --merge-base origin/<base> HEAD -- ':!pnpm-lock.yaml' ':!package-lock.json' ':!yarn.lock'
- ๋ฒ ์ด์ค๋ณด๋ค ์์ ์ปค๋ฐ์ด ์์ผ๋ฉด ์ค๋จ โ PRํ ๊ฒ ์์.
- ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ฉด ์ต์ tag์ ๋ฒ์ ํ๋ณด๋ฅผ ํ์ธํ๋ค:
git tag --sort=-v:refname | head -20
git log origin/main..origin/develop --oneline
ํ๋ณด ๋ฒ์ ์ ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๊ณ ์น์ธ๋ฐ๋๋ค. ์น์ธ ์ PR ์ ๋ชฉ์ ๋ฒ์ ์ ํ์ ํ์ง ์๋๋ค.
Step 2.5: ๋ํ PR ๋ถํ ํ๋จ
๋ฆด๋ฆฌ์ฆ ๋ชจ๋(develop -> main)๋ ์ด ๋จ๊ณ๋ฅผ ๊ฑด๋๋ด๋ค. ๋ฆด๋ฆฌ์ฆ PR์ ๋จ์ผ develop -> main PR๋ก๋ง
์งํํ๋ฉฐ, ๋ถํ ๋ธ๋์น ์์ฑ์ด๋ cherry-pick์ ํ์ง ์๋๋ค.
- ๋ถํ ํ๋ณด ์กฐ๊ฑด(ํ๋๋ผ๋ ํด๋นํ๋ฉด ๋ถํ ๊ฒํ ):
- Step 2์์ ํ์ธํ ๋ณ๊ฒฝ ํ์ผ(lockfile ์ ์ธ) ์๊ฐ 20๊ฐ ์ด๊ณผ
git log origin/<base>..HEAD --oneline์ ์ปค๋ฐ๋ค์ด ์๋ก ๋ค๋ฅธ conventional scope์ 3๊ฐ ์ด์ ๊ฑธ์นจ (์:feat(mission),fix(onboarding),chore(ui)ํผ์ฌ)
- ํด๋นํ๋ฉด ์ปค๋ฐ์ scope ๊ธฐ์ค์ผ๋ก ๊ทธ๋ฃนํํ ๋ถํ ์์ ๋ง๋ค์ด ์ฌ์ฉ์์๊ฒ ์ ์ํ๊ณ ์น์ธ ์ฌ๋ถ๋ฅผ ๋ฌผ์ ๊ฒ(๋ง์์ด ์งํ ๊ธ์ง):
๋ณ๊ฒฝ ๊ท๋ชจ๊ฐ ํฝ๋๋ค(ํ์ผ N๊ฐ, ์ปค๋ฐ M๊ฐ, scope K๊ฐ). PR์ ๋๋ ์ ์ฌ๋ฆด๊น์? 1. <scope A> โ <ํด๋น ์ปค๋ฐ ๋ชฉ๋ก> 2. <scope B> โ <ํด๋น ์ปค๋ฐ ๋ชฉ๋ก> ... [๋ถํ ํด์ ์งํ] / [๊ทธ๋๋ก 1๊ฐ PR๋ก ์งํ] - ์ฌ์ฉ์๊ฐ ๋ถํ ์ ์ ํํ๋ฉด:
- ๊ทธ๋ฃน๋ง๋ค
<base>์์ ์ ๋ธ๋์น๋ฅผ ๋ง๋ค๊ณ (๋ธ๋์น๋ช ์ lefthook ๊ท์นtype(scope)/๋ด์ฉ์ค์) ํด๋น ๊ทธ๋ฃน ์ปค๋ฐ๋งgit cherry-pick์ผ๋ก ์ฎ๊ธด๋ค. ์๋ณธ ๋ธ๋์น๋ ๊ทธ๋๋ก ๋ณด์กด. - ๊ทธ๋ฃน๋ณ๋ก Step 3๋ถํฐ Step 8๊น์ง ๊ทธ๋ฃน๋น ํ ๋ฒ์ฉ ์์๋๋ก ๋ฐ๋ณต ์คํํ๋ค โ ํ ๊ทธ๋ฃน์ PR์ด ๋ง๋ค์ด์ง ๋ค ๋ค์ ๊ทธ๋ฃน์ผ๋ก ์งํ.
- ๋ค ๊ทธ๋ฃน์ด ์ ๊ทธ๋ฃน ์ปค๋ฐ์ ์์กดํ๋ฉด ๋ค ๊ทธ๋ฃน PR์
--base๋ฅผ ์ ๊ทธ๋ฃน์ head ๋ธ๋์น๋ก ์ง์ ํ๊ณ , PR ๋ณธ๋ฌธ(๊ธฐํ ์ฝ๋ฉํธ)์ ์์กด ๊ด๊ณ๋ฅผ ๋ช ์ํ๋ค.
- ๊ทธ๋ฃน๋ง๋ค
- ์ฌ์ฉ์๊ฐ ๊ทธ๋๋ก ์งํ์ ์ ํํ๋ฉด ๋ถํ ์์ด Step 3์ผ๋ก ์งํ.
- ์ฌ์ฉ์๊ฐ "๋ถํ ํ๋จ ์๋ต" ๋ฑ์ผ๋ก ๋ช ์์ ์ผ๋ก ๊ฑด๋๋ฐ๋ผ๊ณ ํ๋ฉด ์ด Step ์ ์ฒด๋ฅผ ์๋ตํ๋ค.
Step 3: ๋น๋ ๊ฒ์ดํธ
pnpm build(turbo). ์ข ๋ฃ ์ฝ๋ 0 ์๋๋ฉด โ ์ฆ์ ์ค๋จ, ์คํจํ turbo ํ์คํฌ ์ถ๋ ฅ ์ฒจ๋ถ.
Step 4: ํ ์คํธ ๊ฒ์ดํธ
pnpm --filter web test(vitest run). ๋ณ๊ฒฝ๋ ํจํค์ง๊ฐ ์์ผ๋ฉดpnpm --filter @repo/api --filter @repo/schema test๋ ์คํ.- ์คํจ โ ์ฆ์ ์ค๋จ, ์คํจ ํ ์คํธ ์ฒจ๋ถ.
pnpm --filter web test:e2e(Playwright). ๋ธ๋ผ์ฐ์ ์์ผ๋ฉด ๋จผ์ pnpm --filter web exec playwright install --with-deps.- ์คํจ โ ์ฆ์ ์ค๋จ, ์คํจ spec ์ฒจ๋ถ.
- ๋ ๋ค ํต๊ณผํด์ผ ๋ค์ ๋จ๊ณ.
Step 5: AI ๋ฆฌ๋ทฐ (3ยท4 ๋ชจ๋ ํต๊ณผํ ๊ฒฝ์ฐ์๋ง)
๊ฐ๋ฐ ์์ ๋ชจ๋(Step 1.5๋ฅผ ๊ฑฐ์ณค์ผ๋ฉด)์์๋ Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ๋ฅผ ์๋ตํ๊ณ next16-rn-reviewer๋ง
๋์คํจ์นํ๋ค โ Codex๊ฐ ์ด ์ฝ๋๋ฅผ Codex๊ฐ ๋ค์ ๋ฆฌ๋ทฐํ๋ ๊ฑด ์ ๋ณด๊ฐ ์๋ค. ์๋๋ ๊ธฐ๋ณธ ํ๋ฆ ๊ธฐ์ค์ด๋ค.
- ๋ฆฌ๋ทฐ ๋ ๊ฐ๋ฅผ ๋ณ๋ ฌ๋ก ๋์คํจ์น(๊ฐ๋ฐ ์์ ๋ชจ๋๋ฉด
next16-rn-reviewerํ๋๋ง). diff ๋ฒ์ (lockfile ์ ์ธ)๋ ๊ณตํต:git diff --merge-base origin/<base> HEAD -- ':!pnpm-lock.yaml' ':!package-lock.json' ':!yarn.lock'- Task ๋๊ตฌ๋ก
next16-rn-reviewer์๋ธ์์ด์ ํธ. ํ๋กฌํํธ์ head ๋ธ๋์น, ๋ฒ ์ด์ค, diff ๋ฒ์ ์ ๋ฌ. ํ๋กฌํํธ ๋์ ์ธ์ด ๊ท์น์ ๋ช ์ํ๋ค: "๋ฆฌ๋ทฐ๋ ํ๊ตญ์ด๋ก ์์ฑํ๋ ์ฝ๋ ์๋ณ์ยท๊ฒฝ๋กยทAPI ์ด๋ฆ์ ๋ชจ๋ ๋ฐฑํฑ(``)์ผ๋ก ๊ฐ์ ๊ฒ. ์์ด ๊ฐ๋ ์ ์ถ์ ๋ฒ์ญํ ์ด์ํ ๋ฒ์ญํฌ ๊ธ์ง." (์๋ธ์์ด์ ํธ๋ ๋ ๋ฆฝ ์ธ์ ์ด๋ผ ์ด ๊ท์น์ ์์๋ฐ์ง ๋ชปํ๋ฏ๋ก ๋งค๋ฒ ํ๋กฌํํธ์ ๋ฃ์ด์ผ ํ๋ค.) - Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ (๊ฐ๋ฐ ์์ ๋ชจ๋๊ฐ ์๋ ๋๋ง) โ openai-codex ํ๋ฌ๊ทธ์ธ์ด ์ค์น๋ ๊ฒฝ์ฐ์๋ง.
/codex:review๊ฐ ์ฐ๋ ๋ฆฌ๋ทฐ ์ ์ฉ companion script๋ฅผ ์คํํ๋ค(๋ฆฌ๋ทฐ๋ง ์ํ, ์ฝ๋ ์์ ๊ตฌ์กฐ์ ์ผ๋ก ๋ถ๊ฐ):node ~/.claude/plugins/cache/openai-codex/codex/*/scripts/codex-companion.mjs review --wait --base origin/<base>(๋ฒ์ ๋๋ ํฐ๋ฆฌ๋ glob์ผ๋ก ํด์ โ ์ฌ๋ฌ ๊ฐ๋ฉด ์ต์ ๋ฒ์ ์ฌ์ฉ.--waitํ์: ๊ฒ์ดํธ๋ผ์ ๋๊ธฐ ์๋ฃ ํ์.)--base origin/<base>(Step 0์์ ์ ํ ๋ฒ ์ด์ค, ๋ณดํตorigin/develop)๋ฅผ ๋ฐ๋์ ๋๊ธธ ๊ฒ. ์๋ตํ๋ฉด companion script์detectDefaultBranch()๊ฐorigin/HEAD(=main)๋ฅผ ์ก๊ณ , fallback ํ๋ณด๋mainยทmasterยทtrunk๋ฟ์ด๋ผdevelop์ ์ ๋ ์ ํ๋์ง ์๋๋ค. ๊ทธ ๊ฒฐ๊ณผ ์ด๋ฏธdevelop์ ๋จธ์ง๋ ์ฝ๋๊น์ง diff์ ๋ค์ด์ ์ด PR๊ณผ ๋ฌด๊ดํ ์ง์ ์ด ๋์จ๋ค. (codex-rescue์๋ธ์์ด์ ํธ๋ ์ฐ์ง ์๋๋ค โ ๊ทธ๊ฑด ์กฐ์ฌ/์์ ์์์ฉ, ๋ฆฌ๋ทฐ ๊ฒ์ดํธ์ฉ ์๋.) ํ๋ฌ๊ทธ์ธ์ด๋ Codex CLI๊ฐ ์์ผ๋ฉด ์๋ตํ๊ณ "Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ ์๋ต๋จ"๋ง ์๋ฆผ โ ์คํจ๋ก ์ทจ๊ธํ์ง ์๋๋ค.
- Task ๋๊ตฌ๋ก
- ๋ฆฌ๋ทฐ ๊ฒฐ๊ณผ(ํ์ + ๋ฐ๊ฒฌ ์ฌํญ) ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ํ์. ๋ ๋ฆฌ๋ทฐ๊ฐ ์คํ๋์ผ๋ฉด ์ต์ข ํ์ ์ ๋ ๋์ ์ชฝ ์ฑํ (Codex ์ถ๋ ฅ์ ํ์ ์ด๋ชจ์ง๊ฐ ์์ผ๋ฏ๋ก blockingยท์น๋ช ์ด์๊ฐ ์์ผ๋ฉด ๐ด๋ก ์ทจ๊ธ). ์ธ์ด ์ ๊ทํ: Codex๋ ์์ด๋ก ์ถ๋ ฅํ๋ฏ๋ก, ์ฌ์ฉ์์๊ฒ ๋ณด์ฌ์ฃผ๊ฑฐ๋ PR ๋ณธ๋ฌธ(Step 8)์ ๋ถ์ด๊ธฐ ์ ์ ํ๊ตญ์ด๋ก ์ฎ๊ธด๋ค โ ๋ฐ๊ฒฌ ์ฌํญ์ ์๋ฏธยท์ฌ๊ฐ๋ยทํ์ผ/๋ผ์ธ์ ๋ณด์กดํ๊ณ , ์ฝ๋ ์๋ณ์๋ ๋ฐฑํฑ์ผ๋ก ๊ฐ์ผ๋ค. ์ต์ข ์ ์ผ๋ก ๋ ๋ฆฌ๋ทฐ ๋ธ๋ก์ ์ธ์ด(ํ๊ตญ์ด)ยท์๋ณ์ ํ๊ธฐ(๋ฐฑํฑ)๊ฐ ์ผ๊ด๋๊ฒ ํ๋ค.
- ํ์ ์ ๋ฐ๋ผ:
- ๐ด ๋ณ๊ฒฝ ์์ฒญ (๋ ์ค ํ๋๋ผ๋) โ ์ฌ์ฉ์์๊ฒ ๊ฒฝ๊ณ . ๋ฉ์ถ๊ณ ๋จผ์ ๊ณ ์น ์ง, draft๋ก ์งํํ ์ง ์ง๋ฌธ. ๋ง์์ด ์งํ ๊ธ์ง.
- ๐ก ์ดํ โ ๊ฒฐ๊ณผ ๋ณด์ฌ์ฃผ๊ณ ๊ณ์ ์งํ ์ฌ๋ถ ํ์ธ.
Step 6: ํธ์ (์น์ธ ๊ฒ์ดํธ)
- ์ฌ์ฉ์์๊ฒ ํธ์ ์น์ธ์ ๋ช ์์ ์ผ๋ก ๋ฐ์ ๊ฒ. ์น์ธ ์ ํธ์ ๊ธ์ง.
- ์น์ธ ํ
git push -u origin <๋ธ๋์น>. - ์คํจ ์ ์์ธ ๋ถ์ ํ ๋ณด๊ณ .
Step 7: ๋ฆฌ๋ทฐ์ด ๊ฒ์ (assignee ์๋, ๋ณธ์ธ ์ ์ธ)
ํ ๊ณ ์ ๋ฆฌ๋ทฐ์ด: ์ด ํ๋ก์ ํธ ๊ฐ๋ฐ์๋ pbk95120, jongse7 ๋จ ๋๋ฟ์ด๋ค(๊ณ ์ , ๋ณ๋ ์์).
$1์ด ์์ผ๋ฉด GitHub API ๊ฒ์์ด๋ ์ฌ์ฉ์ ํ์ธ ์์ด ME(ํ์ฌ ๋ก๊ทธ์ธ, Step 0)๊ฐ ์๋ ๋๋จธ์ง
ํ ๋ช
์ ๋ฐ๋ก ๋ฆฌ๋ทฐ์ด๋ก ์ง์ ํ๋ค.
$1์ด ์๋ ๊ฒฝ์ฐ:ME๊ฐpbk95120์ด๋ฉด ๋ฆฌ๋ทฐ์ด =jongse7,ME๊ฐjongse7์ด๋ฉด ๋ฆฌ๋ทฐ์ด =pbk95120. ๋ฐ๋ก 4๋ฒ์ผ๋ก.$1์ด ์๋ ๊ฒฝ์ฐ, ์ค์ GitHub ๋ก๊ทธ์ธ์ผ๋ก ๋งค์นญ. ์์๋๋ก, ์ฒซ ๋งค์นญ ์ฑํ:- ํธ๋ค ์ง์ ํ์ธ:
gh api users/$1 --jq '.login'์ฑ๊ณตํ๋ฉด ๊ทธ๋๋ก ์ฌ์ฉ($1์ด ์ด๋ฏธ GitHub username์ธ ๊ฒฝ์ฐ). - ํ์
์ login ๋งค์นญ:
gh api repos/<owner>/<repo>/collaborators --jq '.[].login' --paginateโ$1๊ณผ ๋์๋ฌธ์ ๋ฌด์ ๋งค์นญ. - ์ด๋ฆ ์ ์ญ ๊ฒ์ โ ํ๊ธ ์ด๋ฆ์ URL(
?q=)์ ๋ฃ์ง ๋ง ๊ฒ(์ธ์ฝ๋ฉ ๊นจ์ง). ๋ฐ๋์-f๋ก ์ ๋ฌ:gh api -X GET search/users -f q="$1 in:name" --jq '.items[].login'(org ๋ฉค๋ฒ๊ฐ ํ ๊ฒฝ์ ๋ก ์ ๊ทผํ๋ฉด/collaborators์ ์ ๋ ๋ ์ด ๊ฒ์์์ ์กํ.) - ํ๋ณด๊ฐ ์ฌ๋ฟ์ด๋ฉด ํ๋กํ๋ก ํ์ธ:
gh api users/<login> --jq '.login+" | "+(.name//"")+" | "+(.company//"")'.
- ํธ๋ค ์ง์ ํ์ธ:
- ์ฌ๋ฌ ๋ช ๋งค์นญ โ ํ๋กํ(name/company) ๋ณด์ฌ์ฃผ๊ณ ์ฌ์ฉ์์๊ฒ ์ ํํ๊ฒ ํ ๊ฒ.
- ๋งค์นญ ์์ โ ์ฌ์ฉ์์๊ฒ ์ ํํ GitHub username์ ๋ฌผ์ ๊ฒ.
- assignee =
ME(ํ์ฌ ๋ก๊ทธ์ธ, Step 0). ์ ํด์ง ๋ฆฌ๋ทฐ์ด๊ฐME์ ๊ฐ์ผ๋ฉด โ ๊ฒฝ๊ณ ํ๊ณ ๋ฆฌ๋ทฐ์ด์์ ์ ์ธ(๋ณธ์ธ์๊ฒ ๋ฆฌ๋ทฐ ์์ฒญ ๋ถ๊ฐ), 0๋ฒ ์๋ ์ง์ ์ด์๋ค๋ฉด ์ด ์ํฉ์ ๋ฐ์ํ์ง ์์(ํญ์ ๋ฐ๋์ชฝ์ด ๋์ด). - ๋ฆฌ๋ทฐ์ด ์๋ PR์ ์์ฑํ์ง ์์ ๊ฒ โ ๋จ, ์ฌ์ฉ์๊ฐ "๋ฆฌ๋ทฐ์ด ์์ด ์์ฑํด์ค"์ฒ๋ผ ์ด ๊ท์น์ ๋ช ์์ ์ผ๋ก ์ค๋ฒ๋ผ์ด๋ํ๋ฉด ๋ฐ๋ฅผ ๊ฒ(๊ทธ ๊ฒฝ์ฐ์๋ ๋จผ์ ์คํฌ ๊ท์น์์ ํ ๋ฒ ์๋ฆฌ๊ณ ํ์ธ๋ฐ์ ๊ฒ).
Step 8: PR ์์ฑ (์น์ธ ๊ฒ์ดํธ)
.github/PULL_REQUEST_TEMPLATE.md๋ฅผ ์ฝ์ด ๊ทธ ์น์ ๊ตฌ์กฐ ๊ทธ๋๋ก ํ๋ ์ด์คํ๋๋ง ์ฑ์ด๋ค. ํ ํ๋ฆฟ์ ์๋ ์น์ ์ ๋ณธ๋ฌธ์ ์ถ๊ฐํ์ง ๋ง ๊ฒ. (ํ์ฌ ํ ํ๋ฆฟ = ์์ฝยท์ฒดํฌ๋ฆฌ์คํธยทAI ๋ฆฌ๋ทฐยท๊ธฐํ 4์น์ ) ๋ฆด๋ฆฌ์ฆ ๋ชจ๋์ release note์ release checklist๋ ํ ํ๋ฆฟ์## ๐ฌ ๊ธฐํ ์ฝ๋ฉํธ์์ ๋ฃ๋๋ค.
## ๐ ์์
๋ด์ฉ ์์ฝ
<diff ์์ฝ 2โ5 bullet(๋ฌด์์ด ์ ๋ฐ๋์๋์ง), ํ๊ตญ์ด>
- resolved #<๋ธ๋์น๋ช
/์ปค๋ฐ์์ ์ฐพ์ ์ด์ ๋ฒํธ, ์์ผ๋ฉด ์ด ์ค ์ญ์ >
## โ
์ฒดํฌ๋ฆฌ์คํธ
- [x] `develop` ๋ธ๋์น์ ์ต์ ์ฝ๋๋ฅผ `pull` ๋ฐ์๋์?
- [x] ๋น๋๊ฐ ํต๊ณผํ๋์?
- [x] vitest ํ
์คํธ๊ฐ ํต๊ณผํ๋์?
- [x] Playwright e2e๊ฐ ํต๊ณผํ๋์?
## ๐ค AI ๋ฆฌ๋ทฐ
<๊ฐ๋ฐ ์์ ๋ชจ๋๋ฉด ์ ๋ชฉ์ "### Claude ๋ฆฌ๋ทฐ (Codex ๊ตฌํ)"๋ก ์ฐ๊ณ next16-rn-reviewer ๊ฒฐ๊ณผ๋ง ๋ถ์ธ๋ค.
๊ธฐ๋ณธ ํ๋ฆ์ด๊ณ Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ๊ฐ ์คํ๋์ผ๋ฉด "### Claude (next16-rn-reviewer)" / "### Codex ๊ต์ฐจ ๋ฆฌ๋ทฐ"
์์ ๋ชฉ์ผ๋ก ๊ฐ๊ฐ ๊ตฌ๋ถ. ๋ชจ๋ ํ๊ตญ์ด๋ก, ์ฝ๋ ์๋ณ์ยทํ์ผ ๊ฒฝ๋ก๋ ๋ฐฑํฑ์ผ๋ก ๊ฐ์ผ๋ค โ Codex ์์ด ์ถ๋ ฅ์
Step 5์ ์ธ์ด ์ ๊ทํ๋ฅผ ๊ฑฐ์น ํ๊ตญ์ด ๋ฒ์ ์ ๋ถ์ธ๋ค(์์ด ์๋ฌธ ๊ทธ๋๋ก ๋ถ์ด์ง ๋ง ๊ฒ).>
## ๐ฌ ๊ธฐํ ์ฝ๋ฉํธ
<ํ์ ์์
ยท๋ฆฌ๋ทฐ์ด์๊ฒ ๋จ๊ธธ ๋ฉ๋ชจ, ์์ผ๋ฉด ๋น์. ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ฉด Release Notes/Release Checklist ํฌํจ>
- PR ์์ฑ ์ ์ฌ์ฉ์ ์น์ธ์ ๋ฐ์ ๊ฒ. ๋ณธ๋ฌธ์ ์์ ํ์ผ์ ์ฐ๊ณ
--body-file๋ก ์ ๋ฌ:
gh pr create \
--base <base> \
--head <๋ธ๋์น> \
--title "<์์ฝ์์ ๋ฝ์ ๊ฐ๊ฒฐํ ์ ๋ชฉ. ๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ฉด release: vX.Y.Z>" \
--assignee "@me" \
--reviewer "<๋งค์นญ๋ ๋ฆฌ๋ทฐ์ด login>" \
--body-file <tmp> \
[Step 5๊ฐ ๐ด์ด๊ณ ์ฌ์ฉ์๊ฐ draft ์ ํ ์ --draft]
- PR URL๊ณผ ํ ์ค ์์ฝ ์ถ๋ ฅ(๋น๋ โ / vitest โ / e2e โ / ํ์ / assignee / ๋ฆฌ๋ทฐ์ด).
์ฃผ์์ฌํญ
- gh ๋ฏธ์ค์น/๋ฏธ์ธ์ฆ ์ ์ ๋ ์งํํ์ง ์๊ณ ์๋ด ํ ์ค๋จ.
- ๋ํฐ ํธ๋ฆฌ(์ปค๋ฐ ์ ๋ ๋ณ๊ฒฝ)๋ฉด ์ค๋จ.
- ๋ณ๊ฒฝ ๊ท๋ชจ๊ฐ ํฌ๋ฉด(Step 2.5 ๊ธฐ์ค) ๋ถํ ์ฌ๋ถ๋ฅผ ๋จผ์ ๋ฌผ์ ๊ฒ โ ๋ง์์ด ์งํ ๊ธ์ง.
- ๋น๋/ํ ์คํธ ๊ฒ์ดํธ๊ฐ ๋นจ๊ฐ์ด๋ฉด PR ์์ฑ ๊ธ์ง.
- ํธ์ยทPR ์์ฑ ์ ๋ฐ๋์ ์ฌ์ฉ์ ์น์ธ.
- diff๋ lockfile ์ ์ธ(
:!pnpm-lock.yaml:!package-lock.json:!yarn.lock). - assignee๋ ๋ณธ์ธ(
@me), ๋ฆฌ๋ทฐ์ด ๋ชฉ๋ก์์ ๋ณธ์ธ ์ ์ธ. - pnpm ์ฌ์ฉ(npm/yarn ๊ธ์ง).
- PR ์ ๋ชฉ์ ์ปค๋ฐ ์ปจ๋ฒค์
prefix(feat/fix/chore ๋ฑ) ์์ด, subject๋ ํ๊ธ/์๋ฌธ ๋ชจ๋ ๊ฐ๋ฅ, 50์ ์ด๋ด.
๋ฆด๋ฆฌ์ฆ ๋ชจ๋๋ ์์ธ์ ์ผ๋ก
release: vX.Y.Zํ์์ ์ฌ์ฉํ๋ค. - ๋ฆฌ๋ทฐ์ด ์๋ PR์ ์์ฑํ์ง ์์ ๊ฒ(์ฌ์ฉ์์ ๋ช ์์ ์ค๋ฒ๋ผ์ด๋๊ฐ ์์ผ๋ฉด ์์ธ, Step 7.5 ์ฐธ๊ณ ).
