Skip to content
Merged

OIDC #29

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 84 additions & 1 deletion canary-publish/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # (필수) GitHub API 인증 토큰. 필요시 사용자 PAT로 대체 가능
npm_tag: canary # (선택) 배포에 사용할 npm 태그 (예: canary, beta 등)
npm_token: ${{ secrets.NPM_TOKEN }} # (필수) npm publish를 위한 인증 토큰
publish_script: pnpm run deploy:canary # (필수) Canary 배포를 실행할 스크립트 명령어
packages_dir: packages # (선택) 변경 감지에 사용할 패키지 디렉터리 (기본값: packages,share)
excludes: ".turbo,.github" # (선택) 변경 감지에서 제외할 파일/디렉터리 목록 (쉼표로 구분)
version_template: '{VERSION}-canary.{DATE}-{COMMITID7}' # (선택) Canary 버전명 템플릿
dry_run: false # (선택) true면 실제 배포 없이 시뮬레이션만 수행
language: 'en' # (선택) 메시지 언어 설정 (en, ko 등)
create_release: false # (선택) true면 Canary 배포 후 GitHub Release 자동 생성
provenance: true # (선택) provenance 생성 활성화 (npm CLI 11.5.1+ 필요)
```

### ⚠️ `create_release: true` 사용 시 주의사항
Expand Down Expand Up @@ -108,6 +108,89 @@ jobs:

**위 설정이 누락되면 릴리즈 생성이 실패할 수 있습니다. 반드시 확인해 주세요!**

## NPM OIDC 신뢰할 수 있는 게시

이 액션은 NPM의 OIDC 기반 신뢰할 수 있는 게시를 사용합니다. NPM 토큰을 시크릿으로 저장할 필요가 없으며, 워크플로우별 단기 자격 증명을 사용하여 더 나은 보안을 제공합니다.

### 사전 요구사항

1. **NPM CLI 버전**: npm CLI v11.5.1 이상 필요
2. **GitHub Actions 러너**: GitHub 호스트 러너 사용 필수
3. **NPM 패키지 설정**: npmjs.com에서 신뢰할 수 있는 게시자 설정 필요

### 설정 방법

1. **npmjs.com에서 신뢰할 수 있는 게시자 설정**:
- npmjs.com에서 패키지 설정으로 이동
- "Publishing access" → "Trusted publishers"로 이동
- 다음 정보로 새 신뢰할 수 있는 게시자 추가:
- Organization/User: GitHub 조직 또는 사용자 이름
- Repository: 저장소 이름
- Workflow filename: 워크플로우 파일 이름 (예: `canary-publish.yml`)
- Environment name: (선택) GitHub 환경을 사용하는 경우

2. **워크플로우 업데이트**:
- `id-token: write` 권한 추가
- `npm_token` 입력 제거 (또는 비워두기)
- npm CLI 버전이 11.5.1+ 인지 확인

OIDC를 사용하는 워크플로우 예시:

```yaml
name: changeset canary publish

on:
issue_comment:
types:
- created

permissions:
id-token: write # OIDC에 필수
contents: write # 릴리즈 생성에 필수
pull-requests: write # PR 코멘트에 필수

jobs:
canary:
if: ${{ github.event.issue.pull_request && (github.event.comment.body == 'canary-publish' || github.event.comment.body == '/canary-publish')}}
runs-on: ubuntu-latest
steps:
- name: Get PR branch name
id: get_branch
run: |
PR=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" ${{ github.event.issue.pull_request.url }})
echo "::set-output name=branch::$(echo $PR | jq -r '.head.ref')"

- name: Checkout Repo
uses: actions/checkout@v3
with:
ref: ${{ steps.get_branch.outputs.branch }}

- name: Setup Node with latest npm
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'

- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Canary Publish
uses: NaverPayDev/changeset-actions/canary-publish@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
npm_tag: canary
publish_script: pnpm run deploy:canary
packages_dir: packages
provenance: true
```

### OIDC의 장점

- NPM 토큰을 생성, 저장, 갱신할 필요 없음
- 자동 provenance 증명
- 토큰 유출 위험 감소
- 더 나은 감사 추적

## 실행 결과

![example](./src/assets/example.png)
Expand Down
85 changes: 84 additions & 1 deletion canary-publish/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ jobs:
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # (Required) GitHub API token for authentication. Use a user PAT if necessary.
npm_tag: canary # (Optional) The npm tag to use for deployment (e.g., canary, beta).
npm_token: ${{ secrets.NPM_TOKEN }} # (Required) Token used for npm publishing.
publish_script: pnpm run deploy:canary # (Required) Script command to execute the canary deployment.
packages_dir: packages # (Optional) Directory containing packages to check for changes (default: packages,share).
excludes: ".turbo,.github" # (Optional) Files or directories to exclude from change detection (comma-separated).
version_template: '{VERSION}-canary.{DATE}-{COMMITID7}' # (Optional) Template for the canary version string.
dry_run: false # (Optional) If true, performs a dry run without publishing.
language: 'en' # (Optional) Language for output messages (e.g., en, ko).
create_release: false # (Optional) If true, creates a GitHub Release after canary publishing.
provenance: true # (Optional) Enable provenance statements (requires npm CLI 11.5.1+)
```

