회사에서 web 프로젝트 마이그레이션을 진행하면서 prettier와 eslint가 제대로 적용되지 않은 코드가 늘어났다. 첫 번째 원인은 prettier/eslint 설정을 프로젝트 중간부터 진행했기 때문이고 😅, 두 번째 원인은 리팩토링 시 잠시 prettier/eslint를 끄고 할 때가 있는데 그것 때문인 듯 하다.
github에 코드가 push되기 이전에 prettier/eslint를 자동으로 적용할 수 있을까 싶어 알아 보니, Husky라는 라이브러리를 통해 이를 편리하게 자동화할 수 있다고 하여 이용해 보기로 했다.
또한 기존에 dev 브랜치를 대상으로 빌드 에러를 검사해 주는 GitHub Action workflow가 있었는데, 레포지토리를 변경한 후 해당 workflow를 다시 설정해 놓는 것이 딜레이되는 바람에 배포 시 빌드 에러가 발생하는 상황이 있곤 했다. 이러한 상황을 해결하기 위해, 이 기회에 github action을 공부해 보며 build workflow를 등록해 보려 한다.
본 글에서는 Husky와 GitHub Action의 개념 및 설정 방법을 다룬다. yarn을 이용하며, prettier/eslint는 이미 셋업되어 있다고 가정한다. prettier/eslint 자체에 대해 다루지는 않을 예정이다.
git hook 설정을 도와주는 라이브러리
git hook은 commit/push와 같은 git 이벤트가 발생했을 때 특정 스크립트를 실행할 수 있도록 해주는 기능이다. husky를 활용하면 특정 git hook들을 자동으로 활성화해줄 수 있기 때문에 협업 시 특히 유용하다.
그리고 husky의 작동 방식을 미리 한 줄 요약하면,
git 이벤트 발생 시
.husky
라는 폴더 내에 있는 스크립트들을 실행한다.
난 commit 시 staged된 파일들에 대해 prettier/eslint를 자동으로 적용하고 싶었고, 그 방법은 아래와 같다.
yarn add -D husky lint-staged
husky와 lint-staged를 -D
를 통해 devDeps로 설치한다. devDeps로 설치하는 이유는 빌드 시엔 불필요한 기능이기 때문이다.
lint-staged는 전체 파일이 아닌 staged된 파일에 대해서만 명령어를 실행할 수 있도록 해주는 라이브러리이다.
postinstall
과 lint-staged
라는 script를 아래 사진과 같이 작성한다.참고로 git 폴더의 최상단에 package.json이 존재한다면 postinstall
부분에 husky install
만 적어주면 된다.
우리 회사의 경우 git 폴더 최상단 아래에 package.json이 존재하는 폴더가 따로 있는 구조이기 때문에 나는 아래 사진처럼 작성하였다.
postinstall
postinstall은 어떠한 라이브러리가 설치되면 바로 이어서 실행되는 스크립트이다. 이를 통해 팀에서 git hook을 쉽게 공유할 수 있게 되는 것! 팀원들과 package.json을 공유하니 말이다.
husky install
은 git hook들을 활성화 해주는 명령어로, git 폴더 최상단에서만 실행될 수 있다. 따라서 나의 경우 cd ..
를 통해 git 폴더 최상단으로 이동해 준 후 husky install을 실행하였다. 그리고 추가적으로 ./{package.json 존재 폴더}/.husky
경로를 명시하여 .husky
폴더의 위치를 알려 주었다.
lint-staged
staged된 파일들에 대해서만 실행되는 스크립트로, 나는 ts/tsx 형식 파일들을 대상으로 실행하고 싶은 명령어를 작성해 주었다. prettier/eslint를 적용하며, 자동으로 고칠 수 있는 부분은 고치게끔 하는 명령어를 작성했다.
npx husky add .husky/pre-commit
package.json이 있는 폴더 내에서 위 커맨드를 실행하면 .husky
폴더와 그 안에 pre-commit
파일이 생성되는데, 파일 내용에 commit 시 실행되어야 할 스크립트를 작성해 줌으로써 commit git hook을 설정할 수 있다.
package.json이 존재하는 폴더 내에서 lint-staged
스크립트를 실행해 주기 위해, 앞선 postinstall
스크립트의 경우와 비슷하게 cd
를 이용하여 아래 사진과 같이 작성하였다. git 폴더의 최상단에 package.json이 존재한다면 4행에 yarn lint-staged
만 적어주면 된다!
모든 절차를 마친 후 커밋을 해보면, 아래처럼 자동으로 prettier/eslint가 실행된다. 👏
.eslintrc.json
의 rules
에 따라 warning이 뜰지 error가 뜰지가 결정되며, error가 발생하면 커밋이 되지 않는다.
이제 GitHub Action을 알아보자!
빌드/테스트/배포를 자동화할 수 있는 github의 CI/CD 툴
dev 브랜치에 push/pull request된 코드들에 대해 빌드 에러를 검사할 것이다.
우선 GitHub Action의 구성 요소를 살펴 보면,
github에서 발생하는 일 (ex: push, pull request)
이벤트 발생 시 실행될 작업(Job) 목록
//
로 부연 설명을 달아 보았다.name: Next.js CI // Workflow 이름
# Controls when the workflow will run
on: // 구독할 github event 설정
push: // event 이름
branches: ['dev'] // event를 구독할 브랜치, 여러 개 브랜치도 가능
pull_request:
branches: ['dev']
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs: // job 목록
# This workflow contains a single job called "build"
build: // job 이름
# The type of runner that the job will run on
runs-on: ubuntu-latest // 구동 환경
strategy:
matrix:
node-version: [ 19.3.0 ] // 여러 개 node 버전도 가능
# Steps represent a sequence of tasks that will be executed as part of the job
steps: // step 목록
- uses: actions/checkout@v3.5.3 // action 실행
- name: Set up NodeJS ${{ matrix.node-version }} // step 이름
uses: actions/setup-node@v2.5.2 // action 실행
with:
node-version: ${{ matrix.node-version }}
- name: Install Dependencies // step 이름
run: | // 의존성 설치 스크립트 실행
cd {폴더명}/
npm install -g yarn
yarn install
- name: Test Build // step 이름
run: | // 빌드 실행
cd {폴더명}/
yarn build
env: // Settings에서 등록한 secret들
SECRET_KEY: ${{ secrets.SECRET_KEY }}
https://docs.github.com/ko/actions/using-workflows 공식 문서도 자세히 되어 있으니 참고해 보면 좋다.
workflow 등록 후 push나 PR을 해보면, build 프로세스가 수행되는 것을 확인할 수 있다. 😇
처음엔 약간 복잡해 보였지만 원리를 이해하고 나니 크게 어렵진 않았던 것 같다. git hook과 github action을 통해 더 다양한 작업들을 자동화해 볼 수 있을 것 같아서 활용도를 높여보고 싶다!
Reference:
https://www.interglobalmedianetwork.com/blog/adding-husky-to-a-subfolder-of-a-git-root-repository
https://youtu.be/iLqGzEkusIw