[CI/CD] Github Actions로 Github Pages 배포 자동화하기

chaevivi·2023년 8월 17일
0
post-thumbnail

CI/CD란?

CI/CD (Continuous Integraion/Continuous Delivery)는 지속적 통합/지속적 배포를 말하는 것으로 애플리케이션 개발 단계를 자동화하여 애플리케이션을 더욱 짧은 주기로 고객에게 제공하는 방법이다.
CI/CD는 새로운 코드 통합으로 인해 개발 및 운영팀에 발생하는 문제(일명 "통합 지옥")를 해결하기 위한 솔루션이다. (redhat 참고)

보통 하나의 애플리케이션을 만들 때, 한 번에 끝나지 않는다. 불규칙적으로 생기는 버그와 수정 사항들, 그리고 기능 추가 등 배포를 해도 끊임없이 발생하는 문제점들을 고치기 위해 여러 번 다시 배포를 해야 하는 경우가 생긴다.

만약 이미 배포한 애플리케이션에 수정 사항이 생겨 코드를 수정했다면 그 수정 사항이 해당 애플리케이션에 바로 반영되지 않는다. 이를 위해 '통합' 과정은 필수지만, 이 '통합' 과정은 꽤나 어렵고 복잡하다. 그래서 지속적으로 통합하고 배포해주는 자동화 서비스들이 많이 생겨났다. (Jenkins, Github Actions, Travis CI 등)

현재 리액트로 만든 프로젝트 중 하나를 Github Pages로 배포를 했기 때문에 Github Actions로 CI/CD 자동화를 구축해보려 한다. 리액트 프로젝트를 Github Pages로 배포하는 과정은 이 포스트📄에서 확인하길 바란다.



1. Github Actions란?

Github Actions는 빌드, 테스트, 배포 파이프라인을 자동화해줄 수 있는 CI/CD 플랫폼이다. Github 저장소에서 매 pull request에 대한 빌드와 테스트 workflows를 생성하거나, 병합된 pull request를 배포해 줄 수 있다.

Github Actions의 구성 요소에는 Workflows, Events, Jobs, Actions, Runners가 있다. 각각에 대해서 간단하게 살펴보자. 자세한 내용은 Github Actions Docs에서 확인할 수 있다.


(1) Workflows

  • 워크플로우는 하나 이상의 작업(jobs)을 수행할 수 있는 구성 가능한 자동화 프로세스이다.
  • 워크플로우들은 저장소에 체크인된 YAML 파일로 정의되며, 저장소 내의 이벤트에 의해 트리거되거나, 수동으로 트리거되거나, 정의된 스케줄에 따라 트리거된다.
  • 워크플로우들은 저장소 내의 .github/workflows 디렉토리에 정의되며, 하나의 저장소는 각각 다른 일들을 수행할 수 있는 여러 개의 워크플로우들을 가질 수 있다.

(2) Events

  • 이벤트는 저장소 내에서 발생하는 특정한 활동으로 워크플로우를 트리거시킨다.
  • 특정한 활동이란 Github에서 풀 리퀘스트(pull request)를 하거나, 이슈가 열리거나 저장소에 커밋을 푸시(push)할 때 발생한다.
  • REST API에 요청을 보내거나 수동으로 스케줄에 따라 실행되도록 워크플로우를 트리거할 수 있다.

(3) Jobs

  • 작업은 동일한 실행 환경(runner)에서 실행되는 워크플로우의 일련의 과정이다.
  • 각 단계는 실행될 예정인 쉘 스크립트이거나, 실행 예정인 액션들이다.
  • 단계들은 순서대로 실행되고 서로 독립되어 있다.
  • 각 단계가 동일한 실행 환경(runner)에서 실행된다면, 다른 단계에 데이터를 공유할 수 있다.

(4) Actions

  • 액션은 Github Actions 플랫폼을 위한 커스텀 애플리케이션으로 복잡하지만 자주 반복되는 일을 수행한다.
  • 액션을 사용하면 워크플로우 파일에 적은 많은 양의 반복되는 코드를 줄일 수 있다.
  • 액션은 Github에서 git 저장소를 풀(pull)할 수 있고, 빌드 환경에 올바른 도구체인(toolchain)을 설정하거나, 클라우드 공급자에게 인증을 설정할 수 있다.

(5) Runners

  • 러너는 워크플로우가 트리거될 때 해당 워크플로우를 실행하는 서버이다.
  • 각각의 러너는 한 번에 하나의 작업을 수행한다.
  • Github는 워크플로우를 실행할 수 있는 Ubuntu Linux, Microsoft Windows, macOS 러너를 제공한다.
  • 각각의 워크플로우는 새롭게 프로비저닝된 가상 머신에서 실행된다.


2. Github token 생성하기

Github token은 workflow에서 사용하기 위해 Github가 자동으로 생성한 것으로 워크플로우 작업 중 인증하는데 사용한다. 자세한 내용은 Github Docs에서 확인할 수 있다.

Github에서 오른쪽 상단에 자신의 프로필을 누르고 settings > 왼쪽 탭 제일 아래에 있는 Devloper settings > 왼쪽 탭의 Personal access tokens > Tokens(classic) 으로 들어간다.

이 곳에서 개인 토큰을 생성할 수 있는데 여기서 Generate new token (classic)을 누른다.


그러면 이러한 페이지가 뜨는데 'Expiration' 만료 기한을 정하고 workflow를 선택한 후 하단의 Generate token 버튼을 누르면 개인 토큰이 생성된다. 이 과정에서 토큰을 복사해두지 않으면 다시 확인할 수 없기 때문에 꼭 복사해둔다.


