지난 포스팅에서는 ‘커밋 메시지가 무엇이며 인포그랩은 어떤 커밋 컨벤션을 사용하는지’ 알아보았습니다. 이모지를 쓰고 이슈 번호도 넣은 커밋 메시지는 추적하기 쉽고, 보기에 좋습니다. 하지만 커밋 메시지가 길고 복잡할수록 매번 불편하고 실수도 잦아집니다.

이번 포스팅에서는 좋은 커밋 메시지를 강제하고, 자동화하는 방법을 알아봅니다. 아울러 인포그랩 프로덕트 팀의 커밋 메시지 자동화 방법도 소개하겠습니다.

인포그랩에서 실제 사용 중인 커밋 컨벤션 관련 예제는 여기서 찾아보실 수 있습니다.

커밋 메시지를 적을 때 무엇이 불편한가요?

✨ Feat(페이지 경로 또는 컴포넌트): 새로운 기능 추가 또는 기능 업데이트
🔨 Fix(페이지 경로 또는 컴포넌트): 버그 또는 에러 수정
⭐️ Style(페이지 경로 또는 컴포넌트): 코드 포맷팅, 코드 오타, 함수명 수정 등 스타일 수정
🧠 Refactor(페이지 경로 또는 컴포넌트): 코드 리팩토링(똑같은 기능인데 코드만 개선)
📁 File(페이지 경로 또는 컴포넌트): 파일 이동 또는 제거, 파일명 변경
🎨 Design(페이지 경로 또는 컴포넌트): 디자인, 문장 수정
🏷 Comment(페이지 경로 또는 컴포넌트): 주석 수정 및 삭제
🍎 Chore: 빌드 수정, 패키지 추가, 환경변수 설정
📝 Docs: 문서 수정, 블로그 포스트 추가
🔥 Hotfix: 핫픽스 수정

인포그랩 프로덕트 팀의 커밋 컨벤션을 다시 살펴봅시다. 저희는 이모지를 사용해 보기 좋은 커밋 메시지를 만드는데요. 하지만 매번 적절한 이모지를 찾는 일은 고역입니다. 시간이 오래 걸리고 실수할 가능성도 커집니다. 또 커밋 메시지의 타입(Feat, Fix, …)을 꼭 대문자로 시작해야 하는데요. 이것을 지키기가 쉬운 일은 아닙니다.

그래서 이런 규칙 준수 여부를 자동으로 감지하고 ‘틀렸다’는 것을 알려주는 방법을 찾아 보았습니다.

어떻게 커밋 메시지를 강제할 수 있을까요?

커밋 컨벤션 준수 여부를 자동 감지하는 방법을 말하기에 앞서 짚고 갈 기능이 있습니다. 바로 ‘Git Hooks’입니다. Git Hooks는 Git 관련 이벤트가 발생했을 때 우리가 정한 스크립트를 실행하는 기능입니다. 이 기능은 서버 훅과 클라이언트 훅으로 나뉩니다. 서버 훅은 Git 서버에서 동작하고, 클라이언트 훅은 Git 커맨드를 입력하는 컴퓨터에서 동작합니다.

Git Hooks를 사용하면 두 가지 방법으로 커밋 메시지를 강제할 수 있습니다.

1. 서버 훅: Git의 push rule 기능 사용하기

먼저 서버 훅은 아래와 같이 분류합니다.

설명
pre-receivepush 요청 시 가장 먼저 실행
update여러 브랜치에 push할 때 브랜치마다 실행
post-receive푸시를 완료한 후 실행(알림이나 서비스 업데이트용)

pre-receive 훅에 커밋 메시지를 검사하는 스크립트를 넣으면 서버에 푸시되지 않도록 할 수 있습니다. GitLab에서는 push rule 기능을 사용해 정규 표현식으로 커밋 메시지를 검사할 수 있습니다. 만약 정규 표현식을 위배하는 커밋 메시지를 감지하면 해당 푸시를 거부하고 오류를 일으킵니다.

2. 클라이언트 훅: 푸시하기 전 미리 검사하기

클라이언트 훅은 아래와 같이 분류합니다.

