[git] lint 에러 발생 시 PR merge 제한하기

초코침·2023년 9월 3일
0

git

목록 보기
3/4
post-thumbnail

pre-commit에 린트를 돌리는데 왜 배포하려니 린트 에러가 발생할까

팀원 간 통일성 있는 코드를 위해 husky를 도입하여

pre-commit에 코드 포맷팅(prettier)린팅(eslint)을 수행하도록 설정했습니다.


코드 포맷팅과 린팅을 자동으로 수행하게 설정했기 때문에 main 브랜치에는 정렬되고 문법 에러가 없는 코드만을 합칠 수 있겠다고 기대했으나,

배포할 때 타입 에러가 적지 않게 발생했습니다.

분명히 커밋칠 때 훅으로 걸어둔 린팅 과정을 거친 코드들만 PR에 올라올 수 있었을 텐데

왜 배포하려니 이런 어처구니 없는 에러가 발생했을까요?


틈틈이 고민해 본 결과, 린트가 커밋 누락까지 체크해줄 순 없었기 때문이었습니다.


예를 들어, Button 컴포넌트를 만들어 App 컴포넌트에서 사용하는 코드를 작성했다고 가정해 봅시다.

// Button.tsx
const Button = () => {
  return <button>버튼</button>;
};

export default Button;
// App.tsx
import Button from './components/Button'; // 📌

function App() {
  return (
    <>
      <Button />
    </>
  );
}

export default App;

위 코드를 작성하고 린트를 돌려보면 에러가 발생하지 않습니다.


그런데 이때 작성한 Button 컴포넌트를 커밋하는 것을 까먹고

App만 커밋하여 PR에 App 컴포넌트의 변경 사항만 반영됐다면

리모트에서는 App 파일의 import문을 이해할 수 없을 것입니다. (Button을 커밋하지 않았으니까요!)


로컬에서 작업을 완료하여 App을 커밋할 때 실행된 린트는 잘 통과가 됐기 때문에 에러가 발생하지 않고 PR까지 이어질 수 있었지만,

Button 파일 커밋을 잊었기 때문에 리모트에서 배포 과정을 거치며 실행된 린트는 에러를 발생시키게 되는 것입니다.


따라서, 아무리 린트 규칙을 엄격하게 정하고 철저히 지켰다 하더라도

참조 중인 파일을 커밋하지 않았다면 배포 시에 린트 에러를 만날 수 있는 것이죠. 😤


이러한 이유로 pre-commit, pre-push 때 린트 훅을 거는 것은 무의미하겠다는 생각이 들었습니다.

그래서 pr을 merge 하기 전 정말로 문법 에러가 없는 코드인지 확인하는 것이 좋겠다고 생각하여 린트를 github action으로 추가해 봤습니다.

PR이 생성되면 린트 체크하기

프로젝트 루트 경로에 .github 폴더를 만들고 그 내부에 workflows 폴더를 만듭니다.

workflows 폴더 안에 실행할 action을 yml 파일로 작성해 넣어주면 되는데,
저는 pr을 체크할 목적으로 만들 것이기 때문에 check_pull_request라는 이름으로 yml 파일을 만들었습니다.

yml 작성하기

pr이 (재)오픈되거나, push를 통해 변경 사항이 생길 때마다 린팅할 수 있도록 다음과 같이 yml을 작성했습니다. 작성한 다음에는 main에 push합니다.

name: check_pull_request # action 이름

on:
  pull_request: # action을 발생시킬 이벤트
    types: [opened, reopened, synchronize] # pr이 open, reopen, synchronize된 경우
  workflow_dispatch: # action 탭에서 이 워크플로우를 수동으로 실행할 수 있게 해 줌

jobs:
  lint: # job 이름
    runs-on: ubuntu-latest # 실행 환경
    steps: # pr이 (재)오픈, 업데이트 되었을 때 실행할 명령어
			- uses: actions/checkout@v3
      - run: yarn # package 설치
      - run: yarn run lint # lint 실행

작성하는 법은 깃허브 공식 문서를 참고했고, types에 대한 설명은 깃허브 웹훅 액션 타입 문서에 잘 나와있습니다.


위 예시에서 언급했던 대로 App만 커밋하고 pr을 생성하면 작성한 액션이 실행됩니다.

로컬에서 Button 컴포넌트를 작성했지만 커밋하지 않았기 때문에 에러가 발생합니다.

Merge 제한 걸기

pr을 생성하면 린트를 실행하지만 린트 에러의 발생 여부와는 관계 없이 Merge pull request 버튼은 활성화되어 있습니다.

린트 에러가 있다는 경고를 확인하지 못하고 merge해버렸다면 다시 배포 때 에러를 확인하는 루트를 타겠죠…

이를 방지하기 위해 테스트가 통과하지 않으면 merge할 수 없는 제한을 걸어보겠습니다.

Rules 추가하기

repository의 Settings > Branches에 들어가 Add Rule 버튼을 클릭합니다.

branch name pattern에 merge되는 것을 보호할 브랜치를 작성하고, Require status checks to pass before merging에 yml을 작성할 때 쓴 job 이름을 넣어줍니다.

다시 pr로 돌아가보면 Merge pull request 버튼이 비활성화된 것을 확인할 수 있습니다.

마지막으로, 커밋하지 않았던 Button 파일을 푸시하면 merge 버튼이 활성화됩니다.

저는 pr을 올리면 코드 전체를 린팅하도록 액션을 작성했는데, 이 블로그에서는 내가 작업한 부분에 대해서만 린트를 돌리게 액션을 작성하셨더라고요.

프로젝트에 적용한다면 이런 식으로 해야겠습니다 ㅎㅎ


이렇게 파일을 누락하는 실수가 없었다면 린트를 돌리는 위치의 중요성에 대해서는 생각하지 못하고 넘어갔을 것 같습니다.

왜 한 팀원의 로컬에서만 프리 커밋이 실행되지 않는 건가 너무 궁금했는데 그 이유를 알게 돼서 속이 시원하고 공부까지 하게 돼서 좋았네요!

결론! 실행 안 된 것 아님. 파일 누락한 것이었음.

profile
블로그 이사중 🚚 (https://sungjihyun.vercel.app)

0개의 댓글