CI/CD
는 애플리케이션 개발 단계를 자동화하여 애플리케이션을 보다 짧은 주기로 고객에게 제공하는 방법이다.CI
는 개발자를 위한 자동화 프로세스인 지속적인 통합(Continuous Integration)을 의미한다. CI를 성공적으로 구현할 경우 애플리케이션에 대한 새로운 코드 변경사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되므로 여러 명의 개발자가 동시에 애플리케이션 개발과 관련된 코드 작업을 할 경우 서로 충돌할 수 있는 문제를 해결할 수 있다.CD
는 지속적인 서비스 제공(Continuous Delivery) 또는 지속적인 배포(Continuous Deployment)를 의미하며 이 두 용어는 상호 교환적으로 사용된다. 두 용어 모두 파이프라인의 추가 단계에 대한 자동화를 뜻하지만 때로는 얼마나 많은 자동화가 이루어지고 있는지 설명하기 위해 별도로 사용되기도 한다.지속적인 제공
은 개발자들이 애플리케이션에 적용한 변경 사항이 버그 테스트를 거쳐 리포지토리에 자동으로 업로드 되는 것을 뜻하며, 운영팀은 이 리포지토리에서 애플리케이션을 실시간 프로덕션 환경으로 배포할 수 있다.지속적인 배포
는 개발자의 변경 사항을 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리스 하는 것을 의미한다. 이는 애플리케이션 제공 속도를 저해하는 수동 프로세스로 인한 운영팀의 프로세스 과부하 문제를 해결한다..env
파일을 통해 환경 변수에 접근하고, Github Actions에서 배포할 때에는 Actions Secrets을 통해 환경 변수에 접근할 수 있지 않을까?.env
파일에 존재하는 환경 변수 중, 프로덕션 단계에서 필요한 변수를 Actions Secrets에 추가하고 Action이 트리거 될 때 자동으로 프로덕션 환경을 위한 환경 변수 파일을 생성해주도록 하겠다.먼저 저희에게 다음과 같은 환경 변수가 있다고 가정해보자.
# .env 파일에 저장된 환경 변수 REACT_APP_DOMAIN=https://domain.co.kr REACT_APP_DEBUG=false
echo
인데, 해당 명령어는 콘솔 창에 인수로 받은 문자열을 출력하는 아주 단순한 명령어이다.test.txt
파일에 저장하는 커맨드이다.echo "Hello, World!" >> test.txt
test.txt
파일이 존재하지 않는다면, 파일을 생성한 후 문자열을 입력하게 된다.$
를 붙여줘야 하는데, 만약 다음과 같이 env
옵션을 설정하지 않는다면 Runner는 해당 변수를 찾지 못해 올바르게 환경 변수를 설정할 수 없다..env
파일의 업로드 없이, 환경 변수를 설정한 상태에서 배포가 가능하다.name: Automatically Deployment
on: [push]
jobs:
deployment:
runs-on: ubuntu-latest
# 해당 Job의 이름을 아래와 같이 설정하여 Actions 탭에서 확인할 수 있게 설정합니다.
name: Deploying to surge
steps:
# 해당 레포지토리로 check-out하는 Action을 불러왔습니다.
- uses: actions/checkout@v2
# Node 환경을 설정하여 npm 커맨드를 사용할 수 있도록 하는 Action을 불러옵니다.
# 여기에서는 14 버전을 사용하고 있습니다.
- uses: actions/setup-node@v2
with:
node-version: '14'
# Github Repository Secrets를 통해 환경 변수 파일을 생성합니다.
- name: Generate Environment Variables File for Production
run: |
echo "REACT_APP_DOMAIN=$REACT_APP_DOMAIN" >> .env.production
echo "REACT_APP_DEBUG=$REACT_APP_DEBUG" >> .env.production
env:
REACT_APP_DOMAIN: ${{ secrets.REACT_APP_DOMAIN }}
REACT_APP_DEBUG: ${{ secrets.REACT_APP_DEBUG }}
# 해당 프로젝트에서 사용하는 모든 라이브러리와 Surge를 설치합니다.
- name: Install Dependencies and Surge
run: |
npm install
npm install surge --global
# React 프로젝트를 빌드합니다.
- name: Build React Application
run: npm run build
# Surge에 빌드된 파일을 배포합니다.
- name: Deploy React Application to Surge
run: surge ./build ${{ secrets.SURGE_DOMAIN }} --token ${{ secrets.SURGE_TOKEN }}
이제 마지막으로, 배포 과정을 진행해 줄 workflow 파일을 작성하자!
배포 단계는 아래와 같다.
프로젝트의 루트 디렉토리에 .github/workflows 폴더를 생성하고, 아래와 같이 main.yaml 파일을 생성한다.
# master-deploy-work.yml
name: main
on:
push:
branches:
- main # main 브랜치에서 push 이벤트가 일어났을 때 실행
pull_request:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@main
- name: Generate Environment Variables File for Production # Github Repository Secrets를 통해 변수 파일을 생성
run: |
echo "REACT_APP_AUTH_SERVER=$REACT_APP_AUTH_SERVER" >> .env.production
echo "REACT_APP_API_SERVER=$REACT_APP_API_SERVER" >> .env.production
env:
REACT_APP_AUTH_SERVER: ${{ secrets.REACT_APP_AUTH_SERVER }}
REACT_APP_API_SERVER: ${{ secrets.REACT_APP_API_SERVER }}
# 실행 속도를 빠르게 하기 위해 설치된 Node 모듈을 캐시하도록 설정합니다.
- name: Cache node modules
uses: actions/cache@v2
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Install Dependencies
run: yarn
- name: Build
run: yarn build
env:
CI: ""
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
aws s3 cp \
--recursive \
--region ap-northeast-2 \
build s3://admin.pops.show
https://ji5485.github.io/post/2021-06-26/create-env-with-github-actions-secrets/
https://velog.io/@seeh_h/AWS와-github-action을-이용해-배포-자동화-하기
https://velog.io/@1nthek/GitHub-Action으로-AWS-S3에-배포-자동화
https://velog.io/@2pandi/CICD와-github-Actions를-통한-클라이언트-배포feat.-AWS-s3