GitHub Package Registry로 비공개 NPM 패키지 배포하기
2025. 4. 7. 19:04ㆍDev_etc/Git
by HITS-AI
왜 GitHub Package Registry를 선택했는가?
기존에는 내부 라이브러리를 공유하기 위해 SSH 주소를 통해 로컬 설치하는 방식을 사용했지만, 다음과 같은 이유로 GitHub Package Registry 기반 배포로 전환하였습니다-
- 버전 관리의 명확성: Git 태그 기반 버저닝으로 변경 이력 추적이 명확
- 설정의 간편함: GitHub Action을 통한 배포 자동화 가
- 설치 속도 및 안정성: CDN 캐싱과 병렬 처리 덕분에, git+ssh 방식에 비해 설치 속도가 빠르고 안정적 (17s -> 13s)
package.json 설정
git package에 배포하기 위해서는 라이브러리의 package.json에 name, version, publishConfig 값을 지정해줘야 합니다.
// package.json
{
"name": "@hits-ai/hits-ngl",
"version": "1.0.0", //태그 기반으로 배포할 경우, 임의의 version명 지정.
"publishConfig": {
"registry": "https://npm.pkg.github.com/"
}
}
name은 반드시 GitHub 조직 이름(@hits-ai)을 prefix로 포함해야 하며, publishConfig.registry는 npm.pkg.github.com으로 지정해야 합니다.
배포 방식
위 설정한 package.json을 기반으로 npm에 배포하는 두 가지 방법을 소개해보겠습니다.
1. GitHub Action으로 배포 자동화
2. 수동 배포
GitHub Actions으로 배포 자동화
태그 패턴
저희 프로젝트는 태그 기반 배포 자동화 aciton을 적용했습니다.
.github/workflows/publish.yml
name: Build and Publish on Tag
on:
push:
tags:
- "hits-ngl/v[0-9]+.[0-9]+.[0-9]+-mod.[0-9]+" //hits-ngl/v2.4.0-mod.0 -> 2.4.0-mod.0 으로 배포
jobs:
build-and-publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: "18"
registry-url: "https://npm.pkg.github.com"
- name: Install dependencies
run: npm install
- name: Extract version from tag
id: version
run: |
REF=${GITHUB_REF#refs/tags/hits-ngl/}
VERSION=${REF#v}
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
- name: Inject version into package.json
run: |
VERSION=${{ steps.version.outputs.version }}
jq --arg v "$VERSION" '.version = $v' package.json > temp.json && mv temp.json package.json
- name: Build library
run: npm run build-min
- name: Publish to GitHub Packages
run: npm publish
env:
NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-min은 사전 정의된 빌드 스크립트입니다. 환경에 맞게 조정해 주세요.
해당 액션을 통해
main에 병합 후 배포를 희망하는 커밋에 태그를 달아주면 자동으로 빌드/배포 자동화가 진행됩니다.
수동 배포
1. 버전 수정
수동 배포에서는 pacakge.json의 version에 실제로 배포될 version을 지정해줘야 합니다.
"version": "2.4.0-mod.0"
2. 빌드
npm run build-min # build-min은 사전 정의된 빌드 스크립트입니다. 환경에 맞게 조정해주세요.
3. 로그인 (최초 1회)
npm login --registry=https://npm.pkg.github.com
또는 .npmrc 설정:
@hits-ai:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=ghp_xxx...
4. 패키지 배포
npm publish
설치 방법 (로컬 또는 배포 환경)
위 과정을 통해 npm에 패키지 배포를 완료했고, 이제 배포된 비공개 라이브러리를 어떻게 프로젝트에 설치하는지 소개해보겠습니다-!
우선 패키지 영향범위가 있는 스코프에 .npmrc 파일을 생성하고, 아래 내용을 기입해 줍니다.
@hits-ai 하위의 패키지 들은 해당 주소로 접근하겠다는 뜻입니다-
@hits-ai:registry=https://npm.pkg.github.com/
해당 파일에 아래처럼 토큰을 주입해도 되지만, 토큰을 노출시키는 게 꺼림칙해서 토큰을 따로 주입하기로 했습니다.
@hits-ai:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=ghp_xxx...
이제 로컬/배포환경에서 각자 토큰을 주입하고 설치하도록 설정해 주겠습니다.
로컬
- 토큰 발급
https://github.com/settings/tokens 에서 read:packages 권한이 있는 personal access token(PAT)을 생성 - npmrc 등록 스크립트
설치 전에 npm 인증을 확인하여 인증이 필요하면 토큰을 입력받고, 필요 없으면 그대로 설치를 진행하는 스크립트를 적용해 설치하고 있습니다.
"scripts": {
"setup-npm-and-install": "npm run setup-npm && pnpm i",
}
#!/bin/bash
NPMRC="$HOME/.npmrc"
REGISTRY_URL="https://npm.pkg.github.com"
NAMESPACE="@hits-ai"
check_login(){
npm whoami --registry="$REGISTRY_URL" > /dev/null 2>&1
}
save_token(){
if [ ! -f "$NPMRC" ]; then
touch "$NPMRC"
echo "'$NPMRC' Created"
fi
if grep -q "$REGISTRY_URL" "$NPMRC"; then
echo "Invalid token"
sed -i.bak "/$NAMESPACE:registry=$REGISTRY_URL/d" "$NPMRC" 2>/dev/null
sed -i.bak "/\/\/npm.pkg.github.com\/:_authToken=/d" "$NPMRC" 2>/dev/null
fi
echo -n "GitHub Personal Access Token: "
read -s TOKEN
echo
echo "" >> "$NPMRC"
echo "$NAMESPACE:registry=$REGISTRY_URL" >> "$NPMRC"
echo "//npm.pkg.github.com/:_authToken=$TOKEN" >> "$NPMRC"
echo "Token saved to ~/.npmrc"
}
if check_login; then
echo "Login Success"
exit 0
fi
MAX_TRY=3
for ((i = 1; i <= MAX_TRY; i++)); do
save_token
if check_login; then
echo "Login Success"
exit 0
else
echo "Login Failed. ($i/${MAX_TRY})"
fi
done
배포 환경
기본 환경 (Docker x)
도커환경이 아닌 기본 환경에서는,
배포 액션에 다음과 같이 패키지 설치 전에 Git에 설정되어 있는 인증 토큰을 주입시켜 인증하고 설치를 진행합니다.
# .github/workflows/cd.yml
- name: Authenticate with GitHub Packages
run: |
echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" > ~/.npmrc
- name: Install dependencies
run: pnpm install
Docker 환경
도커 환경에서는 도커파일 내부에서 인증을 해줘야 합니다.
1. git action 파일에서 도커에 환경 변수로 토큰을 지정해 줍니다.
# .github/workflows/cd.yml
file: "apps/Dockerfile"
build-args: |
GITHUB_PAT=${{ secrets.PAT }}
2. docker 파일에서 넘겨받은 토큰으로 인증 후 설치 진행
# apps/Dockerfile
ARG GITHUB_PAT
...
RUN echo "//npm.pkg.github.com/:_authToken=${GITHUB_PAT}" > ~/.npmrc
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
마무리
이번 작업을 통해
gitpackge 방식을 처음으로 접해보면서
버전 관리의 일관성, 자동 배포, 설치 속도 개선을 확보할 수 있었고,
개인적으로도 배포의 흐름 docker를 다루는 방식들을 엿볼 수 있어 재밌었습니다!
'Dev_etc > Git' 카테고리의 다른 글
Release Git Flow_릴리즈 , 태그 생성 자동화 (with. git action) (0) | 2023.09.24 |
---|