npm Trusted Publishers로 GitHub Actions 자동 배포 구축하기.md
들어가며
npm 패키지를 배포할 때마다 로컬에서 npm publish를 실행하는 것은 번거로운 일입니다. GitHub Actions를 통해 자동화하고 싶지만, npm 토큰을 관리하는 것도 부담스럽죠.
이 글에서는 npm의 Trusted Publishers 기능을 사용하여 토큰 없이도 안전하게 자동 배포하는 방법을 소개합니다.
Trusted Publishers란?
npm Trusted Publishers는 OpenID Connect (OIDC)를 사용하여 CI/CD 환경에서 npm에 인증하는 방식입니다.
기존 방식 (Access Token)
- npm 토큰을 생성하고 GitHub Secrets에 저장
- 토큰이 노출되면 보안 위험
- 토큰 만료 시 수동 갱신 필요
Trusted Publishers
- 토큰 없이 GitHub Actions가 직접 npm에 인증
- GitHub의 신원 증명을 통해 배포 권한 부여
- 더 안전하고 관리가 편함
전체 작업 흐름
- npm에 첫 배포 (수동)
- npm에서 Trusted Publishers 설정
- GitHub Actions 워크플로우 작성
- Release 생성으로 자동 배포
1단계: 패키지 준비
package.json 설정
Trusted Publishers는 provenance(출처 증명)를 검증하기 때문에 repository 필드가 정확해야 합니다.
{
"name": "@pksung1/expo-store-signing",
"version": "1.0.0",
"description": "Expo config plugin for Android store signing",
"main": "plugin/build/index.js",
"repository": {
"type": "git",
"url": "https://github.com/pksung1/expo-store-signing.git"
},
"homepage": "https://github.com/pksung1/expo-store-signing",
"publishConfig": {
"access": "public"
},
"scripts": {
"build": "cd plugin && tsc",
"prepare": "npm run build"
},
"files": [
"plugin/build",
"app.plugin.js"
],
"keywords": ["expo", "expo-plugin", "android", "signing"],
"author": "pksung1",
"license": "MIT",
"dependencies": {
"@expo/config-plugins": "^9.0.0"
},
"devDependencies": {
"typescript": "^5.0.0"
}
}
중요 포인트:
repository.url: 정확한 GitHub 저장소 URLpublishConfig.access: scoped package는public필수files: 배포될 파일 목록 명시
Scoped Package 사용 시
@username/package-name 형태로 배포하려면 npm Organization이 필요합니다.
https://www.npmjs.com/org/create 에서 Organization을 생성하세요 (무료).
2단계: 첫 배포 (로컬)
Trusted Publishers는 이미 존재하는 패키지에만 적용되므로, 첫 배포는 수동으로 해야 합니다.
# npm 로그인
npm login
# 빌드
pnpm build
# 배포
npm publish --access public
성공하면 다음과 같이 출력됩니다:
+ @pksung1/expo-store-signing@1.0.0
3단계: npm Trusted Publishers 설정
3-1. npm 패키지 페이지 접속
배포된 패키지 페이지로 이동합니다.
https://www.npmjs.com/package/@pksung1/expo-store-signing
3-2. Trusted Publishers 추가
- Settings 탭 클릭
- Publishing access 섹션으로 스크롤
- Trusted publishers → Add a trusted publisher 클릭
- 다음 정보 입력:
- Provider: GitHub Actions
- GitHub organization/user:
pksung1(본인 username) - Repository name:
expo-store-signing - Workflow filename:
publish.yml - Environment (선택): 비워두거나
production
- Add 클릭

