Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .agent/skills/pull-request/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ description: Framework 저장소의 Draft PR 생성, 검증 결과와 체크리
- 명사형 종결의 최상위 개조식 사용. 변경 내용·검증 결과는 각각 1~3개 항목
- 핵심 동작·영향·실제 결과만 기록. 구현 과정·작업 순서·시도한 방법·중첩 목록·홍보 문구 생략
- 중요한 미검증 범위와 API 계약·배포 조건 유지. 상세 설명은 Issue 또는 문서에 기록
- 체크리스트는 해당 변경의 필수 검증과 리뷰 확인으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환, 리뷰 반영 후 머지
- 체크리스트는 변경 범위 확인과 필수 검증으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환 후 머지
- 이슈 전체 완료는 `Closes #번호`, 부분 완료·참고는 `Refs #번호`
- 본문은 파일과 `--body-file`로 전달. 문자열 `\n` 사용 금지

Expand All @@ -29,7 +29,9 @@ gh pr ready

## 병합

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·체크리스트·리뷰 확인 후 merge commit으로 병합한다.
리뷰는 선택사항이며 승인 리뷰·리뷰 체크·미해결 대화를 공통 머지 조건으로 요구하지 않는다.

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·검증 체크리스트 완료 후 merge commit으로 병합한다.

```bash
head_branch=$(gh pr view --json headRefName --jq .headRefName)
Expand Down
8 changes: 5 additions & 3 deletions .claude/skills/pull-request/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ description: Framework 저장소의 Draft PR 생성, 검증 결과와 체크리
- 명사형 종결의 최상위 개조식 사용. 변경 내용·검증 결과는 각각 1~3개 항목
- 핵심 동작·영향·실제 결과만 기록. 구현 과정·작업 순서·시도한 방법·중첩 목록·홍보 문구 생략
- 중요한 미검증 범위와 API 계약·배포 조건 유지. 상세 설명은 Issue 또는 문서에 기록
- 체크리스트는 해당 변경의 필수 검증과 리뷰 확인으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환, 리뷰 반영 후 머지
- 체크리스트는 변경 범위 확인과 필수 검증으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환 후 머지
- 이슈 전체 완료는 `Closes #번호`, 부분 완료·참고는 `Refs #번호`
- 본문은 파일과 `--body-file`로 전달. 문자열 `\n` 사용 금지

Expand All @@ -29,7 +29,9 @@ gh pr ready

## 병합

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·체크리스트·리뷰 확인 후 merge commit으로 병합한다.
리뷰는 선택사항이며 승인 리뷰·리뷰 체크·미해결 대화를 공통 머지 조건으로 요구하지 않는다.

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·검증 체크리스트 완료 후 merge commit으로 병합한다.

```bash
head_branch=$(gh pr view --json headRefName --jq .headRefName)
Expand Down
8 changes: 5 additions & 3 deletions .codex/skills/pull-request/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ description: Framework 저장소의 Draft PR 생성, 검증 결과와 체크리
- 명사형 종결의 최상위 개조식 사용. 변경 내용·검증 결과는 각각 1~3개 항목
- 핵심 동작·영향·실제 결과만 기록. 구현 과정·작업 순서·시도한 방법·중첩 목록·홍보 문구 생략
- 중요한 미검증 범위와 API 계약·배포 조건 유지. 상세 설명은 Issue 또는 문서에 기록
- 체크리스트는 해당 변경의 필수 검증과 리뷰 확인으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환, 리뷰 반영 후 머지
- 체크리스트는 변경 범위 확인과 필수 검증으로 구성. 미수행 항목 체크 금지
- 실제 검증 후 결과·체크 상태 갱신, Ready for review 전환 후 머지
- 이슈 전체 완료는 `Closes #번호`, 부분 완료·참고는 `Refs #번호`
- 본문은 파일과 `--body-file`로 전달. 문자열 `\n` 사용 금지

Expand All @@ -29,7 +29,9 @@ gh pr ready

## 병합

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·체크리스트·리뷰 확인 후 merge commit으로 병합한다.
리뷰는 선택사항이며 승인 리뷰·리뷰 체크·미해결 대화를 공통 머지 조건으로 요구하지 않는다.

사용자 요청 범위와 저장소 승인 조건을 확인한다. 공통 규칙의 필수 검사·검증 체크리스트 완료 후 merge commit으로 병합한다.

