2023-10-28 · 13 min read · 개발

자동화를 향한 첫걸음 - Github Actions

협업에서 느꼈던 부족한 점

협업을 하며 하나의 프로젝트를 온전히 마무리하면서 개인적으로 느끼기에 부족한 부분들이 존재했다.

이 부분들을 개선하는 것이 무엇보다도 중요할 것이다.

스토리북 관리 부실

작업이 진행되고 컴포넌트가 점점 많아지면서 스토리북 관리가 제대로 이루어지지 않았다. 컴포넌트에 대한 스토리가 없거나 있어도 그것을 팀원 모두가 적극적으로 활용하지 않아서 스토리북을 도입한 효과를 크게 느끼지 못했었다.

왜 이런 문제가 발생하게 되었는지 생각해봤을 때 지속가능한 컴포넌트를 만드는 역량의 부족함, 처음 사용해보는 스토리북의 어려움 등이 있을 것이다.

그 중에서도 내가 생각하기에 가장 큰 원인은 코드 리뷰 과정에서의 번거로움 때문이었던 것 같다.


코드 리뷰 과정에서 리뷰어가 직접 작업 브랜치로 이동해서 npm run storybook을 실행하고 스토리북을 보는 과정이 굉장히 번거롭고 귀찮게 느껴졌다.

그래서 스토리북에서 컴포넌트에 대한 UI 테스트를 진행하기 보다는 그냥 만들어진 화면에서 컴포넌트가 잘 작동하는지가 우선시되었던 것 같다.

배포 과정에서 발생하는 불편함과 두려움

팀 규칙으로 스프린트가 종료되는 주마다 배포를 진행했었다. 하지만 organization에서 이루어진 프로젝트의 경우 vercel로 배포할 시 비용 문제가 발생한다. 그래서 어쩔 수 없이 개인이 포크를 해서 수동으로 배포하는 방식으로 진행하기로 했다.

이 과정에서 다음과 같은 문제가 발생하게 되었다.

  • 더 빠르게 작업 내용에 대한 배포 환경을 확인하고 싶다.
  • 주마다 이루어진 배포 주기로 커다란 작업량에 대한 배포 환경에서 발생한 에러와 원인을 찾기 어렵다.
  • 이러한 과정에서 배포에 대한 불안감이 생겨 새로운 작업, 변화를 두려워하게 된다.

이렇게 부족한 부분들을 살펴보니 자동화에 대한 필요성을 크게 느끼게 되었다.

What is Github Actions?

Github Actions는 빌드, 테스트, 배포 파이프라인을 자동화할 수 있는 지속적 통합 및 지속적 배포 (CI/CD) 폴랫폼이다.

우선 Github Actions에서 어떠한 개념과 용어들이 사용되는지 하나씩 알아보자.

CI/CD

ci-cd

CI/CD의 기본 개념은 지속적인 통합, 지속적인 서비스 제공, 지속적인 배포이다.

단어들에서 알 수 있듯이 우선 중요한 건 지속성이다.

CI/CD 차이

CI는 지속적인 통합(Continuous Integration)을 의미한다. 변경 사항을 병합할 때 빌드 및 테스트를 실행하여 변경 사항이 애플리케이션에 제대로 적용되는지 확인한다.

CD는 지속적인 제공(Continuous Delivery), 지속적인 배포(Continuous Deployment)을 의미한다. 두 용어는 혼용해서 쓰인다.

지속적인 제공과 지속적인 배포도 개발 환경과 운영 환경으로 세분화할 수 있다. 우선 큰 틀에서 바라볼 때는 변경 사항이 적용된 애플리케이션의 배포 자동화라고 볼 수 있다.


개념적으로는 어찌저찌 구분되지만 어쨌든 중요한 것은 끊임없이 테스트하고 배포를 하도록 하여 작은 단위를 유지하도록 하는 것이다.

Workflows

workflow.github/workflows 경로에서 정의된다. workflows 파일명에 주의하자.

yml 파일 하나가 하나의 workflow라고 이해하면 된다. 배포, pr 테스트와 같이 여러 workflow를 구성할 수 있다.

Events

workflow 실행을 트리거하는 저장소에서의 특정 활동이다.

다음과 같이 main 브랜치에 푸시되거나 PR이 발생할 때 활동을 시작한다는 것으로 쉽게 이해할 수 있을 것이다.

on:
push:
branches: [main]
pull_request:
branches: [main]

Jobs

job은 같은 runner에서 workflow 안에 실행되는 step의 집합으로 가상 머신에서 내용을 돌아가게 하는 것이다.

job 또한 여러 개를 만들 수 있다.

jobs:
my_first_job:
name: My first job
my_second_job:
name: My second job

Actions

복잡하지만 자주 반복되는 작업을 수행하는 Github Actions 플랫폼용 사용자 지정 애플리케이션이다. action을 통해 workflow 내 반복적으로 사용되는 코드의 양을 줄일 수 있다.

Runners

트리거된 워크플로를 실행하는 서버이다.

실전으로

기본적인 개념과 용어에 대해 정리가 되었으니 실전으로 도입하자.

이번 글에서 하고자 하는 자동화 영역은 깃허브 organization에서 storybookvercel 배포과 관련된 부분이다.

