github actions > NPM package 자동 배포

wonder-lee·2023년 2월 25일
1
post-thumbnail

개요

github main branch가 merge 되면, 자동으로 NPM publish를 하면 좋겠다.

사내 npm package를 개발하고 팀원들과 개발 과정 공유 중, 위와 같은 이야기가 나와 github acitons을 이용하여 npm package 자동 배포 개발 과정을 정리한 포스트 입니다.

내용

github actions를 이용하여 구현하고 싶은 자동화는 아래와 같습니다.

  1. main branch가 push event를 발생시킬 때 자동화가 이루어진다.
  2. package의 version이 update되었을 때 npm publish를 실행한다.
  3. github action의 시작, 종료, 에러를 slack message를 전송한다.
  4. github action이 실행되고 package의 version 정보를 slack message로 전송한다.

github actions 환경 설정

우선 위의 목적 4가지를 실행할 경우 연동할 slack webhook url과 npm 배포시 필요한 npm token은 공개되어서는 안되는 key입니다.
그렇기 때문에 공개된 repository > github actions file에 직접 작성하는 것이 아닌, Repository secrets로 설정을 해야합니다.

Repository secrets 설정은 Respository > Settings > Secrets and variables > Actions 설정 page로 들어가면 위의 사진과 같은 설정 page가 보이게 됩니다. 여기서 우측 상단에 있는 New repository secrets라는 초록색 버튼을 눌러서 Repository secrets 등록합니다.
저는 위 사진처럼 NPM_TOKEN, SLACK_WEBHOOK_URL로 등록하였습니다.

gitbub actions 개발

github actions?

자동으로 repository에서 어떤 event가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있습니다.
github actions에는 크게 2가지의 작업 단계가 있습니다.
workflow는 github actions가 실행하게 될 가장 큰 틀의 자동화된 단계라 보시면 됩니다.
action는 workflow 안에서 실행하게될 하나 하나의 job들이라 보시면 됩니다.

초기 설정

자, 그럼 github actions의 가장 큰 틀인 workflow를 생성해 봅시다.
1. github actions는 실행시킬 repository root folder에서 .github folder를 생성합니다.
2. .github folder에서 실행시킬 workflows folder를 생성하여, workflow file을 생성합니다.
- 저는 on-push-check-and-publish-packages.yml file로 생성하였습니다. (참고)
3. 저는 main branch에서 git push event가 발생할 때, 해당 workflow가 실행되게 아래처럼 설정하였습니다.

name: "on-push-check-and-publish-package"
on:
  push:
    branches:
      - main
jobs:
  check-and-publish-package:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16.x

on, push, braches, main

명령어는 직관적으로 main brach가 push event를 발생할 때 알 jobs를 실행 시킨다는 trigger 명령어입니다. 이 외에도 다양한 git event가 발생할 때 trigger를 연동시킬 수 있으며 가능한 event는 공식 homepage의 workflow event 내용을 확인해보시면 됩니다. (ex : pull request, issue open, braches 이름 포함, 특정 경로의 file 등등)

jobs, check-and-publish-package

jobs는 work flow에서 실행될 행동들 이라고 생각하시면 됩니다. 그리고 모든 jobs를 통틀 이름을 다음 줄에 적어놓은 check-and-publish-package으로 설정하게 됩니다. 그러면 아래 image처럼 윗줄에서 설명했던 trigger가 발생되어 실행되는 jobs들을 통틀어 check-and-publish-package라고 불러지게 됩니다.

runs-on

jobs들을 실행할 환경을 설정하는 명령어 입니다. 저는 일반적으로 사용되는 ubuntu-latest로 설정하였습니다.

steps

