깃허브(GitHub) 이슈/PR 템플릿으로 협업 속도 높이기

이슈함을 열었더니 제목은 “안 돼요”, 본문은 “로그인이 안 됩니다” 한 줄. 어떤 브라우저인지, 어떤 계정인지, 언제부터인지 되묻고 답을 기다리는 데만 하루가 갑니다. 재현 정보를 받아내는 왕복 두 번이면 실제 수정에 30분이면 될 버그가 이틀짜리 티켓이 됩니다. 깃허브 템플릿 활용법은 이 왕복을 없애는 가장 값싼 방법입니다. 파일 몇 개를 저장소에 커밋해 두면, 이슈를 여는 사람이 필요한 정보를 처음부터 채워서 보내게 됩니다. 이번 글에서는 마크다운 템플릿부터 입력을 강제하는 이슈 폼, PR 체크리스트, 조직 전체 일괄 적용까지 순서대로 다룹니다.

템플릿이 실제로 줄여주는 것

템플릿은 문서가 아니라 입력 폼입니다. 기여 가이드(CONTRIBUTING.md)에 “재현 방법을 적어주세요”라고 써두는 것과, 이슈 작성 화면에 빈 칸이 떠 있는 것은 회수율이 전혀 다릅니다. 사람은 읽으라고 준 문서는 안 읽지만, 눈앞에 있는 빈 칸은 채웁니다.

템플릿을 넣으면 세 가지가 달라집니다.

  • 되묻는 왕복이 사라집니다. 버전·OS·재현 순서가 첫 제출에 담깁니다.
  • 분류가 자동으로 됩니다. 템플릿마다 라벨과 제목 접두어를 미리 붙일 수 있어서, 이슈함이 저절로 정리됩니다.
  • 리뷰가 빨라집니다. PR 템플릿에 “왜 바꿨는지”와 “어떻게 확인했는지” 칸이 있으면 리뷰어가 코드부터 읽지 않아도 됩니다.

가장 빠른 시작: 마크다운 템플릿 한 장

저장소 루트에 .github/ISSUE_TEMPLATE/ 폴더를 만들고 마크다운 파일을 넣으면 끝입니다. 파일 맨 위 --- 사이에 들어가는 부분이 프론트매터로, 템플릿 이름과 기본 라벨을 지정합니다.

---
name: 버그 리포트
about: 동작하지 않는 기능을 신고합니다
title: "[BUG] "
labels: bug, triage
assignees: ""
---

## 무슨 일이 일어났나요

## 재현 방법
1.
2.
3.

## 기대한 결과

## 실행 환경
- OS:
- 버전:

커밋하고 나면 이슈 작성 버튼을 눌렀을 때 템플릿 선택 화면이 뜨고, 고르면 본문이 저 내용으로 채워진 상태로 시작합니다. title에 접두어를 넣어두면 제목 앞에 자동으로 붙고, labels에 적은 라벨은 이슈 생성과 동시에 달립니다.

마크다운 템플릿의 한계는 명확합니다. 안내일 뿐 강제가 아닙니다. 작성자가 항목을 통째로 지우고 한 줄만 써서 올려도 막을 방법이 없습니다. 여기서 한 단계 더 나가면 이슈 폼입니다.

이슈 폼(YAML)으로 필수 입력 강제하기

확장자를 .yml로 바꾸고 폼 스키마로 작성하면, 마크다운 본문 대신 실제 입력 위젯이 뜹니다. 텍스트 한 줄, 여러 줄, 드롭다운, 체크박스를 조합할 수 있고 required: true를 붙인 칸은 비워두면 제출 자체가 안 됩니다.

