pennyway 프로젝트를 진행하면서 github actions를 활용한 CI/CD 파이프라인을 구축하게 되었는데, 해당 과정에 대해 자세하게 이해하면서 넘어가면 좋을 것 같아서 글을 작성해보겠습니다.
해당 게시물에서는 CI Pipeline에 대해서만 다루고, 다음 포스팅에서 CD Pipeline에 대해 다루어보겠습니다.
소프트웨어 개발과정에서 인프라 관리와 개발 프로세스(통합, 테스트 등)를 자동화하여 개발에만 집중하여 더 빠른 제품을 만들어낼 수 있도록 하기 위해 많은 조직에서 DevOps 방식을 채택하고 있다.
CI/CD 파이프라인을 구축하기 위해 많은 도구가 있지만 오늘은 Github Actions와 Amazon Web Services를 이용하여 CI/CD 파이프라인을 구축해보겠다!! 🔥🔥🔥🔥
우선 CI Workflow에서는 eslint를 통해 타입스크립트로 작성된 문법을 검사하고, vitest 프레임워크를 이용하여 유닛 테스트를 진행합니다.
ESLint에서 ES는 Ecma Script를 의미하며, Ecma라는 기구에서 만든 Script, 즉, 표준 자바스크립트를 의미합니다. Lint는 에러가 있는 코드에 표시를 달아놓는 것을 의미합니다.
참고: ESLint 알고 사용하기
test와 lint job의 경우 버전을 명시하고, modules를 다운받는 과정이 중복되어 reusable workflow로 분리하여 사용하였습니다.
우선 reusable workflow는 아래와 같이 작성하였습니다.
# reusable-install-dependencies.yml
name: Install dependencies
on:
workflow_call:
inputs:
task:
type: string
required: true
name:
type: string
required: true
jobs:
install-dependencies:
runs-on: ubuntu-latest
steps:
# 1. 해당 브런치의 코드를 내려받기
- name: Checkout
uses: actions/checkout@v4
# 2. 노드 버전 설치
- name: Setup Node 18.18.0
uses: actions/setup-node@v4
with:
node-version: 18.18.0
cache: yarn
# 3. yarn 버전 설정
- name: Set yarn version
id: set-version
run: yarn set version 1.22.19
# 4. yarn 캐시 경로 불러오기
- name: Get cache dir path
id: yarn-cache-dir-path
run: echo "CACHE_DIR=$(yarn config get cacheFolder)" >> $GITHUB_OUTPUT
# 5. yarn 캐싱
- name: Yarn cache
uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.CACHE_DIR }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-${{ steps.set-version.outputs.YARN_VERSION }}
restore-keys: |
${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}-
# 6. yarn 캐시 체크
- name: Install dependencies
run: |
CACHE_HIT="${{ steps.yarn-cache.outputs.cache-hit }}"
NODE_MODULES_EXISTS=$(test -d "node_modules" && echo "true" || echo "false")
if [[ "$CACHE_HIT" != 'true' || "$NODE_MODULES_EXISTS" == 'false' ]]; then
yarn install
fi
# 7. 해당 task 실행
- name: Test ${{ inputs.task }} with ${{ inputs.name }}
run: yarn ${{ inputs.task }}
lint와 test의 경우 0~6번이 중복되고 있어서 위와 같이 분리하고, 해당 task가 실행되는 실제 test.yml을 다음과 같이 구성하였습니다.
# test.yml
name: Continuous Integration
on:
pull_request:
branches: ['main']
jobs:
lint:
uses: ./.github/workflows/reusable-install-dependencies.yml
with:
task: lint
name: eslint
test:
uses: ./.github/workflows/reusable-install-dependencies.yml
with:
task: test
name: vitest
위와 같이 설정해주면 다음과 같이 성공한 것을 확인할 수 있다!
reusable-workflow를 구축하기 위한 수많은 도전 끝에 결국 성공했다 ㅎㅎ
현재 pennyway 프론트팀에서는 다음과 같이 작업을 진행하기로 하였습니다.
근데 1번 단계에서는 실제로 UI만을 구현하고 PR을 한 이후에 코드 리뷰를 진행하게 되는데 이 과정에서 실제 UI 화면을 보지 않고 코드만 보는 것은 큰 도움이 되지 못한다고 생각하였습니다. 이에 Pull Request 요청에 대한 웹 상에서 미리 보기 기능을 추가하여 코드 리뷰의 질을 향상하고자 AWS Amplify를 적용해보았습니다.
Pull Request 요청에 대한 웹 상에서 미리 보기 기능은 AWS와 Firebase 외 다양한 서비스에서 제공하고 있다.
이 중 AWS Amplify를 선택한 이유는 현재 pennyway 프로젝트에서는 서버에서 AWS를 적극적으로 이용하여 인프라를 관리하고 있기 때문에 추후 비용 추적이나 관리의 용이성을 위해 선택하게 되었다.
우선 적용하기 이전에 AWS Amplify가 무엇인지에 대해 알아보자.
기본적으로 제공하는 CI/CD workflow를 통해 정적 웹 애플리케이션의 글로벌 배포 및 호스팅을 지원하는 완전관리형 서비스로 AWS Amplify 콘솔에서 애플리케이션의 코드 repository를 연결하기만 하면 코드를 커밋할 때마다 프런트엔드와 백엔드의 변경 사항이 단일 워크플로로 배포된다. (아니 이런게 있다고?)
실제 내부 작동 방식을 살펴보면, Git Repository를 연동하고 소스코드를 push하기만 하면 프로젝트가 빌드되고 그 결과물을 호스팅까지해주는 완전관리형 서비스인 것을 확인할 수 있다. 이를 통해 프론트와 백엔드 서버를 구축할 수 있지만, 현재 pennyway 프로젝트에서 AWS Amplify를 이용하는 이유는 Pull Request 요청에 대한 웹 상에서 미리 보기 기능을 추가하기 위함이니 빠르게 적용해보자.
적용하는 방법은 Web previews for pull requests 문서에서 To enable web previews for pull requests 탭에 있는 단계를 따라가면 빠르게 적용할 수 있다. 문서가 편하지 않다면 구경회님이 작성해주신 AWS Amplify로 PR 미리보기를 참고하는 것도 좋을 것 같다!
설정을 완료해주면 아래 이미지와 같이 정상적으로 등록된 것을 확인할 수 있다.
그리고 main 브런치로 PR 요청을 전송해보면, Pull Request Comment로 미리보기 URL이 제공되는 것을 확인할 수 있다.
제가 공부하면서 작성한 게시글인 만큼 틀린 부분이 있을 수 있습니다. 만약 틀렸다거나 오해의 소지가 있는 부분이 있다면 주저없이 저에게 말씀해주세요!! 그럼 행복을 나누어 드릴게요 😀