Problem Drilling

Github Actions 사용, Workflow 테스트 자동화 적용하기, pnpm

남희정 2023. 11. 11. 03:36

Github Action를 사용해서 테스트 자동화를 해보게 되었다. 우선 Github에 있는 node.js.yaml 템플릿으로 어찌저찌 구현하다가 pnpm 이라는 난관.. 그리고 working-directory 쪽에서도 헤맸고. 전혀 다른 곳에서 테스트되기도 했다. 그래도 처음인데도 몇 시간내로 바로 구현했고 27번의 시도만에 성공했다. 이 과정을 공유하고 내가 쓴 워크플로우도 공유하겠다!


Github Actions

Github Actions는 repository에서 바로 소프트웨어 개발 workflow를 자동화하여 실행할 수 있다. 

빌드, 테스트 및 배포 파이프라인을 자동화할 수 있는 CI/CD 플랫폼! 레포에 대한 모든 PR을 build 및 테스트하는 workflow로 만들거나 병합된 PR을 프로덕션에 배포할 수 있다.

CI Continuous Integration 지속적인 통합

테스트 실행이나 빌드 검사, 컨벤션 검사를 통해 코드가 의도대로 동작하고 잘 작성되었는지를 확인하는 것.

CD Continuous Delivery, Deployment 지속적인 서비스 제공 혹은 배포

리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 배포하는 것을 의미한다. 

 

The components of GitHub Actions

The components of GitHub Actions

Github Action을 이해하기 위해서 알아야 하는 개념은 Workflow, Event, Job, Step, Action, Runner 등이 있다.

Workflow

workflow는 repository의 .github/workflows 폴더에 정의되며, repository에는 여러 workflow가 있을 수 있고 각각 서로 다른 작업을 수행할 수 있다. 

 

✔️ 여러 Job으로 구성되고, Event에 의해 Trigger될 수 있는 자동화된 프로세스

✔️ 최상위 개념

✔️ yaml로 작성

Event

workflow 실행을 Trigger하는 repository의 특정 활동이다. 

 

✔️ PR을 만들거나, 이슈를 열거나, commit을 push 하는 것, 특정 시간대에 반복(Cron), Webhook을 사용해 외부 이벤트를 통해 실행하는 것 등

Job

동일한 runner에서 실행되는 여러 step의 집합.

 

✔️ 여러 Step으로 구성되고, 가상 환경의 인스턴스에서 실행된다.

✔️ 한 step에서 다른 step으로 데이터 공유 가능

✔️ 독립적으로 병렬 실행 가능

Step

Task들의 집합, command를 날리거나 action을 실행할 수 있다.

Action

workflow의 가장 작은 블럭(smallest portable building block)

 

✔️ Job을 만들기 위해 Step들을 연결할 수 있음

✔️ 재사용이 가능한 컴포넌트

✔️ 개인적으로 만든 Action을 사용하거나 MarketPlace에 있는 공용 Action을 사용할 수도 있다.

Runner

Workflow가 Trigger될 때 Workflow를 실행하는 서버.

 

✔️ 각 runner는 한 번에 하나의 작업만 실행할 수 있다.

✔️ GitHub은 Ubuntu Linux, Microsoft Windows 및 macOS runner를 제공, 실행은 pro-visioned된 새로운 가상 머신에서 실행된다.

✔️ 다른 OS가 필요하거나 특정 하드웨어 구성이 필요한 경우 self-runner를 호스팅할 수 있다.

Create an example workflow

1️⃣ repository에서 workflow파일을 저장할 ./github/workflows/ 디렉터리를 만든다.

2️⃣  ./github/workflows/ 디렉터리에 .yml로 끝나는 새 파일을 만든다.

 

나는 pr-test.yml이라고 지었다.

Github repo에 Actions에 있는 템플릿을 활용하면 좋다.

 

Repo - Actions

3️⃣ 해당하는 템플릿을 사용한다. 

 

나는 node.js 환경이기 때문에 Node.js를 선택했다.

Node 검색해도되고 두 번째 줄에 바로 보인다. Configure 클릭

 

혹은 Github docs - Build & Test Node.js 에도 있다.

 

Building and testing Node.js - GitHub Docs

You can create a continuous integration (CI) workflow to build and test your Node.js project.

docs.github.com

 

4️⃣ 생성된 코드를 보고 환경에 맞게 수정한다.

 

자동으로 만들어진 node.js.yml 템플릿

 

node.js.yml 

name: Node.js CI

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

jobs:
  build:

    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [14.x, 16.x, 18.x]
       
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    - run: npm ci
    - run: npm run build --if-present
    - run: npm test

위는 Node.js 템플릿 Configure을 누를 경우 자동완성되는 node.js.yml 파일이다.

컴포넌트 별로 나의 pr-test.yaml은 어떻게 수정했는지 코드로 보여주겠다.

 