name: 버그 리포트
description: 동작하지 않는 기능을 신고합니다
title: "[BUG] "
labels: ["bug", "triage"]
body:
  - type: markdown
    attributes:
      value: |
        보고 전에 열려 있는 이슈에 같은 내용이 있는지 확인해 주세요.

  - type: input
    id: version
    attributes:
      label: 버전
      placeholder: v1.4.2
    validations:
      required: true

  - type: textarea
    id: steps
    attributes:
      label: 재현 방법
      description: 순서대로 적어주세요. 코드나 로그는 그대로 붙여넣어도 됩니다.
      render: shell
    validations:
      required: true

  - type: dropdown
    id: os
    attributes:
      label: 운영체제
      options:
        - Windows
        - macOS
        - Linux
    validations:
      required: true

  - type: checkboxes
    id: checks
    attributes:
      label: 확인 사항
      options:
        - label: 최신 버전에서도 같은 문제가 발생합니다
          required: true

자주 쓰는 필드 타입은 다음 네 가지입니다.

타입쓰임필수 지정
input버전, 링크처럼 한 줄짜리 값가능
textarea재현 순서, 로그, 코드가능
dropdownOS, 심각도처럼 선택지가 정해진 값가능
checkboxes제출 전 확인 사항항목별로 가능
markdown작성자에게 보여줄 안내문 (제출 내용에 안 담김)해당 없음

textarea에 render: shell을 주면 입력한 내용이 코드 블록으로 감싸져서 올라갑니다. 로그를 붙여넣을 칸이라면 넣어두는 편이 좋습니다. 백틱을 안 쳐서 로그가 뭉개진 이슈를 다시 볼 일이 없어집니다.

YAML은 들여쓰기 한 칸만 어긋나도 템플릿이 목록에 아예 나타나지 않습니다. 이때 에러 메시지가 따로 뜨지 않아서 원인을 찾기 어렵습니다. 저장소의 Issues 탭에서 새 이슈를 눌러 템플릿이 보이는지 반드시 눈으로 확인하세요.

PR 템플릿 만들기

PR 쪽은 파일 하나면 됩니다. .github/pull_request_template.md를 만들어두면 PR을 열 때 본문이 자동으로 채워집니다. 선택 화면 없이 바로 적용되므로 폴더도 필요 없습니다.

## 무엇을 바꿨나요

<!-- 한두 문장으로. 코드를 안 본 사람도 이해할 수 있게 -->

## 왜 바꿨나요

Closes #

## 어떻게 확인했나요

- [ ] 로컬에서 실행해 동작을 확인했습니다
- [ ] 테스트를 추가하거나 기존 테스트를 갱신했습니다

## 리뷰어가 특히 봐줬으면 하는 곳

<!-- 자신 없는 부분, 설계 판단이 갈릴 수 있는 부분 -->

체크박스 문법을 그대로 쓰면 PR 화면에서 클릭 가능한 체크리스트가 됩니다. 본인이 확인한 항목을 스스로 체크하게 만드는 것만으로 “테스트 돌려봤어요?”라는 질문이 사라집니다. Closes # 줄도 습관을 만드는 장치입니다. 여기에 이슈 번호를 적으면 머지될 때 그 이슈가 자동으로 닫힙니다.

템플릿을 여러 개 두고 싶다면 .github/PULL_REQUEST_TEMPLATE/ 폴더에 파일을 나눠 넣고, PR 생성 URL 뒤에 ?template=hotfix.md를 붙여 고릅니다. 다만 이건 링크를 알고 있는 사람만 쓰게 되므로, 대부분의 팀은 기본 템플릿 한 장으로 충분합니다.

선택 화면 다듬기: config.yml

템플릿을 만들어도 “빈 이슈 열기” 링크가 같이 뜨기 때문에, 급한 사람은 결국 빈 이슈를 씁니다. .github/ISSUE_TEMPLATE/config.yml로 그 링크를 없애고, 이슈함에 오면 안 되는 문의는 다른 곳으로 보낼 수 있습니다.

