기존에 github-actions 를 사용하여 github 서버에서 테스트 코드가 실행되고 도커 이미지가 빌드 및 배포가 되는 ci/cd 를 구성해 본 경험이 있다. 그런데 개발을 진행하다 보니 로컬에서부터 ci 를 적용하여 자동으로 테스트 코드가 실행되고 코딩 컨벤션을 자동으로 적용할 수 있도록 하면 좋을 거 같다는 생각이 들었다. 로컬에서 작업을 하면서 자동으로 ci 를 적용해볼 수 있을 만한 도구들을 찾으면서 많이 사용하는 git hooks 와 pre-commit 모듈 등에 대해서 알아보았다.
1. git hooks
Git hooks 는 특정 이벤트가 발생했을 때 자동으로 정해진 스크립트를 실행할 수 있도록 해주는 git 의 기능이다. Git hooks 는 이벤트에 따라서 client hook 과 server hook 으로 나눌 수 있는데, commit 이나 merge 와 같이 클라이언트에서 발생하는 이벤트들이 client hook, push 와 같이 서버에서 발생하는 이벤트가 server hook 이다.
- .git/hooks
Git hooks 의 스크립트들은 git 레포지토리의 .git/hooks/ 아래에 위치한다. hooks 디렉토리를 확인하면 디렉토리에 .sample 확장자를 가진 스크립트들이 있는데, 기본으로 git 에서 제공해주는 예제 스크립트들이다. 이 스크립트에서 .sample 확장자를 제거해주면 바로 hook 을 사용할 수 있다.
hook 파일들의 이름을 보면 pre-commit, pre-rebase, post-update 등으로 파일명이 구성되어 있는 것을 알 수 있다. Git hooks 의 hook 들은 파일명에 따라서 스크립트가 실행되는 이벤트가 달라진다. 예를들어 pre-commit 의 경우 commit 이 발생하면 해당 스크립트를 수행한다. 스크립트가 에러없이 모두 수행되면 그제서야 commit 이 실행된다.
#!/bin/sh
echo "pre-commit is executed."
./gradlew test
위의 코드는 gradle 을 기반으로하는 프로젝트에서 test 코드를 수행하도록 pre-commit 스크립트를 작성한 것이다. 이와 같이 Git hooks 를 사용하여 commit 전에 테스트 코드 실행이나 coding convention 을 적용하는 formatter 등이 동작하도록 할 수 있다. 하지만 hook 스크립트 들이 위치하는 .git 디렉토리는 기본적으로 .gitignore 에 지정되어 있어서 git repository 를 통해서 업로드하고 공유할 수 없다는 단점이 있다.
2. pre-commit
pre-commit 은 이름 그대로 commit 전에 실행되는 도구이다. yaml 형식으로 스크립트를 작성하여 commit 이 발생하면 스크립트를 먼저 실행시킨다.
- installation
pre-commit 은 python package manager 이 pip 또는 MacOS 의 경우 homebrew 를 사용하여 설치할 수 있다.
# pip
$ pip install pre-commit
# homebrew
$ brew install pre-commit
다음과 같이 pre-commit 의 버전을 확인하여 설치가 잘 됐는지 확인할 수 있다.
$ pre-commit –version
pre-commit 3.0.2
- configuration
pre-commit 이 실행하는 스크립트의 기본적으로 .pre-commit-config.yaml 을 이름으로 가진다. 직접 해당 이름의 파일을 만들어도 되고 아니면 pre-commit 의 sample config 를 다음과 같이 받아서 수정하여 사용해도 된다.
$ pre-commit sample-config > .pre-commit-config.yaml
pre-commit 의 sample-config 는 다음과 같이 구성되어 있다.
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v3.2.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-added-large-files
pre-commit 은 git repo 에서 hook 을 다운받아서 실행하는 방식으로 동작한다. 위의 스크립트에서 처럼 hook 이 저장되어 있는 repo 를 정의하고 해당 repo 에서 사용할 hook 들을 hooks 에 정의하여서 실행시킬 수 있다. pre-commit 은 다양한 hook 들을 제공해주는데, https://pre-commit.com/hooks.html 페이지에서 제공해주는 hook 들을 확인할 수 있다.
이 예제에서는 pre-commit-hooks repo 의 v3.2.0 버전에서 trailing-whitespace, end-of-file-fixer, check-yaml, check-added-large-files 등의 hook 들을 받아서 수행한다. rev 는 revision 또는 tag 를 의미하는 값으로 여기서는 해당 레포지토리의 v3.2.0 태그를 의미한다.
pre-commit 은 git hooks 와는 다르게 따로 모듈을 설치해야 하지만 yaml 을 통해서 스크립트를 공유할 수 있다.
[Reference]
'기타 > Git' 카테고리의 다른 글
[Web] JWT (JSON Web Token) (0) | 2023.03.11 |
---|---|
[git] git 브랜치 병합 전략 (merge, rebase) (0) | 2022.06.15 |
[git] git stash (0) | 2021.10.30 |
[git] squash로 commit 합치기 (0) | 2021.10.30 |
[git] git submodule / subtree (0) | 2021.10.19 |