From cf6dc1c48db6e9df877b1e744e48caf342b50d1e Mon Sep 17 00:00:00 2001 From: Bori-github Date: Sun, 19 Jul 2026 01:25:57 +0900 Subject: [PATCH] =?UTF-8?q?ci(release):=20=ED=83=9C=EA=B7=B8=20=EB=A6=B4?= =?UTF-8?q?=EB=A6=AC=EC=A6=88=EC=97=90=20npm=20publish=20=EC=8A=A4?= =?UTF-8?q?=ED=85=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 기존 워크플로는 GitHub Release만 만들고 npm 발행은 수동이었다. 태그(zpl-core/v*·react-zpl/v*) 푸시 시 해당 패키지를 npm에 발행하도록 추가. - pnpm publish로 workspace:* 의존성을 실제 버전으로 치환 (npm publish는 미치환) - --filter "..." 로 대상 패키지의 워크스페이스 의존성까지 위상 순서 빌드 - 프리릴리즈(-rc 등)는 latest 대신 rc dist-tag로 발행 - 이미 올라간 버전은 재실행 시 스킵 (npm 덮어쓰기 금지 대응) - id-token: write + --provenance 로 공급 출처 증명 첨부 발행 토큰은 NPM_TOKEN 시크릿으로 주입한다(레포 설정 필요). Co-Authored-By: Claude Opus 4.8 --- .github/workflows/release.yml | 50 +++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) 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: