Development/Git

Github Actions 사용해보기

duckworth 2023. 4. 26. 18:20

요즘 개발 프로세스의 자동화가 유행하고 있습니다.

그 대표 주자들 중 하나가 CI/CD인데요, 오늘은 가장 널리 쓰이는 Github Actions에 대해 알아보고 사용해보려 합니다.

CI/CD란?

CI

CIContinuous Integration(지속적인 통합)의 약자입니다. 

버그 수정이나 새로 만드는 기능들이 메인 리파지토리에 빌드되고 테스트 되어서 머지되는 기능을 합니다.

CI에서 중요한 기능은 2가지입니다.

 

1. 코드 변경 사항을 주기적으로 빈번하게 머지(Merge)

: 2명의 개발자가 오랜 기간 코드를 작성하고 같은 리파지토리에 머지를 하려고 할 때, 서로 다른 코드에서 반드시 충돌이 일어납니다. 이 충돌을 해결하는 시간이 많이 걸릴 가능성 역시 높습니다.

위의 문제점을 방지하기 위해 최대한 작은 단위로 나누어서 개발하고 지속적으로 통합하는 것이 중요합니다.

 

2. 통합을 위한 단계(Merge, Build, Test)의 자동화

: 개발자들은 매일 몇번 씩 리파지토리에 머지를 합니다. 이 머지 된 코드들을 팀에서 만든 CI 서버에서 리뷰하게 됩니다.

CI 서버에서는 머지 된 코드들을 빌드해보고 유닛 테스트 같은 방식으로 테스트하여 통과가 되면 초록색 사인을 받고 나중에 배포할 때 머지했던 코드가 반영이 됩니다.

 

작은 단위로 머지하고 빌드하고 테스트하기 때문에 문제점을 빨리 파악할 수 있고 코드의 퀄리티와 개발 생산성이 향상됩니다.

CD

CDContinuous Delivery(지속적인 제공)의 약자입니다. CD는 가끔 Continuous Deployment(지속적인 배포)로 쓰일 때도 있습니다.

 

CI 작업(빌드, 테스트) 후에 CD 작업은 Delivery와 Deployment로 나뉩니다.

Continuous Delivery

CI 작업 후에 수행하는 2단계인 Prepare Release(출시 준비) Deploy Release(배포 출시) 단계 사이에서 개발자가 출시가 가능할지 판단하는 작업을 수동으로 하고 사용자들에게 출시 하게 됩니다.

Continuous Deployment

Continuous Delivery와 동일한 단계를 거치지만 개발자가 판단하고 출시하는 최종 단계 과정까지 자동화시키는 개발 방식입니다.

Github Actions란?

특정한 이벤트가 발생했을 때 원하는 일을 자동으로 수행할 수 있게 해주는 툴입니다.

5가지 중요한 용어가 있습니다.

Event

PR을 main 브랜치로 머지할 때나 커밋을 푸쉬할 때, 이슈를 누군가가 열 때 필요한 이벤트가 있으면 지정할 수 있습니다.

Workflow

이벤트가 발생했을 때, 어떤 스크립트를 자동화 할 것인지 명시합니다. 명시하는 것은 Workflow가 소유한 Jobs로 가능합니다.

Jobs

여러 개의 Job을 실행할 수 있으며, 병렬적으로 순차적으로도 실행 할 수도 있습니다. Job 내부에서는 Step 1, Step 2 같은 순서를 가지고 npm test, install 같은 명령어를 수행할 수 있습니다. 

저희가 흔히 사용하는 명령어뿐만 아니라 Github Actions라는 이름 그대로 Action을 수행할 수도 있습니다.

Action

Job 내부에서 명령어와 동일한 과정으로 실행됩니다. 

Action은 반복 작업을 자동화하기 위한 일종의 매커니즘이며, npm의 라이브러리처럼 이미 잘 만들어진 것들이 많기 때문에 대부분의 경우에 저희는 필요한 Action을 가져다 쓰면 됩니다.

자세한 코드는 밑의 예제에서 살펴보겠습니다.

Runner

Job을 실행해줍니다. VM이나 Docker 컨테이너 역할을 합니다. Job은 각각의 독립된 Runner라는 컨테이너에서 실행됩니다.

프로젝트에 적용해보기

이제 테스트를 수행하는 작업을 자동화 해보겠습니다.

먼저 간단한 리액트 앱이나 평소 사용하시는 웹 프로젝트를 만들어주세요. 이미 개발중인 프로젝트도 좋습니다.

먼저 프로젝트 루트 폴더에 ".github/workflows" 폴더를 만들고 ci.yml이라는 파일을 만들어주세요. yml 파일명은 무엇이든 상관없습니다.

폴더 이름은 반드시 지켜줘야합니다. 저장소에 커밋된 yml 파일을 기반으로 Github 서버에서 CI/CD를 수행해주기 때문입니다.

// .github/workflows/ci.yml

name: Testing CI
on: push
jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.14.2
      - run: npm ci
      - run: npm test

ci.yml을 위와 같이 작성해주세요. 이제 한 줄씩 분석해보면서 알아보겠습니다.

name: Testing code

name은 Workflow를 설명하는 이름을 작성합니다. 딱히 제한 사항이 없습니다.

on: push