```bash
head_branch=$(gh pr view --json headRefName --jq .headRefName)
Expand Down
1 change: 0 additions & 1 deletion .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
- [ ] 변경 범위 확인
- [ ] 변경 범위에 맞는 검증 완료
- [ ] 검증 결과 및 미검증 범위 기재
- [ ] 리뷰 반영 및 미해결 의견 확인

## 관련 이슈

Expand Down
9 changes: 5 additions & 4 deletions .github/scripts/collaboration-policy.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,12 @@ export function validatePullRequest(pr, { legacyPullRequestMaxNumber = 0 } = {})
const kind = pullRequestKind(pr, errors);
bullets(sections.get('변경 내용'), '변경 내용', errors, { max: 3 });
bullets(sections.get('검증 결과'), '검증 결과', errors, { max: 3 });
const checklist = bullets(sections.get('머지 체크리스트'), '머지 체크리스트', errors, { checklist: true });
for (const required of ['변경 범위 확인', '리뷰 반영 및 미해결 의견 확인']) {
const checklist = bullets(sections.get('머지 체크리스트'), '머지 체크리스트', errors, { checklist: true })
.filter(item => item.text !== '리뷰 반영 및 미해결 의견 확인');
for (const required of ['변경 범위 확인']) {
if (!checklist.some(item => item.text === required)) error(errors, `필수 체크 항목: ${required}`);
}
if (checklist.length < 3) error(errors, '머지 체크리스트: 공통 확인 2개와 변경에 맞는 검증 항목 필요');
if (checklist.length < 2) error(errors, '머지 체크리스트: 변경 범위 확인과 변경에 맞는 검증 항목 필요');
const references = [];
for (const line of sections.get('관련 이슈') ?? []) {
const reference = /^(?:- )?(Closes|Fixes|Resolves|Refs) (?:(?:[\w.-]+)\/(?:[\w.-]+))?#([1-9]\d*)$/iu.exec(line);
Expand All @@ -119,7 +120,7 @@ export function validateReadiness(pr, config = {}) {
if (result.legacy || pr.draft) return result;
const { sections } = parseBody(pr.body, PR_HEADINGS);
const items = bullets(sections.get('머지 체크리스트'), '머지 체크리스트', [] , { checklist: true });
for (const item of items) if (!item.checked) error(result.errors, `머지 전 완료 필요: ${item.text}`);
for (const item of items) if (item.text !== '리뷰 반영 및 미해결 의견 확인' && !item.checked) error(result.errors, `머지 전 완료 필요: ${item.text}`);
return result;
}

Expand Down
15 changes: 13 additions & 2 deletions .github/scripts/collaboration-policy.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ const body = `## 변경 내용
- [x] 변경 범위 확인
- [x] 회귀 테스트 완료
- [ ] 실기기 반복 진입 확인
- [x] 리뷰 반영 및 미해결 의견 확인

## 관련 이슈

Expand Down Expand Up @@ -53,9 +52,21 @@ test('체크 후 같은 PR의 머지 검사 통과', () => {
assert.deepEqual(validateReadiness({ ...pr, draft: false, body: body.replace('- [ ]', '- [x]') }).errors, []);
});
test('필수 공통 확인 항목 삭제로 머지 검사를 우회하지 못함', () => {
assert.ok(validatePullRequest({ ...pr, body: body.replace('- [x] 리뷰 반영 및 미해결 의견 확인\n', '') }).errors.length);
assert.ok(validatePullRequest({ ...pr, body: body.replace('- [x] 변경 범위 확인\n', '') }).errors.length);
assert.ok(validatePullRequest({ ...pr, body: body.replace('- [x] 회귀 테스트 완료\n- [ ] 실기기 반복 진입 확인\n', '') }).errors.length);
});
test('리뷰 없는 Ready PR과 기존 미완료 리뷰 체크는 머지 허용', () => {
const ready = { ...pr, draft: false, body: body.replace('- [ ]', '- [x]') };
assert.deepEqual(validateReadiness(ready).errors, []);
const legacyReview = ready.body.replace('## 관련 이슈', '- [ ] 리뷰 반영 및 미해결 의견 확인\n\n## 관련 이슈');
assert.deepEqual(validateReadiness({ ...ready, body: legacyReview }).errors, []);
});
test('변경 범위와 검증 한 개만으로 Ready PR 머지 허용', () => {
const minimal = body.replace('- [ ] 실기기 반복 진입 확인\n', '');
assert.deepEqual(validateReadiness({ ...pr, draft: false, body: minimal }).errors, []);
const reviewOnly = minimal.replace('- [x] 회귀 테스트 완료', '- [ ] 리뷰 반영 및 미해결 의견 확인');
assert.ok(validatePullRequest({ ...pr, body: reviewOnly }).errors.length);
});
test('미완료 항목이 있는 Issue는 진행 추적 허용', () => assert.deepEqual(validateIssue(issue).errors, []));
test('GitHub 웹 Issue Form의 H3 섹션도 같은 양식으로 검사', () => assert.deepEqual(validateIssue({ ...issue, body: issue.body.replaceAll('## ', '### ') }).errors, []));
test('Issue의 완료 기준 누락 거부', () => assert.ok(validateIssue({ ...issue, body: issue.body.split('## 완료 기준')[0] }).errors.length));
Expand Down
16 changes: 8 additions & 8 deletions docs/collaboration.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,20 +59,19 @@ Issue·브랜치·PR 타입은 `feat/fix/chore/refactor` 사용. 개별 커밋
- [x] 변경 범위 확인
- [x] 관련 테스트 완료
- [ ] 실제 기기 반복 진입 확인
- [ ] 리뷰 반영 및 미해결 의견 확인

