Search
Duplicate

[misc] Github Action을 이용해 코드 검사 자동화하기

간단소개
Github Action을 이용해 norm 검사를 자동으로 수행하는 방법을 정리했습니다.
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Github
Scrap
태그
Github
9 more properties

[misc] Github Action을 이용해 코드 검사 자동화하기

42의 C 과제들은 깐깐한 코딩 컨벤션에 맞추어 진행되어야 합니다. Norm이라 불리는 이 컨벤션을 지키지 못하면, 과제를 아무리 잘 했더라도 코드를 다시 짜야 합니다.
다행이, 42에서는 이 norm을 검사해주는 유틸리티를 제공합니다. Norminette 검사기를 활용하면 내 코드가 이 규정을 따랐는지 쉽게 확인할 수 있습니다.
최근 Minishell이라는 팀 과제를 진행하면서, Github을 사용해 협업하기로 하였습니다.
이때 팀원 중 한 사람이라도 norm을 따르지 않는다면 과제를 평가받던 중에 norm error로 리트라이해야 하는 불행한 일이 생길 수 있기 때문에, 애초에 코드를 작성하는 과정에서도 이 norm 규정을 지키도록 만들었습니다.
이 글에서는 Github Action을 이용해 검사를 자동화하는 방법과, 특정 조건에 이 Action을 트리거하는 방법을 설명합니다.
Github의 Action은 Workflow 단위로 이루어집니다. 각 Workflow는 리포지토리 최상단에 위치한 .github/workflows 밑에 yaml 형식으로 작성되어야 합니다.
Workflow 파일은 다음 정보를 포함하고 있습니다.
이 Action이 실행되는 조건
이 Action의 실행환경
Action이 실행할 명령들
제가 만든 Workflow를 보며, 설명을 이어가겠습니다.
name: check 42 norminette on: push: pull_request: jobs: check_42_norm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install 42 norminette run: | sudo apt update sudo apt install python3 -y python3 -m pip install --upgrade pip setuptools python3 -m pip install --upgrade norminette - name: check for 42 norminette requirements run: | echo checking files: $(git ls-files) norminette . check_compile_error: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: check for compilation errors run: | sudo apt update sudo apt install build-essential -y echo checking files: $(git ls-files) for f in $(find . -name \\*.c); do gcc -Wall -Wextra -Werror -fsyntax-only $f; done
YAML
복사
하나의 action(workflow)은 다수의 job들로 구성됩니다. 각각의 job은 독립된 환경에서 별도로 실행됩니다. 따라서 여러 개의 검사를 동시에 진행할 수 있으며, 각각의 결과를 받아볼 수 있습니다.
여기에서는 컴파일 오류를 확인하는 check_compile_error와 컨벤션 오류를 확인하는 check_42_norm 작업이 실행됩니다. 아직 프로젝트를 막 시작한 단계여서 별도의 규칙을 만들지는 않았지만, Makefile의 relink 여부와 norm에서 필수로 하는 컴파일 조건들이 있는지 확인하는 작업을 추가할 예정입니다.

트리거 조건

on: push: pull_request:
YAML
복사
Action설정 파일은 실행 조건을 설정하는 on 키와, 실행 내용을 설정하는 jobs키를 필수적으로 요구합니다. 위의 설정으로 (1) 모든 브랜치에서 푸시할 때와 (2) 모든 브랜치에서 PR이 있을 때 이 액션이 트리거되도록 만들 수 있습니다.
트리거 조건으로 설정할 수 있는 이벤트들은 이 공식 문서에 자세하게 나와 있습니다.
처음에는 메인 브랜치에만 적용할까도 생각해 봤는데, 다른 브랜치에서도 norm과 컴파일 플래그를 미리 확인해 볼 수 있다면 좋을 것 같아 모든 브랜치를 대상으로 이 액션을 적용했습니다.
branch protection과 action을 연계하면 좋은 시너지 효과를 볼 수 있는데, 저는 branch protection rule으로 메인 브랜치에 직접 푸시를 할 수 없도록 만들어 PR을 강제하고, 모든 PR마다 norm을 확인하는 이 Action이 작동하도록 만들어 norm 검사를 통과한 코드만 메인 브랜치에 남아있을 수 있도록 만들었습니다.
거기에 추가로 메인 브랜치 PR을 승인하기 위해 반드시 피어리뷰를 거쳐야 하도록 만들면 실수로 중요한 파일을 날리거나, 잘못된 코드가 올라가 오랜 시간 디버깅해야 하는 일을 미리 예방할 수 있습니다.