토큰을 복사했으면 프로젝트의 레포지터리의 Settings 탭 > 왼쪽 탭의 Secrets and variables > Actions로 들어간다. 그리고 New repository secret을 클릭한다.

그리고 Name에 이름을 입력해주고 Secret에 복사해 둔 토큰을 복사한 후 Add secret을 클릭하면 workflow에서 사용할 수 있는 토큰 설정이 완료된다.



3. workflow 생성하기

자동화해줄 프로젝트의 레포지터리에 들어가면 Actions 탭이 있다. Actions 탭에서 workflow를 생성할 수 있다.


(1) 프로젝트 배포 전

여기서 'set up a workflow yourself'를 클릭하거나 아래의 'simple workflow'를 클릭하면 되는데, 'simple workflow'를 클릭하는 것을 추천한다. 'simple workflow'에는 이미 최소한의 구조가 갖춰져 있기 때문에 조금 더 쉽게 워크플로우를 생성할 수 있다.

Github pages로 배포하지 않았더라도 다양한 워크플로우가 있으므로 잘 선택해 사용하면 된다.


(2) 프로젝트 배포 후

프로젝트를 이미 배포했다면 배포 전 화면과는 다르게 되어 있을 것이다. 여기서 왼쪽 탭 상단에 New workflow 버튼을 클릭해 준다.


그러면 여러 워크플로우를 볼 수 있는데, 나는 간단한 워크플로우를 만들 것이기 때문에 검색 창에 'simple workflow'를 쳐서 해당 워크플로우를 선택했다.



4. workflow file 살펴보기

'simple workflow'를 선택하면 아래와 같은 파일이 나온다. 어떤 일을 하는지 하나씩 살펴보자.

name: CI

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

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      
      - name: Run a one-line script
        run: echo Hello, world!

      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.

name: CI
  • 워크플로우의 이름을 나타내는 것으로, 해당 워크플로우의 쓰임에 맞춰 이름을 지으면 된다.

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  • 워크플로우가 언제 실행될 지를 정하는 부분이다.
  • "main" 브랜치에 push나 pull request를 할 때마다 워크플로우가 트리거된다.
  • 브랜치 이름은 변경 가능하다

jobs:
  build:
    runs-on: ubuntu-latest
  • 워크플로우가 하는 작업들로 순차적으로 실행되거나 병렬적으로 실행된다.
  • build : 작업이 실행되는 러너의 타입으로 'ubuntu-latest' 실행 환경에서 실행된다는 것을 의미한다.

 steps:
      - uses: actions/checkout@v3
      
      - name: Run a one-line script
        run: echo Hello, world!

      - name: Run a multi-line script
        run: |
          echo Add other actions to build,
          echo test, and deploy your project.
  • 작업의 일부로 실행되는 일련의 작업들을 실행한다.
  • uses : 작업이 레포지터리를 체크아웃해서 액세스할 수 있도록 한다.
  • run : 러너의 쉘을 사용하여 한 줄 또는 여러 줄의 명령을 실행한다.


5. workflow file 설정하기

Github Pages를 Github Actions로 배포를 자동화하기 위해서 설정해야 할 workflow는 아래와 같다.

name: Deployment

on:
  push:
  	# 'main' 브랜치에 푸시할때마다 워크플로우 트리거
    branches: [main]    

jobs:
  deploy:
    runs-on: ubuntu-latest 
     # GITHUB_TOKEN을 사용하는 작업 내의 액세스를 추가하거나 제거
    permissions:   
      # 작업이 릴리스를 만들 수 있도록 허용
      contents: write    
        
    # 동일한 동시성 그룹을 사용하는 단일 작업 또는 워크플로우만 한 번에 실행
    concurrency:    
      # 여러 워크플로우가 있는 경우 다른 워크플로우의 작업이 취소되지 않도록 동시성 그룹을 빌드
      group: ${{ github.workflow }}-${{ github.ref }}   

    steps:
    - uses: actions/checkout@v3

	# node.js 사용
    - uses: actions/setup-node@v3
      with:
        node-version: 18 
	
    # npm install 보다 빠른 npm ci로 빌드 및 테스트
    - run: npm ci 
    - run: npm run build
    
    - uses: peaceiris/actions-gh-pages@v3
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}     
        # 배포할 디렉토리 이름 (꼭 확인!)
        publish_dir: ./build

이렇게 워크플로우 파일 설정이 완료 후 커밋하면 자동으로 배포가 시작된다! 🙌



6. 에러 해결

실제로 프로젝트를 구현 후 deploy 과정에서 계속 에러가 발생했다. 에러 내용을 보니 Run npm ci 부분에서 발생했다.

이는 프로젝트를 빌드할 때 yarn만을 이용해서 생긴 문제였다. yarn으로 프로젝트를 빌드하면 package.json 파일만 생긴다. Run npm ci 구문을 실행하기 위해서는 package-lock.json 파일이 필요하기 때문에 배포할 프로젝트에서 npm install 을 해주면 된다.




출처
🔗 https://www.redhat.com/ko/topics/devops/what-is-ci-cd?cicd=32h281b
🔗 https://docs.github.com/ko/actions/learn-github-actions/understanding-github-actions
🔗 https://docs.github.com/en/actions/security-guides/automatic-token-authentication

profile
직접 만드는 게 좋은 프론트엔드 개발자

0개의 댓글