티스토리 뷰

BACKEND/NODEJS

nodejs 프로젝트의 ci 설정 다시 보기

나를찾는아이 2024. 5. 23. 12:02
728x90
반응형

 

https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs

 

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

 

위의 문서에는 nodejs 프로젝트의 github action을 통한 build, testing을 수행하는 ci에 대해 설명이 있습니다

 

name: Node.js CI

on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Use Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20.x'
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test

 

 

액션 코드는 이렇게 구성이 되어있습니다

 

몇가지 궁금증들을 풀어볼까 하는데요

 

 

단일 진실공급원의 nodejs 버전을 사용하는가?

 

만약 여러분들이 여러개의 노드버전에서 동작하는 라이브러리를 개발하고 있는 경우라면

 

strategy:
  matrix:
    node-version: ['14.x', '16.x', '18.x']

steps:
- uses: actions/checkout@v4
- name: Use Node.js ${{ matrix.node-version }}
  uses: actions/setup-node@v4
  with:
    node-version: ${{ matrix.node-version }}

 

github action에서 위와같은 matrix를 설정하여 여러개 버전에서 ci를 수행하는 github action을 생성할수 있습니다

 

그리고 여러개의 버전에서 동작을 테스트 하기때문에 이렇게 생성하는 것이 바람직합니다.

 

 

지정된 버전을 사용해서 node 환경을 셋업할때는 다음과 같이 설정합니다

        uses: actions/setup-node@v4
        with:
          node-version: '20.x'

 

 

여기서 node-version 버전은 string이든 number든 상관없습니다

 

내부적으로 github action에 주입되는 값들은 내부적으로 getInput 메서드로 꺼내오기 때문에 string 형으로 반환됩니다(환경변수에서 꺼내오는 개념)

 

그리고 버전표기역시 내부적으로 semver을 사용하고 있기 때문에 semver를 만족하는 버전 표시방식이면 뭐든 가능합니다.(틸드, 캐럿 등)

 

 

하지만 여기서 생각해볼만한것이 있는데

 

여러분들이 여러개의 버전에서 동작하는 라이브러리가 아니라 그 자체로 동작하는 어플리케이션(서비스)를 운영하고 있다면, 

개발환경, 운영환경에서 사용하는 공통의 고정된 node-version이 있을것입니다

 

그런데 위와같이 github action에 버전을 명시하는 경우 github action이사용하는 버전과

 

여러분이 운영에 사용하는 실제 node-version의 버전이 서로 다를수 있는 가능성이 존재하게 됩니다

 

진실공급원이 2개가 있기 때문입니다

 

그렇다면 진실 공급원은 어디에 있어야할까요?

 

 

nodejs 프로젝트라면 반드시 package.json 파일을 포함합니다

 

package.json 파일의 구성요소에는 engines가 있는데요

 

{
  "engines": {
    "node": ">=0.10.3 <15"
  }
}

 

 

해당 프로젝트가 동작하는 nodejs 버전을 의미합니다

 

실제로 package.json에 명시된 버전과 다른 버전을 사용하여 프로젝트를 실행하면 오류를 발생시킵니다

 

 

이렇게 package.json에 버전을 명시하고

 

github action은 해당 버전을 참조하는 식으로 구성하면 진실공급원을 하나로 만들수 있어 더 안전한 ci를 수행할수 있습니다

 

 

이미 github action의 setup-node 액션은 그에 대한 지원을 하고 있습니다

 

        id: setup-node
        uses: actions/setup-node@v4
        with:
          node-version-file: package.json

 

이렇게 node-verison-file을 명시하는 경우 package.json에서 node 버전정보를 읽고 node환경을 셋업합니다

 

 

setup-node는 캐시기능이 있는가?


setup-node는 nodejs 환경을 세팅하기도 하지만 기본적인 캐시 기능이 있습니다

 

      - name: Setup Node
        id: setup-node
        uses: actions/setup-node@v4
        with:
          node-version-file: package.json
          cache: 'npm'

 

해당 작업에 대해 cache 인자값으로 사용중인 패키지 매니저(npm, yarn)를 입력하면 캐시기능이 활성화됩니다

 

그리고 추가로 cache-dependency-path를 설정할수도 있는데요

 

cache-dependency-path 이 없으면 기본값의 lock 파일을 찾습니다

 

npm일 경우는 package-lock.json을 찾습니다

 

이를 통해서 캐시 생성하고 가져오게 됩니다

 

https://docs.npmjs.com/cli/v10/commands/npm-cache

 

npm-cache | npm Docs

Manipulates packages cache

docs.npmjs.com

 

여기서 사용하는 캐시는 말그대로 npm 에서 사용하는 npm-cache 기능입니다

 

엄밀하게 말해서 node_modules 폴더를 캐시하는것이 아닙니다

 

다운로드해야할 패키지들의 정보를 캐시합니다

 

setup-node시에 캐싱을 사용하면 캐싱을 생성하고 복원으로 인해 약간의 시간이 더 걸리는데

 

대신에 npm install을 할때 캐시로 인한 이득을 볼수 있습니다

 

 

 

기존에는 Setup Node가 1초면 완료가 되었는데

 

 

캐시를 사용하여 복원을 하는 과정과 

 

캐시를 저장하는 과정으로 약 10초가량이 추가되었습니다

 

 

하지만 npm ci 명령어를 수행할때 npm 캐시가 없을때 1분 36초가 걸리던것이

 

 

1분 5초로 31초가량을 절약하였습니다

 

아마도 여러분이 사용하는 패키지가 더 많으면 더 효과를 볼수 있을것 같네요

 

 

 

node_modules를 캐시할수는 없는가?

 

actions/cache@v4 를 통해서 node_modules 폴더를 캐시하고 복구하여 사용할수있 있습니다

 

const keyPrefix = `node-cache-${platform}-${packageManager}`;
const primaryKey = `${keyPrefix}-${fileHash}`;

 

예를들어 액션이 실행되는 플랫폼과 패키지매니저 그리고 package-lock 파일의 해시를 조합하여 restore-key 로 만들어

 

같은 조건이 부합할때 node_modules를 복원할수 있도록 기술적으로는 가능합니다

 

다만 깃헙에서는 action이 다양한 환경에서 실행될수 있는 만큼 권장하지는 않더라구요

 

 

그런데 이 방법을 사용해도 애매한 문제들이 남습니다

 

node_modules가 복원된 다음에 이후에 npm ci 명령어를 수행하게 되면

 

(ci 명령어는 clean install을 뜻하며 node_modules 폴더를 삭제후에 다시 install 하는 작업을 실행합니다)

 

다시 node_modules가 삭제되기때문에 오히려 node_modules를 캐싱하는 것자체가 의미가 없어질수도 있습니다

 

그래도 node_modules를 보존하면서 npm ci가 아닌 npm install을 사용한다고 할때는 의존성의 버전이 프리징이 되지 않으니 이것 또한 방법이 애매하다는 문제가 있습니다

 

 

그래도 package-lock이 변경이 없이 소스코드만 변경되었을때는 유용한 방법일수도 있겠습니다

 

 

 

728x90
반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함