npm 패키지 배포, turborepo, trusted publisher, pnpm
Source: Dev.to
일주일 전에 제 개인 모노레포를 업데이트하는 작업을 시작했습니다(아직도 작업 중입니다).
모든 작업 중에서 패키지를 배포하는 것이 가장 복잡한 작업 중 하나였으며, 여기서 왜 복잡할 수 있는지 설명합니다.
이전 방식
내 이전 프로세스는 꽤 간단했습니다:
- npmjs에 로그인합니다.
- 액세스 토큰을 생성합니다.
- 토큰을 배포 프로세스에 추가합니다.
NPM_TOKEN환경 변수와 semantic‑release용GITHUB_TOKEN을 생성합니다.
그리고 끝!
하지만 npmjs는 보안 정책을 변경했으며 이제 전통적인 토큰 대신 OpenID Connect를 사용하는 trusted publishing 사용을 권장합니다.
Trusted Publishing 설정
1. 패키지를 최소 한 번은 게시하기
npmjs에서 trusted publisher 설정을 만들기 전에 패키지가 레지스트리에 존재해야 합니다.
새 패키지를 게시하려면 수동으로 한 번 게시하세요 (예: pnpm publish --tag dummy) 또는 setup-npm-trusted-publish 도구를 사용하세요.
2. trusted publisher 추가하기
패키지 설정 섹션에 접근합니다:
https://www.npmjs.com/package//access- 또는
https://www.npmjs.com/package///access
그 다음, trusted publisher 정보(GitHub 또는 GitLab)를 추가합니다.
아래와 비슷한 화면이 나타날 것입니다:
입력해야 할 항목
- 조직 또는 사용자
- 레포지토리
- 워크플로 파일 이름 (확장자 포함). 주의:
.github/workflows안에 있어야 합니다.

제 경우:
- 조직:
dezkareid - 레포지토리:
dezkareid - 워크플로 파일:
ci-packages.yml
완료! 설정이 끝났으며 이제 워크플로로 넘어갈 수 있습니다.
Source:
GitHub Actions에서 Trusted Publishing 설정
1. Job 권한
GitHub이 OIDC 토큰을 얻을 수 있도록 id-token 권한을 활성화해야 합니다:
permissions:
id-token: write
또한 semantic‑release를 사용해 태그를 만들고, changelog를 생성하며 GitHub에 배포한다면 추가 권한이 필요합니다:
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
2. 워크플로 예시
semantic‑release 저장소에는 GitHub Actions용 설정 예시가 포함되어 있습니다.
3. semantic-release 설정
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
pnpm을 사용한 모노레포에서 발생한 문제들
모노레포 + pnpm 아키텍처
- 프로젝트 위치: 모노레포에서는 우리가 배포하려는 패키지에 해당하는 워크스페이스를 지정해야 합니다.
- pnpm 인증: pnpm은 워크스페이스를 npm과 다르게 관리하여 인증 오류가 발생했습니다.
구체적인 오류
-
워크플로 파일 이름 오류
trusted publishing 설정에 파일 이름을 올바르게 추가하지 않아 npm이 OIDC 설정을 찾지 못했습니다. -
Turborepo에 의해 필터링된 환경 변수
release명령이 turborepo를 통해 실행되면서 환경 변수가 필터링되었습니다. 작업 디렉터리(working-directory)를 패키지 폴더로 지정하고semantic-release를 직접 실행하여 문제를 해결했습니다. -
@semantic-release/npm플러그인이 pnpm에서 동작하지 않음
이 플러그인은 npm을 패키지 매니저로 가정합니다. pnpm을 사용할 경우 인증이 실패했습니다. 해결책은 전용 플러그인을 사용하는 것이었습니다:npm i -D @anolilab/semantic-release-pnpm
최종 semantic-release 설정
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@anolilab/semantic-release-pnpm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
이러한 설정을 적용하면 pnpm으로 관리되는 모노레포에서 trusted publishing을 사용해 패키지를 배포하는 것이 문제 없이 작동합니다. Happy releasing!
{
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"releaseRules": [
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" },
{ "type": "perf", "release": "patch" },
{ "type": "refactor", "release": "patch" },
{ "type": "docs", "release": false },
{ "type": "style", "release": false },
{ "type": "chore", "release": false },
{ "type": "test", "release": false }
]
}
],
"@semantic-release/github"
],
"extends": "semantic-release-monorepo"
}
이제 이 설정으로 선호하는 스택을 사용하여 패키지를 다시 게시할 수 있습니다. 제가 워크플로우를 남겨두니 확인해 보시고, 도움이 된다면 복제해 보세요 :D
