[5주차] Git Hooks를 활용한 Prettier 강제 적용 (React SSR)

[월간-CS][24년 4월] React, Next 배포와 배포 자동화 A부터 Z
이민석's avatar
May 08, 2024
[5주차] Git Hooks를 활용한 Prettier 강제 적용 (React SSR)

이 문서는 [월간-CS][24년 4월] React, Next 배포와 배포 자동화 A부터 Z를 위해서 작성된 문서입니다. 이 문서에는 그 어떤 저작권이 없으며, 편하게 참고 및 사용하셔도 됩니다.

개요

본 문서에서는 Git Hooks 이론을 바탕으로 실제로 다양한 Git Hooks를 만들고 이를 다른 사람과 협업 가능한 형태로 만들어 볼 것입니다.

간단한 Git Hooks 만들어보기

저희는 git push origin <branch_name>을 입력할 때마다 아래의 메세지를 띄우고 싶습니다.

echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."

따라서 .git/hooks/pre-push 파일을 생성하고 아래 파일을 넣어줄 것입니다.

#!/bin/sh

echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."

이제 git push origin main을 입력하면 아래와 같은 출력이 눈에 보입니다.

~\2024-04-cicd-week-5-template>git push origin main

pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다.
pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다.
pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다.

하지만 .git/hooks 파일은 기본적으로 GitHub에 업로드 되지 않으므로, 공유할 방법이 없습니다.

실제로 git clone <repo_이름> <별도_폴더명>으로 프로젝트를 클론 받은 다음에 git push origin main을 해보면 별다른 창이 나타나지 않습니다.

따라서 저희는 Git Hooks를 공유하고 안정적으로 사용할 수 있는 환경을 구성해야 합니다.

Git Hooks 공유하는 방법 찾기

실제 활용 사례를 찾기 위해서 구글에 “How can I share git hooks”라고 검색하였을 때, 몇가지 글을 찾을 수 있었습니다.

  1. Stackoverflow (QnA) | Can Git hook scripts be managed along with the repository?

  2. Dev to (Blog) | A githooks example, and how to share it with the team

  3. Viget (Blog) | Two Ways to Share Git Hooks with Your Team

여기서 언급하고 있는 방법은 아래와 같았습니다.'

  1. 깃 CLI(git config core.hooksPath)를 사용하는 방법

    1. 해당 명령어 수동으로 입력하기 (Dev to Blog)

    2. 해당 명령어 자동으로 실행하도록 구성하기 (Stackoverflow QnA)

    3. 해당 명령어를 스크립트화하고 자동으로 실행하도록 구성하기 (Me)

  2. 소프트 심볼릭(ln -s) 링크를 사용하는 방법

    1. 기존의 링크를 지우고 새로운 소프트 심볼릭 링크를 구성하는 것 (Viget)

    2. 모든 과정을 자동화하고 자동으로 실행하도록 구성하기 (Me)

두 방법 모두 별도의 경로에 Git Hooks 파일을 만드는 것은 동일 하기 때문에 저희는 .github/hooks 폴더를 만들고 여기에 작업을 하겠습니다.

.github/hooks/pre-push 파일을 만들고 아래 내용을 넣어주세요.

#!/bin/sh

echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."

Git Hooks 공유 - 1번, Git CLI를 사용하는 방법

Git CLI를 사용하는 방법은 간편하고 빠르게 Git Hooks를 공유하는데 사용할 수 있습니다.
하지만 2가지 치명적인 단점이 있습니다.

하지만 이 2가지 방법을 개선하기 위해서는 소프트 심볼릭 링크를 써야 합니다

[정리]

이 방법은 아래와 같은 장/단점이 존재합니다.

  • 장점

    • Git Hooks를 공유할 수 있음

  • 단점

    • 완전한 자동화가 아니기 때문에 문제가 발생할 수 있음

    • .git/hooks와 .github/hooks가 동시에 존재하기 때문에 혼란스러울 수 있음

[실습]