name

name: PR Test

name은 말그대로 Job tab에 표시되는 workflow의 이름이다. 이 필드를 생략하면 workflow 파일의 이름으로 대신 사용된다.

 

on

on:
  pull_request:
    branches: [main]

workflow의 Trigger를 지정한다. 자동으로 push가 지정 되는데, 나는 PR시 적용하게 하고 싶어서 pull_request로 변경했다.

즉, 브랜치 main에 대한 PR이 생성되면 Trigger 되도록 지정한 것이다. 

 

jobs

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18]
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Use Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test
  jobs:

✔️ jobs는 pr-test workflow에서 실행되는 모든 jobs를 함께 그룹화 하는 것이다.

 

  test:

✔️ 실제 문법은 jobs.<job_id>

✔️ 기본으로 build:였던 건데 아무 이름이나 지정할 수 있다. 어떤 작업인지 명시해주는 거라고 보면 된다. 

✔️ 나의 workflow는 test라는 job에 2개의 step이 존재하는 구조다.

 

    runs-on: ubuntu-latest

✔️ 어떤 OS에서 실행될지 지정하는 것. 최신 버전의 Ubuntu Linux runner에서 실행되도록 작업을 구성한다.

✔️ 즉, Job이 GitHub에서 호스팅하는 새 가상 머신에서 실행된다.

 

        strategy:
          matrix:
            node-version: [18]

✔️  strategy - matrix 인자를 사용하면 어떤 node 버전에서 테스트할지 확인할 수 있다.  [14.x, 16.x, 18.x] 이런식으로 여러 버전도 가능.

 

    steps:

✔️  pr-test job에서 실행되는 모든 step을 그룹화한다. 

✔️  jobs.<job_id>.steps

✔️  job의 실제 동작을 정의하는 부분

 

      - uses: actions/checkout@v3

✔️ uses 키워드는 각 step에서 사용할 액션을 지정한다.

✔️ 이 step에서는 actions/checkout 액션의 v4를 실행하도록 지정한다. runner로 repository를 체크아웃하여 코드에 대해 작업을 실행할 수 있게 하는 액션이다.

✔️  workflow에서 repository 코드를 사용할 때마다 체크아웃 작업을 사용해야 함.

 

      - uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Use Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: "pnpm"

✔️  pnpm/action-setup@v2 ~ actions/setup-node@v3 의 경우 지정된 버전의 pnpm과 node를 설치, 세팅하는 것. 이걸 설정하면 node 및 pnpm 명령이 모두 PATH에 배치된다.

 

참고로 pnpm의 경우 github docs보다 pnpm 공식 문서 내 Github Actions 부분을 확인하여서 적용했는데 훨씬 수월했다. 

 

Continuous Integration | pnpm

pnpm can easily be used in various continuous integration systems.

pnpm.io

✔️  cache는 캐싱 기능을 설정하는데 사용되는 옵션이다. pnpm 패키지 매니저를 사용하여 Dependency를 캐싱한다는 것을 나타낸다. 캐시 된 종속성을 재사용하여 실행 속도를 향상시킬 수 있다. 

 

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

✔️  name은 UI에서 각 step에 표시되는 이름이므로 적절하게 사용하면 된다.

✔️  run은 시스템의 shell에 명령어를 실행하는 부분이다. 

✔️ - run: pnpm install처럼 한 줄로 쓸 수 있다. (name 생략 가능)

 

최종

name: PR Test
on:
  pull_request:
    branches: [main]
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18]
    steps:
      - uses: actions/checkout@v3
      - uses: pnpm/action-setup@v2
        with:
          version: 8

      - name: Use Node.js 18
        uses: actions/setup-node@v3
        with:
          node-version: 18
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Run tests
        run: pnpm test

실행

27번의 시도

 

build라는 job의 steps

 

 

이 세팅은 환경마다 달라질 수 있다. pnpm은 github docs에도 인증되지 않은 비공식 작업 코드를 제공한다. 중요한 건, 나의 환경에 맞게 수정할 줄 알아야 된다는 것, 특히 버전과 액션이 그렇다.

 

checkout의 중요성, ChatGPT, pnpm 공식문서에 친절히 안내되어있는 것 등으로 잘 해결할 수 있었다. 처음이라 헤맸는데 열심히 도와주신 분도 계셨고 여러모로 많이 배웠다. 다른 분들께 도움이 될 수 있도록 포스팅을 해봤다. 다음엔 더욱 복잡한 workflow를 만들어보고 싶다.

 

 

 


[GitHub Actions 워크플로우 사용하기]

[Github Action 사용법 정리]

[CI/CD(Continuous Integration/Continuous Delivery)란?]

ChatGPT 🤖

 

본문에 첨부된 링크도 전부 참조하였습니다.