steps는 jobs의 실행 단위라고 생각하시면 됩니다. 아래 image처럼 하나 하나 실행되는 단위 입니다. steps에서 실행될 행동들을 직접 작성할 때는 actions라는 file을 생성하거나, actions marketplace에서 다른 개발자들이 작성한 actions를 가져다 사용할 수 있습니다. 마치 다른 개발자가 만든 library를 install해서 사용하는 것과 같다고 생각하시면 됩니다.
저는 다른 개발자가 이미 만들어 놓은 actions인 checkout@v3setup-node@v3를 사용하였습니다.
이 때 uses라는 명령어를 쓰고 뒤에 사용할 actions 명칭을 쓰면 됩니다. 또한, 해당 actions를 사용할 때 넣어줘야할 값이 있다면 with 명령어로 특정 값을 넣어주시면 됩니다. 마치 함수에 인자 값을 넣어주는 개념과 같습니다.

  • checkout@v3
    보통 GitHub Actions에서 작업을 수행하기 전에 Git 리포지토리에서 코드를 가져와야 합니다. 이 액션을 사용하면 원하는 리포지토리에서 소스 코드를 가져올 수 있습니다. 이 액션은 Git의 브랜치, 태그, 커밋을 가져올 수 있으며, 원하는 브랜치나 태그를 선택할 수 있습니다.
    이렇게 작성하면, 현재 리포지토리의 브랜치를 가져와서 작업 폴더에 복사합니다. 이를 통해, 이후의 작업에서 리포지토리의 코드를 사용할 수 있습니다.
  • setup-node@v3
    이렇게 가져온 우리의 project를 Node.js 환경 위에서 실행하게 도와주는 actions입니다.

NPM publish actions

NPM Publish actions는 github market place에 올라와 있는 actions입니다. 우선 NPM 관련 actions 중 가장 stars가 많고, NPM,Github 관련 개발자들이 직접 참가한 actions로 가장 안정성이 좋다고 판단되어 사용하였습니다.

NPM publish actions는 제가 원하는 기능을 완벽히 그리고 쉽게 이용할 수 있게 개발되어 있습니다.

- name: Check & Publish utils package
  uses: JS-DevTools/npm-publish@v1
  id: utils
  with:
    token: ${{ secrets.NPM_TOKEN }}
    package: "./packages/utils/package.json"
  • name : step의 이름을 설정합니다.
  • uses : 사용하는 actions를 설정합니다. 저는 npm-publish@v1을 사용하였습니다.
  • id : npm-publish actions의 unique하게 id를 입력해줍니다.
  • with : 사용하는 actions에 넣어줄 특정값을 설정합니다.
    • token : NPM을 배포할 때, 필요한 NPM token 입니다. github actions 환경 설정시 우리는 secrets key로 설정하였습니다.)
    • package : version을 확인하고 배포할 package의 경로를 설정합니다.

위 처럼 with에 package 경로를 설정하면 해당 package.json file에서 package 정보 참고하여, 자동적으로 이미 배포된 package version과 현재 push하려는 package version을 비교하여 version에 update가 발생하면 NPM token을 이용하여 배포를 해주게 됩니다.

Slack 연동

slack 연동 code는 kakao FE 기술 블로그를 참고하여 작성하였습니다.

- name: Send slack if completed
  if: ${{ success() }}
  uses: ./.github/actions/slack-noti
  with:
    status: success
    slack_webhook_url: ${{ secrets.SLACK_WEBHOOK_URL }}
    package_name: "utils"
    current_version: ${{steps.utils.outputs.version}}
    old_version: ${{steps.utils.outputs.old-version}}
    type: ${{steps.utils.outputs.type}}
  • uses : 직접 actions를 작성할 경우 위 처럼 경로를 설정하게 됩니다.
  • with :
    • ${{ secrets.SLACK_WEBHOOK_URL }} : 말 그대로 발송하게 될 slack channel의 webhook url입니다. 이 때, secrets로 설정한 값은 workflow file에서만 접근이 가능하여 with값으로 넘겨주고 있습니다.
    • ${{steps.utils.outputs.version}} : 위 npm-publish actions를 사용할 때 설정한 step의 id값으로 해당 package의 현재 version 정보를 가져옵니다.
    • ${{steps.utils.outputs.old-version}} : 동일하게 해당 id값의 이전 정보를 가져옵니다.
    • 위 package에 대한 정보들은 Npm-publish actions에서 제공되는 값이며, output되는 정보는 이 곳에서 확인이 가능합니다.

위 처럼 workflow에서 제가 만든 ./.github/actions/slack-noti file로 해당 값들을 넘겨 step으로 실행하게 되면 아래 file내용이 실행되어 집니다.

Skip to content
Search or jump to…
Pull requests
Issues
Codespaces
Marketplace
Explore
 
@wonder-lee 
maxst-fe
/
max-at
Public
Fork your own copy of maxst-fe/max-at
Code
Issues
6
Pull requests
Actions
Projects
Security
Insights
max-at/.github/actions/slack-noti/action.yml
@lee-maxst
lee-maxst [NO-ISSUE] NPM 패키지 제목에 링크 추가
Latest commit f23d243 2 weeks ago
 History
 1 contributor