4단계: GitHub Actions 워크플로우 작성
.github/workflows/publish.yml 파일을 생성합니다.
name: Publish to npm
on:
release:
types: [created]
jobs:
publish:
runs-on: ubuntu-latest
# ⭐ 중요: OIDC 인증을 위한 권한
permissions:
contents: read
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm build
# ⭐ 중요: --provenance 플래그 추가
- name: Publish to npm
run: pnpm publish --access public --no-git-checks --provenance
핵심 포인트
1. permissions 설정
permissions:
contents: read
id-token: write # OIDC 토큰 발급을 위해 필수
2. —provenance 플래그
pnpm publish --provenance
이 플래그는 패키지의 출처를 증명하는 서명을 생성합니다. Sigstore를 통해 투명하게 기록됩니다.
3. NODE_AUTH_TOKEN 불필요
기존 방식과 달리 환경변수로 토큰을 전달할 필요가 없습니다. GitHub Actions의 OIDC 토큰이 자동으로 사용됩니다.
5단계: 배포 테스트
버전 업데이트
# 버전 업데이트
npm version patch # 1.0.0 → 1.0.1
# 커밋 & 태그 푸시
git push --follow-tags
GitHub Release 생성
- GitHub 저장소 → Releases 탭
- Create a new release 클릭
- 태그 선택 (예:
v1.0.1) - Release 제목 입력
- Publish release 클릭
그러면 자동으로:
- GitHub Actions 워크플로우 실행
- 패키지 빌드
- npm에 자동 배포
- Provenance 서명 생성
Actions 로그 확인
Actions 탭에서 워크플로우 실행 로그를 확인할 수 있습니다.
성공하면 다음과 같은 로그를 볼 수 있습니다:
npm notice Publishing to https://registry.npmjs.org/ with tag latest and public access
npm notice Signed provenance statement with source and build information from GitHub Actions
npm notice Provenance statement published to transparency log
+ @pksung1/expo-store-signing@1.0.1
트러블슈팅
1. 404 Not Found 에러
npm error 404 Not Found - PUT https://registry.npmjs.org/@pksung1%2fexpo-store-signing
원인: 패키지가 아직 존재하지 않음
해결: 로컬에서 첫 배포를 먼저 해야 합니다.
npm publish --access public
2. Provenance 검증 실패
Error verifying sigstore provenance bundle:
Failed to validate repository information:
package.json: "repository.url" is "", expected to match "https://github.com/..."
원인: package.json의 repository.url이 비어있거나 잘못됨
해결: repository.url을 정확히 입력
{
"repository": {
"type": "git",
"url": "https://github.com/username/repo.git"
}
}
3. Git Unclean 에러
ERR_PNPM_GIT_UNCLEAN Unclean working tree. Commit or stash changes first.
원인: 빌드 과정에서 생성된 파일이 Git 상태를 변경함
해결: --no-git-checks 플래그 추가
pnpm publish --no-git-checks
4. Permissions 에러
Error: Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable
원인: id-token: write 권한 누락
해결: 워크플로우에 permissions 추가
permissions:
contents: read
id-token: write
모노레포에서 특정 패키지만 배포
pnpm workspace를 사용하는 모노레포라면:
name: Publish Package
on:
push:
tags:
- 'package-name-v*'
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: '18'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
# 특정 패키지만 빌드
- name: Build package
run: pnpm --filter @pksung1/expo-store-signing build
# 해당 디렉토리에서 배포
- name: Publish to npm
working-directory: packages/expo-store-signing
run: pnpm publish --access public --no-git-checks --provenance
보안 강화: Environment 사용
더 안전한 배포를 위해 GitHub Environment를 설정할 수 있습니다.
Environment 생성
- GitHub 저장소 → Settings → Environments
- New environment → 이름:
production - Protection rules 설정:
- Required reviewers: 특정 사용자 승인 필요
- Wait timer: 배포 전 대기 시간
- Deployment branches:
main브랜치만 허용
워크플로우에 적용
jobs:
publish:
runs-on: ubuntu-latest
environment: production # Environment 지정
permissions:
contents: read
id-token: write
steps:
# ...
npm Trusted Publishers에도 추가
npm의 Trusted Publishers 설정에서 Environment 필드에 production 입력
이제 배포 시 승인 과정을 거치게 됩니다.
Provenance의 장점
--provenance 플래그를 사용하면 패키지에 다음 정보가 서명되어 기록됩니다:
- 소스 코드 저장소
- 빌드 환경 (GitHub Actions)
- 빌드 시점
- 커밋 해시
사용자는 이를 통해 패키지의 출처를 검증할 수 있습니다:
npm view @pksung1/expo-store-signing --json | jq .dist.integrity
Sigstore 투명성 로그에서도 확인 가능: https://search.sigstore.dev/
기존 토큰 방식과 비교
| 항목 | Access Token | Trusted Publishers |
|---|---|---|
| 설정 복잡도 | 간단 | 중간 |
| 보안 | 토큰 노출 위험 | 더 안전 |
| 토큰 관리 | 수동 갱신 필요 | 불필요 |
| Provenance | 선택사항 | 자동 포함 |
| 첫 배포 | CI에서 가능 | 수동 필요 |
결론
npm Trusted Publishers를 사용하면:
✅ 토큰 관리 부담 없음
✅ 더 안전한 배포
✅ 자동 provenance 서명
✅ GitHub Release로 간편한 배포
초기 설정은 약간 복잡하지만, 한 번 설정하면 훨씬 편리하고 안전하게 패키지를 관리할 수 있습니다.