분류설명
커밋 워크플로 훅pre-commit커밋하기 전에 실행
prepare-commit-msg커밋 메시지를 생성하고 편집기를 실행하기 전에 실행
commit-msg커밋 메시지를 완성한 후 커밋을 완료하기 전에 실행
post-commit커밋을 완료한 후 실행
이메일 워크플로 훅applypatch-msggit am 명령 시 처음으로 실행
pre-applypatchpatch 적용 후 실행하며, patch 중단 가능
post-applypatchgit am 명령 시 마지막으로 실행, patch 중단 불가
기타 훅pre-rebaseRebase하기 전 실행
post-rewritegit commit –amend, git rebase와 같이 커밋을 변경한 후 실행
post-mergemerge하고 나서 실행
pre-pushgit push 명령 실행 시 동작함. 리모트 정보를 업데이트하고 난 후 리모트로 데이터를 전송하기 전에 실행. push를 중단할 수 있음

커밋을 최종 완료하기 전인 commit-msg 훅에 스크립트를 만들어 커밋 메시지를 검사할 수 있습니다. 또한 커밋 메시지를 수정하고 싶다면 prepare-commit-msg 훅에 관련 스크립트를 작성합니다.

인포그랩은 커밋 메시지를 어떻게 자동화했나요?

위에서 설명한 훅을 사용하려면 .git 폴더 아래에 방대한 스크립트를 직접 작성해야 합니다. 이 방법을 사용하면 너무 번거롭고 이해하기 힘듭니다. 또 다른 개발자들과 스크립트를 공유하지 못합니다.

인포그랩에서는 더 편리한 툴인 Husky와 Commitlint를 사용해 커밋 메시지 자동화 체계를 만들었습니다.

Husky와 commitlint란?

Husky는 Git Hooks 관리를 돕는 npm 모듈입니다. .husky 디렉터리 아래에 스크립트를 담은 훅 파일을 만듭니다. 그 다음, npx husky install 명령을 입력하면 해당 스크립트가 Git에 등록됩니다.

commitlint는 커밋 컨벤션을 쉽게 관리하고 커밋 메시지를 검사하는 도구입니다. 팀에서 정한 커밋 컨벤션을 JSON 형식으로 작성합니다. 그러면 commitlint 명령을 사용해 메시지를 검사할 수 있습니다.

1. 커밋 컨벤션을 commitlint 형식으로 정의하기

커밋 메시지의 기본 틀은 아래와 같습니다. 이 틀을 기준으로 commitlint.config.ts 파일에 각 팀에 맞는 속성을 정의합니다. 예를 들어, 인포그랩에서는 커밋 메시지의 타입에 이모지가 꼭 들어가야 합니다. 저희는 이에 맞추어 “✨ Feat”, “🔨 Fix” 등 타입을 허용하는 type-enum 속성을 재정의했습니다.

type(scope?): subject
body?
footer?

2. Husky에 commitlint 등록하기

commit-msg 훅에 commitlint 명령을 등록합니다. .husky/commit-msg 파일에 아래와 같이 스크립트를 넣습니다.

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx commitlint --edit $1

3. 자동화 추가하기

이제 commitlint를 사용해 커밋 메시지를 엄격하게 관리할 수 있습니다. 하지만 매번 이모지를 붙이고 규칙을 지키는 일은 쉽지 않습니다. 이모지를 붙이거나 이슈 번호를 삽입하는 단순한 작업을 자동화하면 어떨까요?

인포그랩 프로덕트 팀에서는 크게 세 가지 커밋 메시지 자동화를 기획했습니다.

  1. 타입(feat, fix)만 입력하면 이모지를 자동 추가하기
  2. 타입의 첫 글자만 대문자로 자동 수정하기
  3. 브랜치에 이슈 번호가 있으면 footer에 이슈 번호 붙이기

이 자동화 스크립트는 prepare-commit-msg 훅에 넣을 수 있습니다. 보다 상세한 스크립트는 인포그랩의 예제 코드를 참조하세요!

맺음말

지금까지 좋은 커밋 메시지를 검사하고 자동화하는 방법을 알아보았습니다.

커밋 메시지를 잘 구성하면 건강하고 생산적인 개발 환경을 유지할 수 있습니다. 하지만 메시지를 작성하는 데 많은 시간을 투자하거나 스트레스를 받으면 안 됩니다. 대신, 적절한 자동화 계획을 세우면 개발자의 부담을 줄일 수 있습니다.

인포그랩은 GitLab 및 DevOps에 대한 맞춤 기술 지원을 제공합니다. GitLab(Omnibus/Cloud Native Hybrid) 구축 관련 지원이 필요하시면 문의하기 로 연락해 주십시오.

<참고 자료>

  1. husky 로 git hook 하자
  2. git branch 이름과 hook으로 commit message 컨벤션 강제하기
  3. Git Hooks