본문 바로가기

Backend/Git

Use github actions

이번 포스팅에선 github actions 를 사용해보려 합니다.

카테고리 구분은 따로 하는게 좋겠지만 귀찮아서 그냥 git 으로..

 

- What? 

 

github actions 이란 github 에서 CI 와 CD 를 위해 추가된 서비스입니다.

github 저장소에 어떠한 이벤트(ex. push, merge 등)가 발생했을 때 특정 작업이 일어나도록 하거나 반복적으로 도는 작업등을

workflow 의 yml 파일로 정의하여 자동화시켜놓고 linux, window 등의 컴퓨팅 리소스를 할당 받아 실행시킬 수 있습니다.

 

지금도 훌륭한 도구인 Jenkins 에서 트리거를 세팅하고 PR 이 올라왔을 때 혹은 master 에 머지되었을 때 잡이 돌도록 설정하던 것들을
생각하면 github actions 는 아주 손쉬운 도구인 것 같습니다.

 

- How to use?

 

저는 간단하게 TS 프로젝트를 세팅하고 PR 이 생성되었을 때 테스트 코드를 수행하는 잡을 github actions 로 만들어보도록 하겠습니다.

먼저 TS 세팅을 해줍니다.

 

> git init
> npm init
> npm install typescript @types/node --save-dev
> touch tsconfig.json

 

tsconfig.json 은 원하는대로 각자 세팅하면되니 자세한 내용은 패스하겠습니다.

기본 TS 프로젝트 구성은 이거면 됐고, 아주 간단한 모듈을 만들고 해당 모듈을 Jest 로 테스트하는 코드까지 추가하도록 하겠습니다.

 

> mkdir src && touch src/module.ts

 

src 폴더 하위에 module.ts 라는 파일을 하나 만들어주고.. 아래와 같이 내용을 채워줍니다.

 

export const sum = (a: number, b: number) => {
  return a + b;
};

export const sub = (a: number, b: number) => {
  return a - b;
};

export const mul = (a: number, b: number) => {
  return a * b;
};

export const div = (a: number, b: number) => {
  return a / b
};

 

너무 간단한 사칙연산 함수들입니다. 우리는 github actions 에서 테스트가 돌아가는걸 보는게 목적이니까요.

이런데에 너무 공을 들이지 않도록 합니다. 테스트를 돌리기 위해선 Jest 모듈을 추가하고, 테스트 코드를 작성해야겠네요.

 

> npm install jest @types/jest --save-dev
> mkdir test && touch test/module.test.ts

 

import { sum, sub, mul, div } from '../src/module';

describe('test module', () => {
  it('expect sum result', () => {
    expect(sum(1, 2)).toBe(3);
  });

  it('expect sub result', () => {
    expect(sub(1, 2)).toBe(-1);
  });

  it('expect mul result', () => {
    expect(mul(1, 2)).toBe(2);
  });

  it('expect div result', () => {
    expect(div(1, 2)).toBe(1/2);
  });
});

 

최대한 간단하게 간다고 해도 서론이 좀 길었네요. 여기까지 됐으면 이제 github acitons 에서 테스트 코드를 돌릴
workflow 를 정의해보도록 하겠습니다.

컨벤션이 있다고 하면 프로젝트의 root 위치에 .github/workflows 폴더를 생성하고, 그 하위에 정의한 yml 을 위치시켜야 합니다.

 

> mkdir -p .github/workflows && touch test.yml

 

yml 파일 이름에 별다른 규칙은 없어서 저는 test.yml 이라고 하겠습니다.

 

name: Test

on:
  pull_request:
    types: [opened]

jobs:
  test:
    name: "Test"
    runs-on: ubuntu-latest
    permissions:
      packages: write
      contents: read
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
      - name: Cache node_modules
        id: node-modules-cache
        uses: actions/cache@v2.1.4
        with:
          path: ${{ github.workspace }}/node_modules
          key: ${{ runner.os }}-node16-node-modules-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node16-node-modules-
      - name: Install Dependencies
        if: steps.node-modules-cache.outputs.cache-hit != 'true'
        run: npm install
      - run: npm run test

 

