diff --git a/.claude/commands/issue.md b/.claude/commands/issue.md new file mode 100644 index 0000000..b4c5645 --- /dev/null +++ b/.claude/commands/issue.md @@ -0,0 +1,83 @@ +--- +description: AI-SIP/OnO_BACKEND 리포지토리에 GitHub 이슈를 생성한다. 텍스트 설명 또는 파일 경로를 받아 템플릿에 맞게 이슈를 작성한다. +argument-hint: "<이슈 설명 또는 파일 경로>" +--- + +# /issue — GitHub 이슈 생성 + +## 입력: $ARGUMENTS + +## 단계 + +### 1. 입력 파악 +- `$ARGUMENTS`가 존재하는 파일 경로이면 해당 파일을 읽어 내용을 이슈 소스로 사용한다. +- 파일 경로가 아니면 텍스트 그대로를 이슈 소스로 사용한다. +- 인자가 없으면 사용자에게 이슈 내용을 물어본다. + +### 2. 이슈 유형 판단 +입력 내용을 분석해 다음 중 하나로 분류한다: + +| 유형 | 사용 템플릿 | labels | 제목 prefix | +|---|---|---|---| +| 버그·오류·에러·crash·NPE | Bug Report Template | `bug` | `[bug]` | +| 기능 추가·신규 개발 | Common Issue Template | `feature` | `[feat]` | +| 리팩터·코드 정리 | Common Issue Template | `refactor` | `[refactor]` | +| 설정·환경·의존성·chore | Common Issue Template | `chore` | `[chore]` | +| 성능 개선 | Common Issue Template | `performance` | `[perf]` | +| 문서·주석 | Common Issue Template | `documentation` | `[docs]` | +| 테스트 | Common Issue Template | `test` | `[test]` | +| 기타·불명확 | Common Issue Template | (없음) | `[chore]` | + +### 3. 템플릿 채우기 + +**Bug Report Template** (버그 유형): +``` +## ⚙️ 어떤 버그인가요? +[버그 핵심 요약 — 1~2문장] + +### 스크린샷(선택) +[입력에 첨부 이미지·로그가 있으면 삽입, 없으면 섹션 생략] + +## 🔎 어떤 상황에서 발생한 버그인가요? +**Given** — [사전 조건] +**When** — [행동] +**Then** — [실제 결과 / 오류] + +## ✅ 예상 결과 +[정상적으로 동작해야 하는 결과] +``` + +**Common Issue Template** (그 외): +``` +## 📝 Description +[작업에 대한 간략한 설명] + +## ✅ TODO +- [ ] [할 일 1] +- [ ] [할 일 2] +(입력에서 구체적인 작업 항목을 추출해 체크리스트로 작성) + +## 💡 ETC (선택) +[기타 참고 사항, 고려할 점, 논의 필요 사항 — 없으면 섹션 생략] +``` + +### 4. 이슈 생성 전 미리보기 확인 +이슈를 생성하기 전에 다음 항목을 사용자에게 보여주고 확인한다: +- **제목**: 결정된 제목 +- **Labels**: 결정된 레이블 +- **본문 미리보기**: 작성된 본문 전체 + +사용자가 수정을 요청하면 반영한 뒤 재확인한다. 승인하면 5단계로 진행한다. + +### 5. GitHub 이슈 생성 +`mcp__github__issue_write` 도구를 사용해 이슈를 생성한다: +- `owner`: `AI-SIP` +- `repo`: `OnO_BACKEND` +- `method`: `create` +- `title`: 3단계에서 결정한 제목 +- `body`: 3단계에서 작성한 본문 +- `assignees`: `["KiSeungMin"]` (항상 고정) +- `labels`: 2단계에서 결정한 레이블 배열 + +### 6. 결과 보고 +생성된 이슈 URL을 사용자에게 알린다. \ No newline at end of file diff --git a/.claude/commands/pr.md b/.claude/commands/pr.md index 3a3c12c..7a93a81 100644 --- a/.claude/commands/pr.md +++ b/.claude/commands/pr.md @@ -1,17 +1,140 @@ --- -description: PR 제목과 본문 초안 작성. 기준 커밋부터 현재까지의 변경사항을 PR 템플릿에 맞춰 정리. -argument-hint: "<기준 커밋 해시>" +description: 현재 브랜치의 개발 내역을 develop 브랜치로 merge 요청하는 GitHub PR 생성. +argument-hint: "<추가 설명 (선택)>" --- -# /pr — PR 초안 +# /pr — GitHub PR 생성 (→ develop) -## 기준: $ARGUMENTS +## 추가 설명: $ARGUMENTS + +## 주의사항 + +> ⚠️ **main 브랜치로는 절대 PR을 생성하지 않는다.** main merge는 프로덕션 자동 배포로 이어지므로 항상 사용자가 직접 수행한다. +> 이 명령어는 현재 브랜치 → `develop` PR만 생성한다. + +--- ## 단계 -1. **변경 범위 확인** — `<커밋>..HEAD`의 커밋 로그와 diff를 확인한다. 인자가 없으면 현재 작업 트리 변경사항을 대상으로 한다. -2. **미커밋 변경 확인** — `git status`로 아직 커밋되지 않은 변경사항을 확인하고, PR 본문 반영 여부를 명시한다. -3. **템플릿 확인** — `.github/PULL_REQUEST_TEMPLATE.md`를 읽고 같은 구조로 작성한다. -4. **영향 범위 정리** — 사용자 영향, API 호환성, DB migration, 인증/권한, 알림/외부 발송, 배포 리스크를 확인한다. -5. **검증 결과 정리** — 실행한 테스트/빌드 명령과 결과, 실행하지 못한 검증과 남은 리스크를 적는다. -6. **저장 위치 확인** — 기능 문서 폴더가 명확하면 같은 위치에 PR markdown을 저장하고, 불명확하면 사용자에게 확인한다. +### 1. 브랜치 상태 확인 +- `git branch --show-current`로 현재 브랜치 이름 확인 +- 현재 브랜치가 `main` 또는 `develop`이면 **즉시 중단**하고 작업 브랜치에서 실행해야 한다고 알린다 +- `git log develop..HEAD --oneline`으로 develop 대비 커밋 목록 확인 +- `git diff develop...HEAD`로 변경 내용 파악 +- `git status`로 미커밋 변경사항 확인 (있으면 사용자에게 명시) +- 원격에 push 여부 확인 (`git log origin/$(git branch --show-current)..HEAD 2>/dev/null`로 미push 커밋 확인) + +### 2. 변경 내용 분석 +커밋 로그와 diff를 바탕으로 다음을 파악한다: +- **작업 유형**: feat / fix / refactor / chore / perf / docs / test (복수 가능) +- **영향 범위**: 어떤 패키지·API·DB 스키마가 바뀌었는지 +- **연관 이슈 후보 추출**: 커밋 메시지와 브랜치명에서 이슈 번호 또는 키워드를 추출한다 + - 브랜치명 패턴: `feat/123-login` → 번호 `123`, 키워드 `login` + - 커밋 메시지 패턴: `close #123`, `fix #123`, `resolve #123` → 번호 `123` + - 번호가 없으면 작업 내용을 요약한 키워드를 추출한다 + +### 2-1. GitHub에서 연관 이슈 검색 +`mcp__github__.list_issues`를 사용해 `AI-SIP/OnO_BACKEND` 리포지토리의 **open 상태** 이슈를 검색한다: +- 2단계에서 추출한 이슈 번호나 키워드를 open issue의 번호, 제목, 본문과 비교한다 +- 검색 결과 중 이번 PR 작업과 연관성이 높은 이슈를 골라 연관 이슈 목록을 확정한다 +- PR에서 실제로 해결되는 이슈만 `close #이슈번호`로 연결한다 +- 단순 참고 이슈는 자동 종료되지 않도록 `close` 없이 참고 문장으로만 작성한다 +- 연관 이슈를 찾지 못하면 "없음"으로 처리한다 + +### 3. 레이블 결정 +변경 내용을 분석해 다음 중 하나 이상으로 레이블을 결정한다: + +| 작업 유형 | label | +|---|---| +| 신규 기능 | `feature` | +| 버그 수정 | `bug` | +| 리팩터링 | `refactor` | +| 설정·의존성·chore | `chore` | +| 성능 개선 | `performance` | +| 문서·주석 | `documentation` | +| 테스트 | `test` | + +결정한 label은 적용 전에 `mcp__github__.get_label`로 존재 여부를 확인하고, 존재하는 label만 적용한다. + +### 4. PR 제목 결정 +브랜치명과 커밋 내역을 종합해 PR 제목을 결정한다. +- 형식: `[타입] 핵심 변경 요약` (예: `[Feat] 오답노트 태그 필터 기능 추가`) +- 여러 타입이 섞이면 가장 비중이 큰 타입 하나를 사용 + +### 5. PR 본문 작성 +`.github/PULL_REQUEST_TEMPLATE.md` 구조를 그대로 따른다. 실제 변경 내용에 맞게 체크박스를 채운다: + +``` +## ✔️ 연관 이슈 +- close #이슈번호 ← 2-1단계에서 찾았고 PR merge 시 닫아야 하는 이슈마다 한 줄씩 기재 +- 없음 ← 관련 이슈가 없으면 기재 + +## 📝 작업 내용 +> [커밋 단위로 bullet 정리] + +## 👤 사용자 영향 +- [사용자 관점에서 달라지는 점 / 영향 없으면 "없음"] + +## 🔌 API 호환성 +- [ ] 요청/응답 DTO 변경 없음 +- [ ] 기존 Flutter 앱 버전과 호환 확인 +- [ ] breaking change 있음 + +## 🗄️ DB migration +- [ ] 없음 +- [ ] 있음: migration 파일과 기존 데이터 호환성 확인 + +## 🔐 인증/권한 +- [ ] 영향 없음 +- [ ] 사용자별 데이터 소유권 검증 확인 +- [ ] 관리자/특수 권한 영향 확인 + +## ✅ 검증 결과 +- [실행한 테스트·빌드 명령과 결과 / 실행하지 못한 검증과 남은 리스크] + +## 🚀 배포 리스크 +- [배포 시 주의할 점 / 없으면 "없음"] + +## ↩️ 롤백/대응 방법 +- [문제 발생 시 롤백 방법 / 해당 없으면 "없음"] + +### 스크린샷 (선택) +``` + +### 6. 생성 전 미리보기 확인 +PR을 생성하기 전에 다음 항목을 사용자에게 보여주고 확인을 받는다: +- **Base → Head**: `develop` ← 현재 브랜치명 +- **제목**: 결정된 제목 +- **Labels**: 결정된 레이블 +- **연관 이슈**: `close #이슈번호` 또는 없음 +- **본문 미리보기**: 작성된 본문 전체 + +사용자가 수정을 요청하면 반영한 뒤 재확인한다. 승인하면 다음 단계로 진행한다. + +### 7. 원격 브랜치 push 확인 +미push 커밋이 있으면 사용자에게 알리고, push를 완료한 뒤 진행할 것을 안내한다. +push가 완료된 것을 확인한 후 PR을 생성한다. + +### 8. GitHub PR 생성 +`mcp__github__.create_pull_request` 도구를 사용해 PR을 생성한다: +- `owner`: `AI-SIP` +- `repo`: `OnO_BACKEND` +- `title`: 4단계에서 결정한 제목 +- `body`: 5단계에서 작성한 본문 +- `head`: 현재 브랜치명 +- `base`: `develop` (절대 고정 — main 불가) + +Reviewers는 지정하지 않는다. + +### 8-1. Assignee/Label 설정 +PR 생성 후 생성된 PR 번호에 `mcp__github__.issue_write` 도구를 `method=update`로 호출한다: +- `owner`: `AI-SIP` +- `repo`: `OnO_BACKEND` +- `issue_number`: 생성된 PR 번호 +- `assignees`: `["KiSeungMin"]` (항상 고정) +- `labels`: 3단계에서 결정하고 존재 확인된 label 배열 + +milestone, project, issue fields, type 등 나머지 항목은 지정하지 않는다. + +### 9. 결과 보고 +생성된 PR URL, base/head branch, assignee, 적용 label, 연결한 issue, `main`을 target으로 사용하지 않았다는 점을 사용자에게 알린다. diff --git a/.codex/skills/pr/SKILL.md b/.codex/skills/pr/SKILL.md index e7efc8c..7a3e793 100644 --- a/.codex/skills/pr/SKILL.md +++ b/.codex/skills/pr/SKILL.md @@ -1,25 +1,52 @@ --- name: pr -description: OnO PR 제목과 본문 초안을 작성할 때 사용. 사용자가 "pr <커밋 해시>"를 요청하면 해당 커밋부터 현재까지의 변경과 미커밋 변경을 확인해 PR 템플릿에 맞춰 markdown을 작성한다. +description: OnO 현재 브랜치의 개발 내역을 바탕으로 develop 브랜치에 merge 요청하는 GitHub PR을 직접 생성할 때 사용. 사용자가 "pr"을 요청하면 현재 브랜치에서 develop으로 PR을 생성한다. --- # OnO PR ## Workflow -1. 기준 커밋 해시 또는 변경 범위를 확인한다. 인자가 없으면 현재 git 변경사항을 대상으로 한다. -2. `git log`, `git diff`, `git status`로 커밋된 변경과 미커밋 변경을 분리한다. -3. `.github/PULL_REQUEST_TEMPLATE.md`를 반드시 읽고 같은 구조로 본문을 작성한다. -4. 수정된 파일, API/DB/인증/권한/알림/배포 영향 범위를 정리한다. -5. 테스트와 검증은 실행 여부, 명령, 결과를 구분해 적는다. -6. 저장 위치가 명확하지 않으면 사용자에게 확인한다. 기능 문서가 있으면 같은 `docs/<기능폴더>` 아래에 저장한다. -7. 미커밋 변경사항은 PR 본문에 포함했는지 여부를 명시한다. +1. 현재 브랜치를 확인한다. 현재 브랜치가 `main` 또는 `develop`이면 PR을 생성하지 말고 작업 브랜치에서 실행해야 한다고 보고한다. +2. base branch는 항상 `develop`으로 고정한다. `main` branch를 base로 하는 PR은 절대 생성하지 않는다. `main` merge와 production 배포는 항상 사용자가 직접 담당한다. +3. `git status`로 미커밋 변경사항을 확인한다. 미커밋 변경사항이 있으면 PR을 생성하지 말고 먼저 커밋 또는 정리가 필요하다고 보고한다. +4. 현재 브랜치가 원격에 push되어 있는지 확인한다. 원격 브랜치가 없거나 미push 커밋이 있으면 PR을 생성할 수 없으므로 사용자에게 push 필요 여부를 확인한다. +5. `develop..현재브랜치`의 `git log`와 `git diff`를 확인해 변경 범위를 파악한다. +6. GitHub에서 `AI-SIP/OnO_BACKEND`의 open issue를 먼저 조회해 현재 변경사항과 관련된 이슈가 있는지 확인한다. + - `mcp__github__.list_issues`를 사용한다. + - 브랜치명, 커밋 메시지, 변경 파일, 작업 키워드와 이슈 제목/본문을 비교한다. + - 실제로 이번 PR에서 해결되는 이슈가 있으면 PR 본문 `연관 이슈` 항목에 `close #이슈번호`를 포함한다. + - 단순 참고 이슈는 자동 종료되지 않도록 `close` 없이 참고 문장으로만 적는다. + - 관련 이슈가 없으면 `연관 이슈` 항목에 `없음`이라고 명시한다. +7. `.github/PULL_REQUEST_TEMPLATE.md`를 반드시 읽고 같은 구조로 PR 본문을 작성한다. +8. 수정된 파일, API/DB/인증/권한/알림/배포 영향 범위를 정리한다. +9. 테스트와 검증은 실행 여부, 명령, 결과를 구분해 적는다. +10. PR 제목은 브랜치명과 커밋 내역을 종합해 `[Feat]`, `[Fix]`, `[Refactor]`, `[Chore]`, `[Docs]`, `[Test]` 중 가장 적절한 타입으로 작성한다. +11. Labels는 변경 성격에 맞게 `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `bug` 중 적절한 후보를 고르되, `mcp__github__.get_label`로 존재 여부를 확인한 label만 적용한다. +12. `mcp__github__.create_pull_request`로 PR을 생성한다. + - `owner`: `AI-SIP` + - `repo`: `OnO_BACKEND` + - `base`: `develop` + - `head`: 현재 브랜치명 + - `title`: 작성한 PR 제목 + - `body`: 작성한 PR 본문 + - Reviewers는 지정하지 않는다. +13. PR 생성 후 생성된 PR 번호에 `mcp__github__.issue_write`를 `method=update`로 호출해 Assignees와 Labels를 설정한다. + - `owner`: `AI-SIP` + - `repo`: `OnO_BACKEND` + - `issue_number`: 생성된 PR 번호 + - `assignees`: `["KiSeungMin"]` + - `labels`: 존재 확인된 label 배열 +14. milestone, project, issue fields, type 등 나머지 항목은 지정하지 않는다. ## Output -- PR 제목 -- PR 본문 markdown -- 포함한 커밋/미커밋 변경 범위 +- 생성된 PR 번호와 URL +- base/head branch +- Assignee: `KiSeungMin` +- 적용한 label +- 연결한 issue와 `close #이슈번호` 포함 여부 +- `main`을 target으로 사용하지 않았다는 확인 - 사용자 영향 - 검증 결과 - 배포 리스크와 rollback/대응 방법 diff --git a/.github/workflows/close-issues-on-develop-merge.yml b/.github/workflows/close-issues-on-develop-merge.yml new file mode 100644 index 0000000..6d3c908 --- /dev/null +++ b/.github/workflows/close-issues-on-develop-merge.yml @@ -0,0 +1,51 @@ +name: Close Issues on Develop Merge + +on: + pull_request: + types: [closed] + branches: + - develop + +permissions: + issues: write + +jobs: + close-related-issues: + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + + steps: + - name: Close referenced issues + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const body = context.payload.pull_request.body || ''; + const pattern = /(?:close[sd]?|fix(?:e[sd])?|resolve[sd]?)\s+#(\d+)/gi; + const issueNumbers = []; + let match; + + while ((match = pattern.exec(body)) !== null) { + issueNumbers.push(parseInt(match[1], 10)); + } + + const unique = [...new Set(issueNumbers)]; + if (unique.length === 0) { + console.log('연관 이슈 없음 — 종료'); + return; + } + + for (const number of unique) { + try { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: number, + state: 'closed', + state_reason: 'completed', + }); + console.log(`이슈 #${number} 닫힘`); + } catch (e) { + console.log(`이슈 #${number} 처리 실패: ${e.message}`); + } + } \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 327d369..cdba245 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -143,22 +143,64 @@ OnO 작업 에이전트 지침 [Fix] 오답노트 PDF 내보내기 오류 수정 - null 응답 방어 로딩 상태 개선 ``` -### `pr <커밋 해쉬>` - -사용자가 입력한 커밋을 포함해, 해당 커밋부터 현재까지의 변경사항을 파악한 뒤, PR 제목 및 내용을 markdown으로 작성한다. - -- `<커밋 해쉬>`부터 현재까지의 커밋 내역과 diff를 확인한다. -- 작업 트리에 아직 커밋되지 않은 변경사항이 있으면 함께 확인하고, PR 초안에 반영 여부를 명시한다. +### `pr` + +현재 브랜치의 개발 내역을 바탕으로 `AI-SIP/OnO_BACKEND` GitHub Repository에 `develop` 브랜치로 merge 요청하는 Pull Request를 직접 생성한다. + +- `codex_apps` GitHub 도구가 아니라 `mcp__github__` MCP 서버의 `create_pull_request` 도구를 사용한다. +- Repository는 항상 `owner=AI-SIP`, `repo=OnO_BACKEND`를 사용한다. +- base branch는 항상 `develop`으로 지정한다. +- `main` branch를 base로 하는 PR은 절대 생성하지 않는다. `main` merge와 production 배포는 항상 사용자가 직접 담당한다. +- 현재 브랜치가 `main` 또는 `develop`이면 PR을 생성하지 말고, 작업 브랜치에서 실행해야 한다고 보고한다. +- 현재 브랜치 이름과 원격 브랜치 존재 여부를 확인한다. +- 작업 트리에 아직 커밋되지 않은 변경사항이 있으면 PR을 생성하지 말고, 먼저 커밋 또는 정리가 필요하다고 보고한다. +- 현재 브랜치가 원격에 push되어 있지 않으면 PR을 생성할 수 없으므로 사용자에게 push 필요 여부를 확인한다. +- `develop..현재브랜치`의 커밋 로그와 diff를 확인해 PR 제목과 본문을 작성한다. +- PR 생성 전에 GitHub에서 open issue를 검색해 현재 변경사항과 관련된 이슈가 있는지 확인한다. +- 관련 이슈가 있으면 PR 본문 `연관 이슈` 항목에 `close #이슈번호`를 포함해 merge 시 자동 종료되도록 작성한다. +- 관련 이슈가 없으면 `연관 이슈` 항목에는 관련 이슈 없음이라고 명시한다. - 아래 PR 템플릿을 반드시 확인한다. ```text /Users/ksm/programing/sw_maestro/OnO_BACKEND/backend/.github/PULL_REQUEST_TEMPLATE.md ``` -- PR 제목과 본문은 템플릿 양식에 맞춰 작성한다. -- PR markdown 파일은 `plan`에서 만든 기능 문서 폴더 안에, 구현 명세서와 같은 위치에 저장한다. -- 어떤 기능 문서 폴더를 사용해야 할지 명확하지 않으면 사용자에게 확인한다. +- PR 제목과 본문은 템플릿 양식에 맞춰 작성하고, PR markdown 파일은 별도로 만들지 않는다. - PR 본문에는 변경사항 요약, 사용자 영향, 검증 결과, 배포 리스크를 포함한다. +- Reviewers는 지정하지 않는다. +- PR 생성 후 생성된 PR 번호에 `mcp__github__` MCP 서버의 `issue_write` 도구를 `method=update`로 호출해 Assignees와 Labels를 설정한다. +- Assignees는 항상 `KiSeungMin`으로 지정한다. +- Labels는 변경 성격에 맞게 `feat`, `fix`, `refactor`, `chore`, `docs`, `test`, `bug` 중 적절한 후보를 고르되, `get_label`로 존재 여부를 확인한 label만 적용한다. +- milestone, project, issue fields, type 등 나머지 항목은 지정하지 않는다. +- PR 생성 후에는 PR 번호, URL, base/head branch, assignee, 적용한 label, main을 target으로 사용하지 않았다는 점을 간결하게 보고한다. + +### `/issue <내용 또는 파일 경로>` + +사용자가 자유롭게 작성한 내용이나 파일 내용을 바탕으로 `AI-SIP/OnO_BACKEND` GitHub Repository에 이슈를 생성한다. + +- `codex_apps` GitHub 도구가 아니라 `mcp__github__` MCP 서버의 `issue_write` 도구를 사용한다. +- Repository는 항상 `owner=AI-SIP`, `repo=OnO_BACKEND`를 사용한다. +- Assignees는 항상 `KiSeungMin`으로 지정한다. +- 사용자가 파일 경로를 전달하면 먼저 해당 파일을 읽고, 파일 내용을 이슈 원문으로 사용한다. +- 사용자가 직접 내용을 입력하면 그 내용을 이슈 원문으로 사용한다. +- 원문이 부족해도 가능한 범위에서 이슈를 생성하되, 운영 영향이나 재현 조건처럼 필수 판단에 필요한 정보가 없으면 이슈 본문에 "확인 필요"로 명시한다. +- 아래 이슈 템플릿을 반드시 확인하고, 입력 성격에 맞는 템플릿을 선택해 본문을 채운다. + +```text +/Users/ksm/programing/sw_maestro/OnO_BACKEND/backend/.github/ISSUE_TEMPLATE/bug-report-template.md +/Users/ksm/programing/sw_maestro/OnO_BACKEND/backend/.github/ISSUE_TEMPLATE/common-issue-template.md +``` + +- 버그, 오류, 예외, 장애, 잘못된 동작, 회귀 이슈는 `bug-report-template.md` 형식을 사용한다. + - 제목은 `[bug] ...` 형식으로 작성한다. + - label은 `bug`를 포함한다. + - 본문에는 버그 설명, 발생 상황, 예상 결과를 템플릿 항목에 맞춰 정리한다. +- 기능 추가, 개선, 리팩터링, 문서, 설정, 운영 작업은 `common-issue-template.md` 형식을 사용한다. + - 제목은 `[feat]`, `[fix]`, `[refactor]`, `[chore]`, `[docs]`, `[test]` 중 가장 적절한 타입을 골라 작성한다. + - label은 선택한 타입과 이슈 성격에 맞게 적용하되, 존재 여부가 불확실한 label은 무리하게 붙이지 않는다. + - 본문에는 Description, TODO, ETC를 템플릿 항목에 맞춰 정리한다. +- GitHub issue type 기능이 사용 가능하면 입력 성격에 맞는 type을 설정한다. 유효한 type을 확인할 수 없거나 Repository가 issue type을 지원하지 않으면 `type` 필드는 생략한다. +- 이슈 생성 후에는 이슈 번호, URL, 적용한 assignee, label, type을 사용자에게 간결하게 보고한다. ### `check <커밋 번호>`