Github Actions를 사용해 간단 CI 작성하기 (feat. Next.js 프로젝트)

허지예·2024년 8월 6일
0

새로 시작하는 개인 프로젝트 세팅을 하고 있다.

요번에는 이것 저것 새로운 것들을 하려고 하는데, 그 중 하나가 github actions를 활용해 자동화를 이것저것 달아보는 것이다.

오늘은 github actions로 CI/CD 중에 일단 CI를 먼저 작성해보자~!



오늘 간단히 넣어 볼 자동화는 다음과 같다!


1. PR 생성 / 업데이트 시에 build, test 성공 확인하기

제일 기본적인 CI 자동화다


2. 특정 브랜치 머지 제한하기

요번에는 release 브랜치를 디폴트 브랜치로 두고, dev, hotfix 브랜치에서만 release 브랜치로 PR를 생성할 수 있도록 할 것이다.

실수로 일반 feature 브랜치를 release 브랜치에 머지하는 일이 없도록 이 부분을 검사하는 workflow를 만들어 두자.


3. dev, hotfix로의 PR이 머지되면 관련 이슈를 닫기

원래 기본적으로 default 브랜치인 release 브랜치로 머지해야 issue가 닫혀야 한다.

근데 나는 이번 개인 프로젝트에서 issue들을 일종의 todo list로 보고 관리를 할 예정이기 때문에 dev, hotfix에 머지가 되면 관련 이슈를 닫아서 치워두려고 한다.


위 3가지를 작성하고, 1, 2번 같은 경우에는 통과하지 못하면 merge를 못하도록 막는 설정까지 해둘 것이다.



1. PR 생성 / 업데이트 시에 build, test 성공 확인하기

다음과 같이 .github/workflows/CI.yml 파일을 작성한다.

name: CI

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  build:
    name: 🏗️ 프로젝트 빌드를 해본다
    runs-on: ubuntu-latest

    steps:
      - name: ① 레포지터리 체크아웃
        uses: actions/checkout@v4

      - name: ② pnpm 다운로드
        uses: pnpm/action-setup@v4
        with:
          version: 8
          run_install: false # 캐시를 사용하기 위해 false

      - name: ③ node 설정
        uses: actions/setup-node@v4
        with:
          node-version: 18
          cache: 'pnpm' # pnpm-lock.yaml 사용해 캐시

      - name: ④ 의존성 다운로드
        run: pnpm install

      - name: ⑤ 프로젝트 빌드 실행
        run: pnpm run build

  unit-test:
    name: ✅ 단위 테스트를 한다
    runs-on: ubuntu-latest

    steps:
      - name: ① 레포지터리 체크아웃
        uses: actions/checkout@v4

      - name: ② pnpm 다운로드
        uses: pnpm/action-setup@v4
        with:
          version: 8
          run_install: false # 캐시를 사용하기 위해 false

      - name: ③ node 설정
        uses: actions/setup-node@v4
        with:
          node-version: 18
          cache: 'pnpm' # pnpm-lock.yaml 사용해 캐시

      - name: ④ 의존성 다운로드
        run: pnpm install

      - name: ⑤ 단위 테스트 실행
        run: pnpm run unit-test
  • ① 레포지터리 체크아웃

    • actions/checkout@v4`를 사용해 현재 레포지터리를 가져온다
  • ② pnpm 다운로드

    • 현재 프로젝트에서는 pnpm를 사용하기 때문에 pnpm/action-setup$v4를 사용해 pnpm을 다운로드한다.
  • ③ node 설정

    • node 설정을 하고, 최적화를 위해 캐시를 사용한다.
  • ④ 의존성 다운로드

    • 패키지를 내려받는다.
  • ⑤ 프로젝트 빌드 실행 / 단위 테스트 실행

    • 원하는 일을 한다.

🔄 리팩토링: 로컬 액션 사용해 중복된 부분 분리하기

기존 workflow 파일에서는 ① ~ ④까지 동일한 step를 밟는데, 이를 따로 선언해두고 재사용하려고 한다.

.github/actions/project-setup/action.yml 작성

name: 🏗️ 프로젝트 실행 환경을 설정한다
runs:
  using: 'composite'
  steps:
    - name: ① pnpm 다운로드
      uses: pnpm/action-setup@v4
      with:
        version: 8
        run_install: false # 캐시를 사용하기 위해 false

    - name: ② node 설정
      uses: actions/setup-node@v4
      with:
        node-version: 18
        cache: 'pnpm' # pnpm-lock.yaml 사용해 캐시

    - name: ③ 의존성 다운로드
      run: pnpm install
      shell: bash

📌 point!

  • ④에 shell: bash 추가한 이유

    • workflow에서는 run 단계에서 기본적으로 shell이 bash로 설정되지만 action에서는 설정되지 않기 때문에 명시적으로 표기를 해야 한다.
  • using: 'composite'의 의미

    • GitHub Actions에서 여러 스텝을 하나의 액션으로 묶어 재사용할 수 있게 하는 기능
    • 이렇게 선언된 action를 "Composite Actions"라고 불리며, 이를 통해 공통적인 작업을 정의하고 여러 workflow에서 재사용할 수 있다

이를 활용해서 CI.yml 수정

name: CI

on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  build:
    name: 🏗️ 프로젝트 빌드를 해본다
    runs-on: ubuntu-latest

    steps:
      - name: ① 레포지터리 체크아웃
        uses: actions/checkout@v4

      - name: ② 프로젝트 실행 환경 설정
        uses: ./.github/actions/project-setup

      - name: ③ 프로젝트 빌드 실행
        run: pnpm run build

  unit-test:
    name: ✅ 단위 테스트를 한다
    runs-on: ubuntu-latest

    steps:
      - name: ① 레포지터리 체크아웃
        uses: actions/checkout@v4

      - name: ② 프로젝트 실행 환경 설정
        uses: ./.github/actions/project-setup

      - name: ③ 단위 테스트 실행
        run: pnpm run unit-test


2. 특정 브런치 머지 제한하기

.github/workflows/BRANCH__validate_branch.yml 작성하기

name: 브랜치 검증

on:
  pull_request:
    types: [opened, synchronize, reopened, edited]

jobs:
  check-pr-branches:
    name: 🔍 dev, hotfix 브랜치만 release에 머지할 수 있다
    runs-on: ubuntu-latest

    steps:
      - name: ① PR 브랜치 검증
        env:
          BASE_BRANCH: ${{ github.event.pull_request.base.ref }}
          HEAD_BRANCH: ${{ github.event.pull_request.head.ref }}
        run: |
          if [[ "$BASE_BRANCH" == "release" ]]; then
            if [[ "$HEAD_BRANCH" != "dev" && "$HEAD_BRANCH" != "hotfix" ]]; then
              echo "⚠ dev 브랜치나 hotfix 브랜치만 release 브랜치에 머지할 수 있습니다."
              exit 1
            fi
          fi

📌 point!

  • edited 타입: PR의 제목이나 base 브랜치, PR 본문 등이 수정될 경우 실행

  • 잘못된 PR일 경우 exit 1로 오류를 발생하도록 함



3. dev, hotfix`로의 PR이 머지되면 관련 이슈를 닫기