41 lines (34 sloc)  1.54 KB

name: "slack-noti"

inputs:
  status:
    required: false
    default: "failure"
  slack_webhook_url:
    required: true
  package_name:
    required: true
  current_version:
    required: false
  old_version:
    required: false
  process:
    required: false
  type:
    required: false
  emoji:
    required: false
runs:
  using: "composite"

  steps:
    - name: Send slack
      shell: bash
      run: |
        if [ "${{ inputs.status }}" = "workflow" ]; then
          CONTENT="${{inputs.emoji}} *<https://github.com/maxst-fe/max-at|max-at>* > *<https://github.com/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}%7C${GITHUB_WORKFLOW}| NPM 버전 체크 및 배포 - 깃헙 액션>* 이 ${{inputs.process}}되었습니다. ${{inputs.emoji}}\n"
        elif [ "${{ inputs.status }}" = "success" ] && [ ${{inputs.type}} != 'none' ]; then
          CONTENT='> *<https://www.npmjs.com/package/@max-at/utils|@max-at/${{ inputs.package_name }}>* ✅ \n>성공적으로 ${{ inputs.old_version }} 버전에서 ${{ inputs.current_version }} 버전으로 업데이트 되었습니다.🥳'
          
        elif [ "${{ inputs.status }}" = "success" ] && [ ${{inputs.type}} = 'none' ]; then
          CONTENT='> *<https://www.npmjs.com/package/@max-at/utils|@max-at/${{ inputs.package_name }}>* ✅ \n>버전 변경사항이 없으며, ${{ inputs.current_version }} 버전 유지 중 입니다.🏄🏻‍♂️'
        fi
        MSG="{ \"text\":\"${CONTENT}\"}"
        curl -X POST -H 'Content-type: application/json' --data "${MSG}" "${{ inputs.slack_webhook_url }}"
  • shell : linux bash로 설정합니다.
  • run : bash script로 동작시킬 내용을 작성합니다.
    • curl -X POST -H 'Content-type: application/json' --data "${MSG}" "${{ inputs.slack_webhook_url }}"
    • bash script에서 if 구문을 통하여 시작, 실패, 성공, 종료 상황 별로 slack 발송할 message를 설정하고, 마지막으로 slack webhook url로 message를 POST하는 구문입니다.

아래는 slack channel에 전송되는 모습입니다.


위 내용의 github file 원본의 주소 입니다. 참고 바랍니다.

마치며

이렇게 사내 package를 만들고 또한, package가 update되었을 경우 github action을 통하여 자동적으로 package를 배포하는 과정을 기록해보았습니다.
제가 작업을 한 사내 package도 완벽하지 않으며, github actions 또한 완벽하지는 않습니다.
하지만 이 완벽하지 않은 package가 사내 FE개발자에게는 도움이 되었고, 완벽하지 않은 github actions 또한 package를 관리할 때 자동으로 배포되며 slack 상태를 알려주며 작은 도움이 되었습니다.
제가 미약한 시작을 하면 다른 FE개발자들도 동참하여 개선해나가며 완벽으로 가지 않을까 싶습니다.
부족한 개발과정을 읽어주셔서 감사합니다. 🙇🏻‍♂️

문제점

  1. 해당 workflow가 실행될 때 매번 build를 하는 부분 개선 필요
  2. package가 추가될 때 마다 NPM publish actions step을 추가해야하는 부분
  3. npm-publish actions 사용 시 set-output disabled warning issue 개선 여부 확인 필요
    Deprecation warning for 'set-output' #67

오류

  • Node.js 12 actions are deprecated.
    • - uses: actions/checkout@v2
      • 생성한 actions > step > uses에 checkout@v2를 사용할 때, node 버전 문제가 발생하였고, chekcou@v3로 수정하였습니다.
    • github actions issue 참고
  • curl: (3) URL using bad/illegal format or missing URL
    • slack webhooks url로 요청시 발생하였고, screts key 값을 echo로 출력하였지만 계속 빈 값이 나와 4시간 정도를 허비하였다.
      • echo "${{secrets.SLACK_WEBHOOK_URL}}"를 출력하면 빈값이 나왔다.
    • 해결방법은 아래 사진처럼 Environment secrets에 scret key를 저장하는 것이 아닌, 오른쪽 상단에 초록색 button의 New create secret을 눌러 Repository secrets 에 추가하여야지 screts key에 접근할 수 있었다.

참고

profile
원더리입니다.

0개의 댓글