작업 명세

check_42_norm: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: install 42 norminette run: | sudo apt update sudo apt install python3 -y python3 -m pip install --upgrade pip setuptools python3 -m pip install --upgrade norminette - name: check for 42 norminette requirements run: | echo checking files: $(git ls-files) norminette .
YAML
복사
세부 작업들은 jobs키 아래의 오브젝트들로 정의됩니다. 오브젝트의 키가 작업의 이름이 되고, 작업은 steps에 정의된 내용을 순차적으로 실행합니다. 기본적으로 각 job은 병렬적으로 실행되지만, needs 키를 이용해 종속성을 정의하면 순차적으로 실행되도록 만들 수도 있습니다.
runs-on키는 실행환경을 지정합니다. 사용하는 요금제에 따라 다르지만, 우분투, 윈도우, 맥 환경은 기본적으로 제공됩니다. 저는 우분투 환경 기반인 ubuntu-latest이미지를 사용했습니다.
Github Action 실행 환경에 대해: Github에서 기본 제공하는 컨테이너 외에도 개인 서버를 이용하여 Action 자동화를 수행할 수 있습니다. 개인 서버를 이용한다면 과도한 Action 이용으로 발생하는 추가 과금 문제를 해결할 수도 있고, 필요한 요구사항(디펜던시)들을 Action이 트리거될 때 마다 설치할 필요도 없어 시간이 단축됩니다. 다만 이 글에서는 Github에서 제공하는 컨테이너를 사용하는 방법만 다루겠습니다.
다만 이 기본 이미지는 말 그대로 기본적인 것들만 설정되어 있습니다. 기본 이미지에는 build-essentials 패키지도 설치되지 않아 있어서 작업이 돌 때마다 설치해야 합니다. 또한 푸시한 코드를 확인하기 위해서는 Github 인증 정보를 저장하고 저장소에서 pull해 와야 하는데, 이런 설정도 직접 해줘야 합니다.
다행이 Github Action은 사전 설정을 이용할 수 있는 기능을 제공합니다. uses키를 이용해 재사용 가능한 워크플로우 템플릿을 사용할 수 있습니다. actions/checkout은 대표적인 템플릿으로, 해당 브랜치의 가장 최근 코드를 pull해오는 기능을 제공합니다.
actions/checkout에 작업이 끝난 후에 나머지 작업들이 실행되므로, 인증토큰 등에 대해 신경쓸 필요 없이 편하게 norm을 검사하는 코드만 실행할 수 있습니다.
steps키의 요소들은 말 그대로 실행할 동작들을 의미합니다. 위 코드처럼 기능별로 분리해 여러 개의 작업들을 순차적으로 실행할 수 있습니다. 터미널에서 명령어를 입력하는 것 처럼, run키의 하위 항목들로 실행할 동작들을 지정해주면 됩니다.

정리

Github Action을 이용해 코드 검사를 자동화하는 방법을 알아봤습니다. Action을 잘 활용하면, 테스트 실행 뿐 아니라 자동 배포 등 CI/CD에 필요한 다양한 기능들을 수행할 수 있습니다. 아쉽게도 42서울의 깃은 외부 접근이 불가능해 '메인 브랜치 머지가 발생하면 내부 깃에 변경사항을 푸시하는 기능'이나 '내부 깃에 변경사항이 발생하면 깃허브의 깃도 업데이트하는 기능'등은 추가하지 못했습니다.
아주 기본적인 수준의 워크플로우지만, 어떻게 Action을 사용할 수 있는지와 스크립트를 작성하는 데에 도움이 되었으면 좋겠습니다.