위에서부터 하나씩 뜯어보도록 하겠습니다. 공식 문서에 더 많은 내용이 있으니 나중에 참고하시면 좋겠습니다(링크)

name 은 workflow 의 이름을 의미합니다. 여기에 설정한 이름이 github repository 의 actions 탭에서 workflows 에 표시됩니다.

 

그다음 on 은 workflow 를 자동적으로 트리거하기 위한 설정입니다.

어떠한 이벤트에 트리거될지를 먼저 선언하고, 그 하위에 activity types 를 넣을 수 있는데요.

저 같은 경우엔 PR 이 오픈되었을 때 트리거 되도록 설정했다고 보면 됩니다.

 

본격적인 설정은 jobs 에서부터 시작한다고 볼 수 있는데요. job 에는 위처럼 하나의 잡만 설정할 수도 있고, 여러개의 잡을 넣을수도
있습니다. 여러개의 잡을 넣게되면 기본적으론 parallel 하게 실행되지만, jobs.<job_id>.needs 라는 키워드를 통해 순차적으로 실행하게 만들수도 있습니다. 저는 test 라는 잡을 하나만 넣은거구요.

 

이제 job 의 설정으로 들어가서, runs-on 으로 이 잡을 어떤 타입의 머신에서 돌릴 것인지를 정의합니다.

저는 ubuntu 를 사용했지만 mac 이나 windows 를 사용할 수도 있습니다.

 

permissions 는 말 그대로 권한을 주는 것입니다. 저는 packages 에는 write 를, contents 에는 read 를 주었는데 뭐 이 잡을 돌리는데 packages:write 권한 까지는 필요 없지만 권한에 저런것도 있다는 것을 나타내기 위해 써봤습니다. 말 그대로 github pacakges 를 upload 하거나 publish 할 수 있다는 write 권한입니다.(이번 잡과는 아무 상관이 없죠)

contents:read 는 이 repo 의 파일들을 읽을 수 있는 권한을 준 것입니다. 이 외에도 actions, pages 등 여러 목록이 있고
read | write | none 3가지의 권한 범위를 설정할 수 있습니다. 추가로 저는 job 의 하위에 설정해서 이 잡에서만 해당 권한이 유효하도록

잡았는데, on 과 같은 top-level 로 빼서 모든 잡에 권한이 해당되도록 설정할 수도 있으니 참고 바랍니다.

 

그다음은 steps 인데 이는 job 이 갖는 순차적인 task 들입니다. 위에서 job 은 여러개를 정의하면 기본적으로 parellel 하게 동작한다고 했지만 step 의 경우엔 순차적으로 수행되고, 커맨드를 수행하거나 환경 셋업, publish 와 같은 액션을 수행할 수 있습니다.

 

- uses: actions/checkout@v3
- uses: actions/setup-node@v3
  with:
    node-version: 16
- name: Cache node_modules
  id: node-modules-cache
  uses: actions/cache@v2.1.4
  with:
    path: ${{ github.workspace }}/node_modules
    key: ${{ runner.os }}-node16-node-modules-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node16-node-modules-
- name: Install Dependencies
  if: steps.node-modules-cache.outputs.cache-hit != 'true'
  run: npm install
- run: npm run test

 

steps 설정 부분만 뜯어왔습니다. 각 step 은 - 와 indent 로 구분된다고 보시면 쉬울 것 같습니다.

먼저 우리는 이 잡에서 사용하는 ubuntu 장비에 이 repo 의 코드를 내려받아야 합니다. 그냥 repo 에 workflow yml 설정을 넣는다고

그런것까지는 해주지 않습니다. 이걸 해주는게 actions/checkout@v3 인 체크아웃 액션입니다. git checkout 이라고 보시면 되겠죠.

 

그 다음은 노드 버전 세팅입니다. 위에서 언급하는걸 깜빡했는데 저는 TS 프로젝트 구성을 node16 버전으로 했습니다.