blank_issues_enabled: false
contact_links:
  - name: 사용법 질문
    url: https://github.com/내계정/내저장소/discussions
    about: 버그가 아닌 질문은 Discussions에 올려주세요.
  - name: 보안 취약점 신고
    url: https://example.com/security
    about: 공개 이슈로 올리지 말고 이쪽으로 알려주세요.

blank_issues_enabled: false가 빈 이슈 링크를 없앱니다. contact_links는 선택 화면에 외부 링크를 추가하는 항목으로, 사용법 질문은 Discussions로, 보안 취약점은 비공개 채널로 유도할 때 씁니다. 보안 신고를 공개 이슈로 받지 않는 건 오픈소스에서는 기본에 가깝습니다.

여기까지 하면 저장소의 파일 구조는 이렇게 됩니다.

.github/
├── ISSUE_TEMPLATE/
│   ├── bug_report.yml
│   ├── feature_request.yml
│   └── config.yml
└── pull_request_template.md

조직 전체에 한 번에 적용하기

저장소가 열 개인데 열 번 커밋할 필요는 없습니다. 조직(또는 개인 계정) 아래에 .github라는 이름의 저장소를 만들고 거기에 템플릿을 넣으면, 자체 템플릿이 없는 모든 저장소가 그것을 기본값으로 씁니다.

  1. 조직에 .github라는 이름으로 공개 저장소를 새로 만듭니다.
  2. 그 저장소 안에 .github/ISSUE_TEMPLATE/ 폴더와 .github/pull_request_template.md를 넣습니다. (저장소 이름과 폴더 이름이 겹치는 게 맞습니다)
  3. 커밋하면 끝입니다. 개별 저장소에 같은 경로의 파일이 있으면 그쪽이 우선합니다.

공통 규칙은 조직 저장소에 두고, 특수한 사정이 있는 저장소만 자기 템플릿으로 덮어쓰는 구조가 관리하기 편합니다. 나중에 항목을 하나 추가할 때도 한 곳만 고치면 됩니다.

주의할 점

  • 칸을 너무 많이 만들지 마세요. 필수 항목이 여덟 개쯤 되면 사람들은 이슈를 안 쓰고 메신저로 말합니다. 필수는 세 개 이하, 나머지는 선택으로 두는 편이 회수율이 높습니다.
  • 기본 브랜치에 있어야 적용됩니다. 작업 브랜치에만 커밋해두면 템플릿이 나타나지 않습니다. 안 보인다면 이것부터 확인하세요.
  • YAML 폼은 라벨을 미리 만들어두는 게 안전합니다. 없는 라벨을 지정하면 무시되거나 새로 생성되는데, 오타가 그대로 라벨이 되어 남는 경우가 있습니다.
  • 템플릿은 검사기가 아닙니다. 필수 칸을 강제해도 “재현 방법: 그냥 안 됨”이라고 쓰는 건 막지 못합니다. 좋은 예시를 placeholder에 넣어두는 게 실질적으로 더 효과가 큽니다.
  • PR 템플릿의 HTML 주석은 그대로 남습니다. 안내문을 주석으로 넣으면 렌더링에서는 안 보이지만, 나중에 본문을 복사해 릴리스 노트로 쓸 때 섞여 들어옵니다.

마무리

전부 다 만들 필요는 없습니다. 오늘 할 수 있는 가장 작은 일은 .github/pull_request_template.md 한 장을 만드는 것입니다. “무엇을 / 왜 / 어떻게 확인했는지” 세 줄이면 충분하고, 커밋하는 순간부터 다음 PR에 적용됩니다. 이슈 폼은 실제로 되묻는 일이 반복되는 항목이 눈에 보일 때 그때 추가해도 늦지 않습니다.

다음 글에서는 Claude로 코드 리뷰를 자동화하는 프롬프트 모음을 다룹니다. 템플릿으로 정리한 PR에 AI 1차 리뷰를 붙이면 사람이 볼 것이 확 줄어듭니다.

댓글 남기기