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
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에 있는 템플릿을 활용하면 좋다.
3️⃣ 해당하는 템플릿을 사용한다.
나는 node.js 환경이기 때문에 Node.js를 선택했다.
Node 검색해도되고 두 번째 줄에 바로 보인다. Configure 클릭
혹은 Github docs - Build & Test Node.js 에도 있다.
4️⃣ 생성된 코드를 보고 환경에 맞게 수정한다.
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 부분을 확인하여서 적용했는데 훨씬 수월했다.
✔️ 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
실행
이 세팅은 환경마다 달라질 수 있다. pnpm은 github docs에도 인증되지 않은 비공식 작업 코드를 제공한다. 중요한 건, 나의 환경에 맞게 수정할 줄 알아야 된다는 것, 특히 버전과 액션이 그렇다.
checkout의 중요성, ChatGPT, pnpm 공식문서에 친절히 안내되어있는 것 등으로 잘 해결할 수 있었다. 처음이라 헤맸는데 열심히 도와주신 분도 계셨고 여러모로 많이 배웠다. 다른 분들께 도움이 될 수 있도록 포스팅을 해봤다. 다음엔 더욱 복잡한 workflow를 만들어보고 싶다.
[CI/CD(Continuous Integration/Continuous Delivery)란?]
ChatGPT 🤖
본문에 첨부된 링크도 전부 참조하였습니다.
'Problem Drilling' 카테고리의 다른 글
브라우저에서 Excel 파일 다운로드하기: Blob과 CORS 해결과정 (0) | 2024.04.22 |
---|---|
Axios interceptors로 API Data 목적에 맞게 분류하기 (0) | 2024.03.03 |
Github Action Test 성공하고 Workflow 복붙했다가 큰 코 다친 이야기 (2) | 2023.11.12 |
Open Source License 고르기, GPL? MIT? No License? (0) | 2023.11.10 |
Vite config파일 수정해서 배포 디렉토리 상대 경로로 변경하기 (0) | 2023.10.29 |