아래의 순서에 따라서 실습을 진행해주세요.

  1. .github/hooks/pre-push 파일을 만들고 아래 내용을 넣어주세요.

    #!/bin/sh
    
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다."
  2. 아래 명령어를 실행해서 echo 내용이 출력되는지 확인해주세요.

    단, 미리 만들어둔 .git/hooks/pre-push 파일은 제거해주세요.
    단, 미리 만들어둔 .git/hooks/pre-push 파일은 제거해주세요.

    • 명령어

      git push origin main
  3. 프로젝트 package.json에 아래 항목을 추가해주세요.

    만약 없다면 npm init -y로 생성해주세요.

      "scripts": {
        "preinstall": "git config core.hooksPath .github/hooks",
      },
  4. 해당 디렉토리에서 아래 명령어를 입력해서 preinstall script를 실행해주세요.

    1. 명령어

      npm i
  5. 아래 명령어를 실행해서 echo 내용이 출력되는지 확인해주세요.

    • 명령어

      git push origin main
  6. 기존에 생성해둔 .github/hooks/pre-push 파일을 아래와 같이 수정해주세요.

    #!/bin/sh
    
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다. 222"
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다. 222"
    echo "pre-receive는 신규 브런치의 git push origin <branch_name> 시에 실행됩니다. 222"
  7. 아래 명령어를 실행해서 변경된 echo 내용이 출력되는지 확인해주세요.

    1. 명령어

      git push origin main

Git Hooks 공유 - 2번, 소프트 심볼릭 링크 사용하기

패키지 매니저 yarn berry, pnpm 등을 포함한 다양한 곳에서 소프트 심볼릭 링크가 쓰이고 있습니다.

다만 MacOS/Linux와 Windows에서는 공통으로 통용되는 Script의 수가 매우 적습니다.
따라서 실행 환경을 정확하게 통일하여 실행해야 하는 치명적인 단점이 있습니다.

  1. package.json에 불필요한 값 제거

    아래에 해당하는 preinstall 스크립트를 제거해주세요,

      "scripts": {
        "preinstall": "git config core.hooksPath .github/hooks",
      },
  2. Git Config 경로 초기화

    1. 아래 명령어를 실행해서 core.hooksPath를 초기화해주세요.

      git config core.hooksPath .git/hooks
    2. 아래 명령어로 변경을 확인할 수 있습니다.

      1. 방법 1, CLI

        git config core.hooksPath
      2. Cat

        cat .git/config
  3. 하드 링크 걸기

    MacOS/Linux에서는 기본 터미널을 사용하면 됩니다.
    Windows에서는 Git Bash를 사용해야 합니다.
    CMD, Powershell에서는 작동하지 않습니다.
    또한, Windows에서는 소프트 심볼릭 링크가 지속적으로 작동하지 않고 일회성으로만 작동합니다.

    find .git/hooks -type l -exec rm {} \; && find .github/hooks -type f -exec ln -f $(pwd)/* .git/hooks/ \;

Prettier 적용을 하기 위한 Git Hooks 만들기

1번 혹은 2번 방법으로 Git Hooks 사용을 준비했으면 이제 Prettier 적용을 할 차례입니다.

  1. .prettierrc 파일 만들기

    {
      "semi": false,
      "singleQuote": true,
      "tabWidth": 2,
      "useTabs": false,
      "printWidth": 80
    }
    

  2. .github/hooks/pre-push 파일에 아래 내용을 붙여넣기 해주세요.

    #!/bin/sh
    echo "[Git Hooks][Pre-Push] 실행"
    
    changed_file_by_prettier=$(npx prettier --list-different .)
    if [ -z "$changed_file_by_prettier" ]; then
        echo "[Git Hooks][Pre-Push] no files to git add"
    
    else
        npx prettier --write .
        while IFS= read -r file; do
            echo "[Git Hooks][Pre-Push] git add $file"
            git add "$file"
        done <<< "$changed_file_by_prettier"
      
        git commit -m "Formatting : Prettier is auto-work by git hooks"
        echo "[Git Hooks][Pre-Push] git commit -m \"Formatting : Prettier is auto-work by git hooks\""
    fi

쉬운방법

Share article

Unchaptered