세부 목적은 다음과 같다.

  • develop 브랜치에 머지되는 PR에서 스토리북 배포 미리보기
  • develop 브랜치에 머지되는 PR에서 vercel 배포 미리보기
  • develop 브랜치에 푸시가 발생했을 때 스토리북 배포 진행하기
  • develop 브랜치에 푸시가 발생했을 때 vercel 배포 진행하기

기본 프로젝트 세팅 명령어는 다음과 같다.

Terminal window
npx create-next-app@latest // NextJS 설치
npx storybook@latest init // 스토리북 설치

그리고 깃허브에서 workflow에 대한 접근을 허용해야 한다.

Settings/Actions/General 경로에서 Workflow permissions을 다음과 같이 변경한다.

workflow-permissions

스토리북 자동화

우선 스토리북과 관련된 부분부터 진행하자.

스토리북 배포가 필요하기 때문에 Chromatic을 활용하고자 한다.

Chromatic에서 프로젝트를 추가해준다. 토큰 번호는 유출되지 않도록 주의하자.

chromatic

Terminal window
npm install chromatic --save-dev
npx chromatic --project-token=토큰 번호

이제 관련된 workflow를 작성하면 된다.

PR이 작성될 때 코멘트에 스토리북 배포 링크가 추가되는 작업을 진행하고자 한다. 코드는 다음과 같다.

.github/workflows/pull_request.yml

name: Pull Request
run-name: ${{ github.actor }}의 Pull Request
on:
pull_request:
branches:
- develop
jobs:
storybook:
runs-on: ubuntu-latest
outputs:
status: ${{ job.status }}
steps:
- name: checkout repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: cache dependencies
id: cache
uses: actions/cache@v3
with:
path: '**/node_modules'
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-storybook
- name: depedency install
if: steps.cache.outputs.cache-hit != 'true'
run: npm ci
- name: publish to chromatic
id: chromatic
uses: chromaui/action@v1
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: comment PR
uses: thollander/actions-comment-pull-request@v1
with:
message: '🚀storybook: ${{ steps.chromatic.outputs.storybookUrl }}'

secrets.CHROMATIC_PROJECT_TOKEN을 보면 알 수 있듯이 깃허브에서 토큰 값을 저장할 수 있도록 해야 한다.

Settings/Secrets and variables/Actions에서 CHROMATIC_PROJECT_TOKEN으로 토큰 번호를 추가한다.

chromatic-project-token

그러면 다음과 같이 PR에서 스토리북 배포 링크 코멘트가 추가되는 것을 확인할 수 있다.

storybook-pr

이제 develop 브랜치에 푸시가 발생했을 때 스토리북 배포가 진행되는 것을 해보자. 배포는 github pages를 활용하고자 한다.

workflow 폴더에 배포 관련 workflow를 추가한다.

.github/workflows/deploy.yml

name: Build and Publish
on:
push:
branches: ['develop']
permissions:
contents: read
pages: write
id-token: write
jobs:
Deploy-Storybook:
runs-on: ubuntu-latest
steps:
- uses: bitovi/github-actions-storybook-to-github-pages@v1.0.0
with:
path: build/storybook

package.json에서도 스토리북 빌드 관련 경로를 다음과 같이 변경한다.

"build-storybook": "storybook build -o build/storybook"

깃허브에서 깃허브 페이지 배포 설정을 진행한다. GitHub Actions로 설정한다.

github-pages

develop 브랜치에 푸시가 이루어지면 성공적으로 깃허브 페이지 배포가 된 것을 확인할 수 있다.

storybook-deploy

배포 자동화

이제 Vercel 배포로 넘어가자. organization으로 진행하면 비용 문제로 제약이 발생한다.

이에 vercel cli를 활용하고자 한다.

다음 명령어를 실행한다.

Terminal window
npm i -g vercel
vercel login
vercel link

명령어에 따라 진행하면 .vercel 폴더가 생성된다.

vercel-id

깃허브 Secrets and variables/Actions에서 다음 세 가지의 secret을 설정한다.

  • VERCEL_ORG_ID (orgId)
  • VERCEL_PROJECT_ID (projectId)
  • VERCEL_TOKEN (참고링크)

vercel-token

이제 관련 workflow를 작성하면 된다.

PR 관련 workflow은 다음과 같다.

name: Pull Request Deployment
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
run-name: ${{ github.actor }}의 Pull Request
on:
pull_request:
branches:
- develop
jobs:
storybook: // ...storybook 관련 코드
Deploy-Preview:
runs-on: ubuntu-latest
environment:
name: Deploy-Preview
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: npm
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- id: deploy
run: echo "url=$(vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }})" >> "$GITHUB_OUTPUT"
- name: comment PR
uses: thollander/actions-comment-pull-request@v1
with:
message: '🚀preview: ${{ steps.deploy.outputs.url }}'

deploy-pr

빠르게 배포 관련 workflow도 작성해보자.

name: Build and Publish
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
on:
push:
branches: ['develop']
permissions:
contents: read
pages: write
id-token: write
jobs:
Deploy-Storybook: // ...storybook 배포 관련 코드
Deploy-Production:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Vercel CLI
run: npm install --global vercel@latest
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

deploy

workflow 관련 전체 코드는 다음 링크에서 확인할 수 있다.

‘자동화를 향한 첫걸음 - Github Actions’ 관련 workflows 코드

참고 문서