### ⚠️ Important Notes for `create_release: true`
Expand Down Expand Up @@ -108,6 +108,89 @@ jobs:

**If any of these are missing, the release creation step may fail.**

## NPM OIDC Trusted Publishing

This action uses NPM's OIDC-based trusted publishing, which eliminates the need for storing NPM tokens as secrets. This provides better security by using short-lived, workflow-specific credentials.

### Prerequisites

1. **NPM CLI Version**: Requires npm CLI v11.5.1 or later
2. **GitHub Actions Runner**: Must use GitHub-hosted runners
3. **NPM Package Configuration**: Configure trusted publishers on npmjs.com

### Setup Steps

1. **Configure Trusted Publisher on npmjs.com**:
- Go to your package settings on npmjs.com
- Navigate to "Publishing access" → "Trusted publishers"
- Add a new trusted publisher with:
- Organization/User: Your GitHub organization or username
- Repository: Your repository name
- Workflow filename: Your workflow file name (e.g., `canary-publish.yml`)
- Environment name: (Optional) If using GitHub environments

2. **Update your workflow**:
- Add `id-token: write` permission
- Remove `npm_token` input (or leave it empty)
- Ensure npm CLI version is 11.5.1+

Example workflow with OIDC:

```yaml
name: changeset canary publish

on:
issue_comment:
types:
- created

permissions:
id-token: write # Required for OIDC
contents: write # Required for creating releases
pull-requests: write # Required for PR comments

jobs:
canary:
if: ${{ github.event.issue.pull_request && (github.event.comment.body == 'canary-publish' || github.event.comment.body == '/canary-publish')}}
runs-on: ubuntu-latest
steps:
- name: Get PR branch name
id: get_branch
run: |
PR=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" ${{ github.event.issue.pull_request.url }})
echo "::set-output name=branch::$(echo $PR | jq -r '.head.ref')"

- name: Checkout Repo
uses: actions/checkout@v3
with:
ref: ${{ steps.get_branch.outputs.branch }}

- name: Setup Node with latest npm
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'

- name: Install Dependencies
run: pnpm install --frozen-lockfile

- name: Canary Publish
uses: NaverPayDev/changeset-actions/canary-publish@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
npm_tag: canary
publish_script: pnpm run deploy:canary
packages_dir: packages
provenance: true
```

### Benefits of OIDC

- No need to create, store, or rotate NPM tokens
- Automatic provenance attestations
- Reduced risk of token exfiltration
- Better audit trail

## Execution Results

![example](./src/assets/example.png)
Expand Down
7 changes: 4 additions & 3 deletions canary-publish/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ inputs:
description: 'npm tag'
default: canary
required: false
npm_token:
description: 'npm token'
required: true
publish_script:
description: 'canary deploy script'
required: true
Expand Down Expand Up @@ -41,3 +38,7 @@ inputs:
description: 'language for release note, comment etc.'
required: false
default: 'en'
provenance:
description: 'Enable provenance statements (requires npm CLI 11.5.1+, uses OIDC if available)'
required: false
default: 'true'
27 changes: 2 additions & 25 deletions canary-publish/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53566,33 +53566,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.setNpmRc = setNpmRc;
const core = __importStar(__nccwpck_require__(6108));
const fs = __importStar(__nccwpck_require__(77));
function setNpmRc() {
return __awaiter(this, void 0, void 0, function* () {
// 입력값에서 npm_token 가져오기
const npmToken = core.getInput('npm_token');
process.env.NPM_TOKEN = npmToken; // 환경변수로 설정
core.info('No changesets found, attempting to publish any unpublished packages to npm');
const userNpmrcPath = `${process.env.HOME}/.npmrc`;
if (fs.existsSync(userNpmrcPath)) {
core.info('Found existing user .npmrc file');
const userNpmrcContent = yield fs.readFile(userNpmrcPath, 'utf8');
const authLine = userNpmrcContent.split('\n').find((line) => {
// check based on https://github.com/npm/cli/blob/8f8f71e4dd5ee66b3b17888faad5a7bf6c657eed/test/lib/adduser.js#L103-L105
return /^\s*\/\/registry\.npmjs\.org\/:[_-]authToken=/i.test(line);
});
if (authLine) {
core.info('Found existing auth token for the npm registry in the user .npmrc file');
}
else {
core.info("Didn't find existing auth token for the npm registry in the user .npmrc file, creating one");
fs.appendFileSync(userNpmrcPath, `\n//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`);
}
}
else {
core.info('No user .npmrc file found, creating one');
fs.writeFileSync(userNpmrcPath, `//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`);
}
core.info('Using OIDC trusted publishing for npm authentication');
core.info('Ensure npm CLI 11.5.1+ is installed and id-token: write permission is set');
});
}

Expand Down
27 changes: 2 additions & 25 deletions canary-publish/src/utils/npm.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
import * as core from '@actions/core'
import * as fs from 'fs-extra'

