diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 092ea16..2ef997e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,8 +6,10 @@ on: - 'zpl-core/v*' - 'react-zpl/v*' +# GitHub Release 생성(contents)과 npm provenance 서명(id-token)에 필요한 최소 권한. permissions: contents: write + id-token: write concurrency: group: github-release-${{ github.ref }} @@ -48,9 +50,57 @@ jobs: echo "태그 버전($TAG_VER)과 package.json 버전($VER)이 다릅니다: $TAG" exit 1 fi + # 프리릴리즈(0.1.0-rc.1 등)는 latest가 아닌 rc dist-tag로 발행한다. + # 그러지 않으면 `npm install @zpl-kit/react-zpl`이 RC를 집어간다. + case "$VER" in + *-*) NPM_TAG="rc" ;; + *) NPM_TAG="latest" ;; + esac echo "name=${NAME}" >> "$GITHUB_OUTPUT" echo "version=${VER}" >> "$GITHUB_OUTPUT" echo "title=${NAME} v${VER}" >> "$GITHUB_OUTPUT" + echo "npmtag=${NPM_TAG}" >> "$GITHUB_OUTPUT" + + - uses: pnpm/action-setup@v4 + + - uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: pnpm + registry-url: https://registry.npmjs.org + + - name: 의존성 설치 + run: pnpm install --frozen-lockfile + + # exports가 dist를 가리키므로 발행 전 빌드가 반드시 선행되어야 한다. + # `...` 선택자로 대상 패키지의 워크스페이스 의존성(react-zpl→zpl-core)까지 + # 위상 순서대로 함께 빌드한다. + - name: 빌드 + env: + NAME: ${{ steps.meta.outputs.name }} + run: pnpm --filter "${NAME}..." build + + - name: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + NAME: ${{ steps.meta.outputs.name }} + VERSION: ${{ steps.meta.outputs.version }} + NPM_TAG: ${{ steps.meta.outputs.npmtag }} + run: | + set -euo pipefail + # 이미 올라간 버전이면 재발행하지 않는다. npm은 덮어쓰기를 막으므로 + # 태그 재푸시·재실행 시 워크플로 전체가 실패하는 걸 방지한다. + if npm view "${NAME}@${VERSION}" version >/dev/null 2>&1; then + echo "이미 publish된 버전: ${NAME}@${VERSION} — 스킵" + exit 0 + fi + # --no-git-checks: 태그 detached 체크아웃 + 빌드 산출물 때문에 필요. + # --provenance: id-token 권한으로 공급 출처 증명을 첨부. + # workspace:* 의존성은 pnpm publish가 발행 시 실제 버전으로 치환한다. + pnpm --filter "${NAME}" publish \ + --no-git-checks \ + --provenance \ + --tag "${NPM_TAG}" - name: GitHub Release 생성 env: