새롭게 이직한 회사는 npm package를 통해 디자인 시스템을 개발/배포/관리를 하고 있었다.
11월 React Native Seoul 정기 meet-up에 팀 동료들과 함께 참여하였고 fastlane을 통한 React Native 배포 자동화에 관한 발표를 듣고 디자인 시스템 패키지만이라도 자동 배포가 되었으면 좋겠다는 생각을 했다. 그리고 이전 회사에서 github action을 통해 NextJS build check 자동화를 구축해본 기억이 있어 github action을 통해 npm package 배포 자동화를 구축하는 방법론이 떠올라 적용 시켜보기로 하였다.
dist
디렉터리를 만든다.npm publish
를 통해 세팅 되어 있는 npm package repository에 패키지를 배포한다. github action에서도 기존에 package.json에 script를 명령어로 사용할 수 있기 때문에 package.json의 명령어를 통해 배포 흐름을 만들 생각이다.
patch
, minor
, major
버저닝이 있어서 patch
버전 배포에 대해서는 develop
브랜치에 머지되면 자동으로 patch
버전을 하나 올려서 배포한다. minor
, major
에 대해서는 github action을 통해 배포하는 동료가 직접 버전을 입력할 수 있도록 할 것이다.# github action name
name: Auto Publish - patch update
# develop 브랜치에 push 되면 자동 patch update를 한다는 구현
on:
push:
branches: [ develop ]
# 실제 실행 구현부
jobs:
# build 환경
build:
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
matrix:
node-version: [16.13.1]
# 실행할 순서
steps:
# github action에서 NodeJS 세팅을 위한 actions/setup-node@v2 action을 사용
- uses: actions/checkout@v2
- name: Set up NodeJS ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
registry-url: https://registry.npmjs.org/
# yarn을 사용하기에 yarn을 global install하고 install dependencies
- name : Install Dependencies
run: |
npm install -g yarn
npm install --legacy-peer-deps --save-dev --ignore-scripts install-peers
yarn install
# npm version을 patch 명령어를 통해 올리고, 리눅스 파이프라인 명령어를 통해 patch로 변경한 버전을 저장
- name : Patch
run: |
npm version patch > version.txt
# 저장한 버전 파일을 읽어 변수로 사용하기 위해 외부 action을 사용 -> setps.{id}.outputs.content로 사용 가능
- name: Read version.txt
id: commit
uses: juliangruber/read-file-action@v1
with:
path: ./version.txt
# version을 변경한 package.json을 commit, 바뀐 버전으로 commit message 작성 후 push
- name: Deploy and Push
run: |
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
git add package.json
git commit -m "${{ (steps.commit.outputs.content) }}"
echo ${{ (steps.commit.outputs.content) }}
yarn deploy
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# slack 웹훅을 통해 채널에 전송
- name: Send result to slack
uses: Ilshidur/action-slack@2.0.2
with:
args: "버전 ➡️${{ (steps.commit.outputs.content) }}의 결과는 ➡️${{ job.status }} 에요"
env:
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
if: always()
registry-url
을 https://npm.pkg.github.com/
로, NODE_AUTH_TOKEN
을 github secret에 등록한(사실 github 개인 토큰 세팅에서 권한을 workflow도 허용하면 자동으로 찾아간다.)${{secrets.GITHUB_TOKEN}}
으로 했었다. action을 통해 배포시 npm publish
명령어에서 unathorized 오류를 뱉었다.npm patch
를 통해 자동 버저닝은 하였으나 해당 버전을 commit message로 commit 하고 싶었다. 어떻게 가져올지 고민이 되었다. 처음에는 pacakge.json 자체를 읽어왔다. 버저닝 하나 때문에 package.json 전체를 읽고 version이 포함된 위치를 찾아서 그 버전을 가져오는게 과하다고 생각했고, npm patch
에서 return하는 버전 관련 문자열을 사용하는 것이 좋겠다고 생각했다.모듈명: cannot find module
.. github action에서 typescript를 위한 tsc
, tsc-alias
가 제대로 동작하지 않는 줄 알았다. 그리고 디자인 시스템 패키지에서는 tsc
, tsc-alias
가 잘 동작해서 github action의 step에 tsc
, tsc-alias
를 global하게 설치도 해보았다. 여전히 에러가 났고, 찾을 수 없는 모듈들을 꼼꼼히 살펴보았다... 공통점이 있었다 ...!npm package
자동 배포를 위한 세팅으로 변경하였더니 해결했다! 그래서 registry-url
을 https://registry.npmjs.org/
로, NODE_AUTH_TOKEN
을 github secret에 등록한 npm repository token인 ${{ secrets.NPM_TOKEN }}
으로 변경하여 해결하였다.build:
...
permissions:
contents: write
git config --global user.name "${GITHUB_ACTOR}"
git config --global user.email "${GITHUB_ACTOR}@users.noreply.github.com"
npm patch
명령어에서 return 해주는 버전을 리눅스의 파이프라인 명령어로 파일을 생성하였다. npm version patch > version.txt
를 통해 version.txt
파일에 생성하고, juliangruber/read-file-action@v1
외부 action을 사용하여 setps.{id}.outputs.content
로 해당 action에서 읽어온 string을 commit message로 사용할 수 있도록 하였다.모듈명: cannot find module
에러가 발생한 모듈들의 공통점은 모두 peer-dependency에 적혀있는 모듈들이었다. 그래서 다음과 같은 명령어를 github action에 추가하여 해결하였다.npm install --legacy-peer-deps --save-dev --ignore-scripts install-peers
참고