July 24, 2023
Git hooks는 사용하고 싶고, pre-commit이나 husky는 설치하고 싶지 않았다
어떻게 해야할까?
prepare-commit-msg hook을 사용해 커밋 메세지 컨벤션을 체크한다
#!/bin/sh
commit_msg_file="$1"
commit_msg_type="$2"
commit_msg="$3"
if [ "$commit_msg_type" = "-m" ]; then
echo "$commit_msg" > "$commit_msg_file"
fi
commit_msg=$(cat "$commit_msg_file")
# 정규표현식 파일을 참조한다
commit_msg_regex=$(cat "$(dirname "$0")/../../.github/commit-regular.txt")
if ! echo "$commit_msg" | grep -Eq "$commit_msg_regex"; then
echo "Invalid commit message format."
exit 1
fi간단히 말해 해당 파일을 .git/hooks/prepare-commit-msg 위치에 작성하면, Git이 알아서 git commit 마다 컨벤션 체크가 동작한다!
(feat|fix|refactor|style|docs|test|chore):.{1,50}(\n.{1,72})?$위 파일은 정규표현식으로 향후 커밋 메세지를 체크할때 사용한다
Git Actions를 통한 CI 작업에도 사용하기 때문이다.git 폴더는 숨김 폴더이기 때문에 github에 올라가지 않는다.
따라서 해당 파일을 모든 개발자가 셋업 하기에는 너무 귀찮은 일이다.
특정 IDE 마다 다르겠지만 대부분 훅을 제공해 여러 설정을 자동으로 세팅할 수 있다.
devcontainer는 Codespace 개발환경 세팅을 위한 규칙이라고 생각하면 편하다!
가장 간단한 예시로는 레퍼지토리에 devcontainer 규칙에 맞는 파일을 정의하면, 어떤 누구나 코드스페이스를 실행할때 설정해놓은 Ubuntu Image 위에 Java, Docker가 설치되며 Extenstion도 자동으로 설치된다!
{
// ...
"postCreateCommand": "bash ./.devcontainer/postCreateCommand.sh",
}cp .github/hooks/prepare-commit-msg .git/hooks/prepare-commit-msg
chmod +x .git/hooks/prepare-commit-msgpostCreateCommand.sh 을 이용해 쉘 스크립트 파일을 .git/hooks로 복사한다
인텔리제이를 포함해서 모든 에디터에서 공통이다.
val installLocalGitHook = tasks.register<Copy>("installLocalGitHook") {
from("${rootProject.rootDir}/.github/hooks")
into(File("${rootProject.rootDir}/.git/hooks"))
eachFile {
mode = "755".toInt(radix = 8)
}
}
tasks.build {
dependsOn(installLocalGitHook)
}해당 파일은 코틀린으로 작성되었으며 특정 Gradle 버전마다 다른 형식을 사용할 수 있다
단점: graldew build 실행시 세팅되기 때문에 만약 빌드를 안하면 세팅되지 않는다!
위 커밋 컨벤션 체크 쉘 스크립트 파일을 그대로 이용했다
name: Commit Message Check
on: [push]
jobs:
commit_message_check:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Read Commit Regular Expression
id: read_commit_regex
run: |
commit_msg_regex=$(cat ./.github/commit-regular.txt)
echo "Commit Regular Expression: $commit_msg_regex"
echo "::set-output name=commit_regex::$commit_msg_regex"
- name: Validate Commit Message
run: |
commit_msg=$(git log --format=%B -n 1 ${{ github.sha }})
echo "Commit Message: $commit_msg"
commit_regex="${{ steps.read_commit_regex.outputs.commit_regex }}"
if [[ ! "$commit_msg" =~ $commit_regex ]]; then
echo "Invalid commit message format."
exit 1
else
echo "Commit message is valid."
fi./gradlew ktlintCheck --daemon
status=$?
echo "$status"
if [ "$status" = 0 ] ; then
echo "> Completed ktlint hook."
exit 0
else
echo "> Error ktlint hook."
echo "============================"
exit 1
fi lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Ktlint check
uses: gradle/gradle-build-action@749f47bda3e44aa060e82d7b3ef7e40d953bd629
with:
arguments: ktlintCheckKtlint를 예시로 사용했다!