on은 저희가 작성한 Workflow가 발생할 이벤트를 지정해줍니다. 현재 위 예제에서는 깃허브 저장소에 push가 발생하면 Workflow가 실행됩니다. on은 아래 코드처럼 다양한 방법으로도 사용해볼 수 있습니다.

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

push가 main 브랜치에서 발생하거나 pull 요청이 main 브랜치에 발생한다면 Workflow가 실행되는 코드입니다.

원할 때만 지정된 조건으로 실행하고 싶을 때 유용한 코드이기도 합니다.

jobs:
  test:
    runs-on: ubuntu-latest

Workflow가 소유한 job을 실행하는 코드입니다. test 할 때 실행되며, runs-on은 우분투 최신버전으로 실행한다는 뜻입니다.  runs-on은 우분투뿐만 아니라 MAC OS, Windows 역시 가능합니다.

만약에 다양한 노드버전이나 OS로 실행하고 싶으시면

strategy: 
  matrix:
    node-version: [12.x, 14.x, 16.x]
    os: [ubuntu-latest, windows-latest, macos-latest]

이런식으로 strategy와 matrix를 runs-on 코드 밑에 작성해주시면 됩니다. 여러 node-version과 os를 전부 실행해볼 수 있습니다.

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.14.2
      - run: npm ci
      - run: npm test

steps는 처음에 actions/checkout@v3를 사용합니다. checkout은 코드 저장소에서 특정 브랜치로 전환하는 작업을 해줍니다. checkout을 하기위해서는 원격 저장소에 올린 코드를 로컬 컴퓨터로 받는 작업이 반드시 필요합니다.

checkout이 하는 것을 자세히 살펴보겠습니다.

 

  • git init : 명령어를 통해 작업 디렉토리를 로컬 저장소로 만듭니다.
  • git config : 명령어를 통해 각종 인증 관련 정보를 설정합니다.
  • git fetch : 명령어를 통해 원격 저장소로부터 코드를 받아옵니다.
  • git checkout : 명령어를 통해 main 브랜치로 전환합니다.
  • git log : 명령어로 마지막 commit의 해시 값을  확인합니다. 

위의 번거로운 작업들을 Github Actions에서 제공해주는 checkout action 덕분에 편하게 코드 한 줄로 수행이 가능합니다!

 

actions/setup-node@v3는 개발자가 설정한 Node.js 버전을 사용하며 캐싱 기능을 수행해줍니다.

with으로 node 버전을 지정해주거나 cache 설정을 할 수 있습니다.

      - uses: actions/setup-node@v3
        with:
          node-version: 16.14.2
          cache: 'npm'

- run: npm ci는 ci 작업을 실행하는 명령어이며, - run: npm test는 저희의 프로젝트를 jest나 testing-library로 테스트 할 때와 마찬가지로 테스팅을 수행해줍니다.

      - run: npm ci      
      - run: npm test
      - run: npm run build

위의 코드처럼 ci와 test 후에 프로젝트 build를 수행하기도 하지만, 예제 코드는 테스팅만 하는 것이 목적이므로 적지 않았습니다.

 

이제 작성한 yml 파일을 커밋해서 확인해봅시다.

 

커밋한 깃허브 저장소에서 Actions에 들어가주세요.

 

"ci cd bug fix"는 제가 커밋한 코드의 메세지입니다. 클릭해서 눌러보시면 Github Actions의 작업 과정을 확인해보실 수 있습니다.

 

모든 과정이 체크 아이콘이 되있다면 CI/CD 작업에 성공한 것 입니다.

문제 해결

Github Actions를 처음 사용하신다면 흔히 겪는 문제들이 있는데요, 해결 방법을 알려드리려 합니다.

NPM 버전 문제

npm의 버전이 최신 버전이 아닐 때 발생했던 문제입니다.

배포하셨던 Github 저장소의 Actions로 이동해주세요. 그 뒤에 배포하신 CI/CD를 클릭해서 확인해봅시다.

Run npm ci에서 위의 사진과 같은 오류 발생하셨을 경우에 제가 해결했던 방법은 NPM을 최신 버전으로 업데이트 하는 것입니다.

npm install -g npm@latest

Run npm test 무한로딩 (타이머는 계속 돌아감)

테스팅 코드를 작성하고 배포했을 때, Github Actions가 Run npm test 단계에서 에러는 안뜨지만 진행도 안되고 타이머만 돌아갈 때 해결하는 방법입니다.

// package.json

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",    
    "test": "jest", <-- "이 부분을 test": "jest --watch"로 설정하면 버그가 발생합니다.
  },

test 명령어 부분에서 --watch로 설정해두면 배포할 때 무한로딩 버그가 발생합니다. 단순히 --watch를 지워주는 것으로 해결할 수 있습니다.

 

 

Reference

드림코딩님 유튜브 :

https://www.youtube.com/watch?v=iLqGzEkusIw&list=PLv2d7VI9OotQUUsgcTBHuy5vJkSgzVHL0&index=21

DaleSeo님 블로그 :

https://www.daleseo.com/github-actions-checkout/

 

GitHub Actions의 체크아웃(Checkout) 액션으로 코드 내려받기

Engineering Blog by Dale Seo

www.daleseo.com

https://www.daleseo.com/github-actions-basics/

 

GitHub Actions의 소개와 핵심 개념

Engineering Blog by Dale Seo

www.daleseo.com