## 관련 이슈

- Closes #395
```

- 구현 중 Draft 생성 허용. 검증 전에는 `검증 대기`와 미완료 체크박스 기재
- 체크리스트는 해당 변경의 머지에 필요한 항목만 작성. 검증 항목과 리뷰 확인 항목 포함
- `변경 범위 확인`, `리뷰 반영 및 미해결 의견 확인`은 고정 필수 항목. 해당 변경의 검증 항목을 하나 이상 추가
- 체크리스트는 해당 변경의 머지에 필요한 항목만 작성. 변경 범위 확인과 검증 항목 포함
- `변경 범위 확인`은 고정 필수 항목. 해당 변경의 검증 항목을 하나 이상 추가
- 수행하지 않은 검증 체크 금지. 빌드·실기기 검증이 미대상이면 결과에 이유 기재
- 검증 결과는 실행 명령·대상·통과 개수·핵심 결과로 요약
- 검증 후 결과·체크 상태 갱신, Ready for review 전환, 리뷰 반영 후 머지
- 리뷰는 요청한 리뷰 또는 자가 검토의 실제 확인 결과로 체크. 체크만으로 승인 리뷰를 대체하지 않음
- 검증 후 결과·체크 상태 갱신, Ready for review 전환 후 머지
- 리뷰는 선택사항. 승인 리뷰·리뷰 체크·미해결 대화를 공통 머지 조건으로 요구하지 않음
- `Closes #번호`는 이슈 전체 완료, `Refs #번호`는 일부 완료 또는 참고에 사용
- 중요 미검증 범위를 후속 Issue로 분리한 경우 `검증 결과`에 범위와 번호 기재. 필수 항목을 삭제해 검사만 통과시키지 않음

Expand All @@ -88,10 +87,11 @@ Issue·브랜치·PR 타입은 `feat/fix/chore/refactor` 사용. 개별 커밋
## 자동 검사와 적용 시점

- `Collaboration / PR format`: 제목·브랜치·섹션 순서·개조식·문장형 종결·항목 수·이슈 연결 및 연결 Issue 본문 검사
- `Collaboration / merge readiness`: Draft의 미완료 체크 허용, Ready PR의 미완료 체크 차단
- `Collaboration / merge readiness`: Draft의 미완료 검증 체크 허용, Ready PR의 미완료 검증 체크 차단
- 기존 PR 본문의 `리뷰 반영 및 미해결 의견 확인` 체크는 형식·머지 검사에서 제외. 검증 항목으로 계산하지 않음
- `Collaboration / policy tests`: 검사기의 정상·거부·Draft·Ready 전환 회귀 검증
- `Collaboration / Issue format`: 새 Issue의 본문 검사, 오류 시 `needs-format` 표시, 수정 후 표시 제거
- CI는 내용의 사실성·검증 충분성·과정 서술의 의미를 판정하지 않음. 작성자와 리뷰어가 확인
- CI는 내용의 사실성·검증 충분성·과정 서술의 의미를 판정하지 않음. 작성자가 확인
- `.github/collaboration-policy.json`의 기존 번호 이하 기록은 새 양식 소급 적용 제외
- 적용 기준 파일은 저장소별 관리. 하네스 동기화 대상에서 제외하여 재동기화 시 기준 유지

Expand All @@ -109,7 +109,7 @@ gh pr merge --merge --match-head-commit "$head_sha" \
--subject "merge: $head_branch" --body ""
```

필수 검사와 리뷰 확인 후 병합. GitHub 웹에서도 같은 제목·빈 본문 사용. 병합 후 실제 커밋의 제목·본문·두 부모 확인. 이 명령 예시는 사용자 승인·저장소 권한·요청 범위를 확장하지 않음.
필수 검사와 검증 체크 완료 후 병합. GitHub 웹에서도 같은 제목·빈 본문 사용. 병합 후 실제 커밋의 제목·본문·두 부모 확인. 이 명령 예시는 사용자 승인·저장소 권한·요청 범위를 확장하지 않음.

## 규칙 원본

Expand Down
3 changes: 1 addition & 2 deletions sync/pr-body.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,13 @@ export const syncPullRequestBody = `## 변경 내용
## 검증 결과

- 동기화 변경 파일 생성 완료
- 대상 저장소 검증·리뷰 대기
- 대상 저장소 검증 대기

## 머지 체크리스트

- [ ] 변경 범위 확인
- [ ] 대상 저장소 검증 완료
- [ ] 검증 결과 및 미검증 범위 기재
- [ ] 리뷰 반영 및 미해결 의견 확인

## 관련 이슈

Expand Down
Loading