.github/workflows/ISSUE__close-issue-on-pr-merged.yml 작성하기

name: PR 관련 이슈 닫기

on:
  pull_request:
    types: [closed]
    branches: [dev, hotfix]

jobs:
  close-issues:
    name: 🔒 관련 이슈를 닫는다
    if: github.event.pull_request.merged == true
    runs-on: ubuntu-latest

    steps:
      - name: ① PR 이름에서 이슈 번호 찾기
        id: extract_issue
        run: |
          ISSUE_NUMBER=$(echo "${{ github.event.pull_request.title }}" | grep -o -E "/#[0-9]+" | head -n 1 | tr -d '/#')
          echo "issue_number=${ISSUE_NUMBER}" >> $GITHUB_ENV

      - name: ② 이슈 닫기 요청하기
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ISSUE_NUMBER: ${{ env.issue_number }}
        run: |
          curl -X PATCH -H "Authorization: token $GITHUB_TOKEN" \
            -H "Accept: application/vnd.github.v3+json" \
            https://api.github.com/repos/${{ github.repository }}/issues/$ISSUE_NUMBER \
            -d '{"state":"closed"}'

📌 point!

  • ① PR 이름에서 이슈 번호 찾기
    • 현재 feature 브랜치 네이밍 규칙은 feature/#[issue번호]-... 다.
      그래서 /#[0-9]+ 정규식을 사용해 이슈 번호를 알아내게 했다.
  • ② 이슈 닫기 요청하기
    • GITHUB_TOKEN을 이용해 이슈를 닫게 되는데, 해당 토큰에 권한 설정을 해줘야 한다.
    • 레포지터리 Settings > Actions > General > Workflow permissions에서 Read and write permissions 체크하기
    • 그러지 않으면 403 에러가 뜬다.


+) workflow 결과에 따라 PR merge 제한하기

레포지터리 Settings > Rules > Rulesets > [New ruleset]

  • Enforcement status를 Active로 바꾼다.

  • Target branches에 브랜치를 추가한다 (base 브랜치 기준)

  • 아래 Rules에서 Require status checks to pass 체크한다.

    • Show additional settings 누리고 Status checks that are required에 체크할 jobs 작성

    • jobs 이름 기준으로 작성한다.

설정을 완료하면 다음과 같이 된다.

필수 workflow로 설정해 둔 것들을 Required가 표시되고, 이 중 하나라도 통과하지 못하면 mergo 버튼이 비활성화된다.



끝! 간단하게만 사용해봤다. 다음엔 husky를 사용해봐야지

profile
대학생에서 취준생으로 진화했다가 지금은 풀스택 개발자로 2차 진화함

0개의 댓글

관련 채용 정보