따라서 이 버전을 동일하게 맞춰줘야하는데, actions/setup-node@v3 액션이 그 부분입니다.

 

그 다음은 Node.JS 에서 좀 옵셔널한 부분인데 일반적으로 Node.JS 프로젝트를 돌리기위해선 npm 이던 yarn 이던 사용해서 모듈을 설치하는 과정이 꼭 필요합니다. 다만 이 과정은 좀 시간을 잡아먹죠. 그래서 이러한 캐시 액션이 들어가게 되었습니다.

대충 설정된 내용을 보면 얼추 이해가 될거라고 생각하는데, 사용하는 모듈의 버전을 고정해둔 파일인 pacakge-lock.json 을 기준으로

모듈을 캐시해둡니다. 만약 프로젝트 작업간에 어떤 모듈이 수정되거나 추가되었으면 pacakge-lock.json 이 변경되고 그때는 npm install 과정을 다시 수행하겠지만 작업에서 모듈이 수정되진 않았다면 그 작업에 대한 github acitons 잡을 수행할 땐 캐시된 모듈을 그대로 사용할 수 있습니다.

 

npm install 과정에서 if syntax 를 사용해 cache-hit 이 되지 않았을 경우에만 디펜던시를 설치하도록 한 부분이 그런 내용이구요.

마지막엔 npm run test 를 수행해 테스트코드를 돌리고 있습니다.

 

그럼 지금까지 주절주절 설정에 대한 설명이 길었는데 이게 실제로 동작을 하는지 한번 작업한 내용을 PR 로 올려보도록 하겠습니다.

 

 

지금까지 작업한 내용을 PR 로 생성했습니다. 이제 actions 이 의도한대로 동작하는지 봐야하는데, 이 부분은 상단 탭의 Actions 에서

확인할 수 있습니다.

 

 

Actions 탭을 눌러서 들어가면 왼쪽의 workflows 에서 정의한 Test workflow 가 있는걸 확인할 수 있고,

오른쪽에서 해당 workflow 가 수행된 내역을 확인할 수 있습니다. (Build and Publish 는 제가 따로 만들어둔 것이니 무시하셔도 됩니다)

 

 

클릭해서 실제 잡이 정의한 step 대로 돌았는지 확인할 수 있습니다. npm run test 의 결과를 보면, 위에서 작성했던 테스트코드를

실행한 히스토리 확인이 가능하네요.

 

이렇게 간략하게나마 github actions 를 사용해봤는데 공식 문서를 참고해 더 많은 것들을 할 수 있습니다.

저는 주로 팀에서 관리하는 repo 에 PR 이 올라왔을 때 테스트를 수행하는 부분과 내부 모듈을 publish 하는 부분에서 사용하고 있습니다.

 

- Limit

 

limit 이라고 적은게 github actions 의 한계를 말하려고하는 것은 아니고.. 비용에 대한 얘기입니다.

참 혜자인게 github actions 는 설정한 repository 가 public 일 경우엔 무료입니다. 무료라는 것은 우리가 설정한 workflow 를 돌리기 위해 필요한 컴퓨팅 리소스에 대한 요금이 무료라는 것이죠. 쉽게 말하면 AWS 의 ec2 를 공짜로 쓰는 것이랄까요.

 

다만 repository 가 private 일 경우엔 어느정도 선을 넘어가면 요금이 발생합니다.

예를 들어 조직용 Github 을 사용하는 경우 storage 는 500MB, 컴퓨팅 리소스는 1개월당 2000분까지는 무료로 사용 가능하지만

이 기준을 넘어가면 분당 요금으로 과금이 들어갑니다. 이런 기준은 이 페이지를 참고하시면 좋을 것 같습니다.

 

뭐가 더 낫다 라고 말하기는 좀 그렇지만 소규모의 조직에서 빠르게 CI/CD 작업이 필요한 경우엔 github actions 은 충분히 좋은 수단이 될 것 같습니다.

'Backend > Git' 카테고리의 다른 글

Github actions - ssh trouble shooting  (0) 2022.12.03
(Github) git 계정 여러개 사용하기  (0) 2021.11.20