Husky로 gitmoji를 포함한 커밋메시지 검사하기1

foresec·2024년 7월 7일

Project

목록 보기
10/11

협업 프로젝트에 있어서 커밋 메시지 컨벤션을 지정했더라도
실수로 인해서 혹은 프로젝트 후반으로 갈수록 컨벤션이 지켜지지 않는 경우가 많다.

이때, 커밋이 되기전에 커밋 메시지를 검사해서 컨벤션을 통과하지 않으면 커밋되지 않도록 하는 방법으로 Git hook과 husky라이브러리를 사용하면 된다.

Git Hook & Husky

https://git-scm.com/book/ko/v2/Git%EB%A7%9E%EC%B6%A4-Git-Hooks
https://typicode.github.io/husky/

Git Hook

특정 Git 이벤트가 발생할 때 자동으로 실행되는 스크립트

크게 클라이언트 훅과 서버훅으로 나뉘고 그 안에서 다양한 훅이 있지만, 이 글에선 commit 메시지를 검증하는 기능이 필요하므로 클라이언트 훅 중 pre-commit, commit-msg를 알아보자

pre-commit

커밋할 때 가장 먼저 호출되는 훅

  • 커밋 메시지를 작성하기 전에 호출됨
  • 이 훅의 Exit 코드가 0이 아니면 커밋은 취소됨
  • 빠트린 것은 없는지, 테스트는 확실히 했는지 등을 검사하기 때문에 커밋할 때 꼭 확인해야 할 게 있으면 이 훅으로 확인한다

ex) lint와 같이 코드 스타일을 검사할 때 등에 자주 쓰임

commit-msg

커밋 메시지가 들어 있는 임시 파일의 경로를 받음

  • 0이 아닌 값을 반환하면 커밋되지 않음
  • 최종적으로 커밋이 완료되기 전에 프로젝트 상태나 커밋 메시지를 검증한다.

Husky

git Hooks를 활용, 커밋하거나 푸시할 때 커밋 메시지, 코드에 대해 자동으로 린트(lint)하고 테스트를 실행하는데 도움을 주는 자동화 라이브러리

왜 Husky를 써야할까

Git Hook 스크립트 자체는 개발자 각각이 자신의 작업 환경에 맞게 설정하고 관리하는 것인데, 협업 프로젝트에서는 개인 설정대로 관리하기보단 공통된 스크립트가 필요하다

이때, husky는

  1. Git Hook 설정을 프로젝트의 의존성으로 포함시켜 개발자들이 프로젝트의 Git Hook 설정을 일관되게 공유하고, 팀 전체에서 동일한 개발 환경을 유지하는데 도움이 된다
  2. 또한, npm 등의 패키지 관리 도구를 사용하여 package.json 파일에 Husky 관련 설정을 추가하여 실행할 수 있다

초기설정

아래 과정을 거치면 초기설정이 완료된다

npm install --save-dev husky
npx husky init

.husky 디렉토리가 프로젝트 최상단에 생성되고 사용하고자 하는 hook 스크립트를 내부에 작성하면 된다.

예시(처음 실행시 pre-commit만 존재)


전체 요구사항

그럼 다음과 같이 요구사항대로 커밋메시지가 검사될 수 있도록 해보자

  1. eslint와 prettier를 커밋 전에 검증해서 코드의 스타일을 일관되게 유지하자

  2. 커밋 메시지를 일관되게 검증하자
    지정한 커밋 컨벤션의 예시는 다음과 같다

    ✨ feat: 로그인 함수 추가

    즉, <GitMoji> <Type>: <message>의 형태로 만들어야한다.

1) eslint와 prettier 검사

husky 초기설정과 prettier설치가 되어있어야 한다.

lint-staged

staged된 파일, 즉 변경된 파일들에 대해 설정된 코드 스타일 린팅 및 포맷팅 도구들을 자동으로 실행한다.

npm install --save-dev lint-staged

package.json에 lint-staged 작성(ts프로젝트이기 때문에 ts로 설정함)

"lint-staged": {
  "*.{ts,tsx}": [
    "eslint --cache --fix",
    "prettier --cache --write"
  ]
}
  • cache : 검사된 파일을 캐싱 하여 빠르게 실행
  • fix : 가능한 경우 자동으로 수정할 수 있는 문제들을 수정
  • write : Prettier가 파일을 직접 수정하여 포맷팅을 적용

pre-commit파일

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

npx lint-staged

husky내부 pre-commit에 작성하여 커밋되기 전에 lint staged를 실행함

2) 커밋 메시지 검사

commitlint

https://commitlint.js.org/

커밋 컨벤션을 지키기 쉽게 도와주는 linter

npm install --save-dev @commitlint/config-conventional @commitlint/cli

.commitlintrc

config 파일을 별도로 작성하여 commit메시지를 원하는 형태로 검사할 수 있다

간단한 설정파일

{
  // @commitlint/config-conventional을 따르는 기본설정
  "extends": [
    "@commitlint/config-conventional"
  ],
  "rules": {
    "type-enum": [
      2,
      "always",
      [
        "build",
        "chore",
        "ci",
        "docs",
        "feat",
        "fix",
        "perf",
        "refactor",
        "revert",
        "style",
        "test"
      ]
    ]
  }

commit-msg

파일 및 기본설정 추가

echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg

위와 같이 실행하면 commit-msg가 husky폴더 안에 생성되며 아래와 같이 내용이 추가가 된다

npx --no -- commitlint --edit $1

여기서 원하는 사항을 추가하여 다음과 같이 작성했다

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

COMMIT_MESSAGE_FILE=$1
COMMIT_MESSAGE=$(cat "$COMMIT_MESSAGE_FILE")

echo "Commit message content: $COMMIT_MESSAGE"

npx commitlint --edit $1

# commitlint 실행 결과에 따라 메시지 출력
if [ $? -eq 0 ]; then
  echo "✅ 커밋 컨벤션을 통과했습니다."
  exit 0
else
  echo "❌ 커밋 메시지가 컨벤션을 준수하지 않습니다."
  exit 1
fi

<Type>: <message>

ex)feat: 로그인 함수 추가

여기까지는
1. eslint와 prettier 검사
2. 그리고 위와 같이 gitmoji를 제외한 기본 형태의 커밋메시지를 검사할 수 있다.

글이 길어져서 다음 글에서 gitmoji를 포함시킨 커밋 컨벤션으로 검사하는 방법과 관련 툴들을 알아보자

profile
왼쪽 태그보다 시리즈 위주로 구분

0개의 댓글