export async function setNpmRc() {
// 입력값에서 npm_token 가져오기
const npmToken = core.getInput('npm_token')
process.env.NPM_TOKEN = npmToken // 환경변수로 설정

core.info('No changesets found, attempting to publish any unpublished packages to npm')

const userNpmrcPath = `${process.env.HOME}/.npmrc`
if (fs.existsSync(userNpmrcPath)) {
core.info('Found existing user .npmrc file')
const userNpmrcContent = await fs.readFile(userNpmrcPath, 'utf8')
const authLine = userNpmrcContent.split('\n').find((line) => {
// check based on https://github.com/npm/cli/blob/8f8f71e4dd5ee66b3b17888faad5a7bf6c657eed/test/lib/adduser.js#L103-L105
return /^\s*\/\/registry\.npmjs\.org\/:[_-]authToken=/i.test(line)
})
if (authLine) {
core.info('Found existing auth token for the npm registry in the user .npmrc file')
} else {
core.info("Didn't find existing auth token for the npm registry in the user .npmrc file, creating one")
fs.appendFileSync(userNpmrcPath, `\n//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`)
}
} else {
core.info('No user .npmrc file found, creating one')
fs.writeFileSync(userNpmrcPath, `//registry.npmjs.org/:_authToken=${process.env.NPM_TOKEN}\n`)
}
core.info('Using OIDC trusted publishing for npm authentication')
core.info('Ensure npm CLI 11.5.1+ is installed and id-token: write permission is set')
}
78 changes: 77 additions & 1 deletion publish/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,92 @@ jobs:
- uses: NaverPayDev/changeset-actions/publish@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }} # 필요하면 user의 PAT을 넣어주세요.
npm_token: ${{ secrets.NPM_TOKEN }} # npm 배포시 필요한 publish token 을 넣어주세요
publish_script: pnpm run deploy # 배포 실행 script 를 넣어주세요
git_username: npay-fe-bot # 버전업 pr 생성시 설정할 github username 을 넣어주세요
git_email: npay.fe.bot@navercorp.com # 버전업 pr 생성시 설정할 github email 을 넣어주세요
pr_title: 🚀 version changed packages # 버전업 pr 생성시 설정할 pr 타이틀 넣어주세요
commit_message: 📦 bump changed packages version # 버전업 pr 생성시 설정할 commit 메시지를 넣어주세요
create_github_release_tag: true # release tag 생성여부를 넣어주세요
formatting_script: pnpm run markdownlint:fix # 생성되는 md 파일의 formatting이 필요하다면 추가해주세요
provenance: true # (선택) provenance 생성 활성화 (npm CLI 11.5.1+ 필요)
```

## NPM OIDC 신뢰할 수 있는 게시

이 액션은 NPM의 OIDC 기반 신뢰할 수 있는 게시를 사용합니다. NPM 토큰을 시크릿으로 저장할 필요가 없으며, 워크플로우별 단기 자격 증명을 사용하여 더 나은 보안을 제공합니다.

### 사전 요구사항

1. **NPM CLI 버전**: npm CLI v11.5.1 이상 필요
2. **GitHub Actions 러너**: GitHub 호스트 러너 사용 필수
3. **NPM 패키지 설정**: npmjs.com에서 신뢰할 수 있는 게시자 설정 필요

### 설정 방법

1. **npmjs.com에서 신뢰할 수 있는 게시자 설정**:
- npmjs.com에서 패키지 설정으로 이동
- "Publishing access" → "Trusted publishers"로 이동
- 다음 정보로 새 신뢰할 수 있는 게시자 추가:
- Organization/User: GitHub 조직 또는 사용자 이름
- Repository: 저장소 이름
- Workflow filename: 워크플로우 파일 이름 (예: `publish.yml`)
- Environment name: (선택) GitHub 환경을 사용하는 경우

2. **워크플로우 업데이트**:
- `id-token: write` 권한 추가
- `npm_token` 입력 제거 (또는 비워두기)
- npm CLI 버전이 11.5.1+ 인지 확인

OIDC를 사용하는 워크플로우 예시:

```yaml
name: changeset-publish

on:
push:
branches:
- main

permissions:
id-token: write # OIDC에 필수
contents: write # 릴리즈 생성에 필수
pull-requests: write # PR 생성에 필수

concurrency: ${{ github.workflow }}-${{ github.ref }}

jobs:
detectAdd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}

- name: Setup Node with latest npm
uses: actions/setup-node@v4
with:
node-version: '20'
registry-url: 'https://registry.npmjs.org'

- uses: NaverPayDev/changeset-actions/publish@main
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_script: pnpm run deploy
git_username: npay-fe-bot
git_email: npay.fe.bot@navercorp.com
pr_title: 🚀 version changed packages
commit_message: 📦 bump changed packages version
create_github_release_tag: true
provenance: true
```

### OIDC의 장점

- NPM 토큰을 생성, 저장, 갱신할 필요 없음
- 자동 provenance 증명
- 토큰 유출 위험 감소
- 더 나은 감사 추적

## 실행 결과

![example](./src/assets/pr.png)
Expand Down
Loading