자동 릴리스는 버전 태그를 푸시하거나 GitHub Actions 워크플로를 수동으로 시작할 때 샌드박스 플러그인을 빌드하고 게시합니다. Atmosphere 계정은 계속해서 패키지 프로필과 릴리스 레코드의 소유자입니다. GitHub가 승인된 워크플로를 식별하고, 릴리스 서비스가 빌드를 검증한 뒤 좁은 위임을 통해 릴리스를 기록합니다. 저장소에는 Atmosphere 계정 자격 증명이 저장되지 않습니다.
컴퓨터에서 시작하는 릴리스에는 emdash-plugin publish를 사용하세요. GitHub Actions가 릴리스를 빌드하고 게시해야 할 때는 이 가이드를 사용하세요.
사전 요구 사항
시작하기 전에 다음을 준비하세요.
- 샌드박스 EmDash 플러그인이 포함된 공개 GitHub 저장소.
- 개발 의존성으로 설치된
@emdash-cms/plugin-cli. CLI로 만든 플러그인에는 이미 포함되어 있습니다. slug,publisher,license, 작성자, 보안 연락처가 있는 유효한emdash-plugin.jsonc.repo를 정규 GitHub URL로 설정하거나, 대화형 설정 중 감지된 GitHub 원격을 확인하세요.package.json의 버전, 또는 레지스트리 전용 플러그인의 경우emdash-plugin.jsonc의 버전.publisher가 지정한 Atmosphere 계정.- 패스키를 지원하는 브라우저. 릴리스 승인은 사용자 검증이 필요합니다.
워크플로를 구성하기 전에 매니페스트 검사를 실행하세요.
pnpm exec emdash-plugin validate
자동 릴리스 설정
-
패키지를 소유한 Atmosphere 계정으로 플러그인 CLI에 로그인합니다.
pnpm exec emdash-plugin login alice.example.comCLI는 이 로컬 게시 세션을 프로젝트 외부에 저장합니다. GitHub Actions는 이를 받지 않습니다.
-
플러그인 디렉터리에서 패키지 프로필을 준비하고 워크플로를 생성합니다.
pnpm exec emdash-plugin release setup명령은
emdash-plugin.jsonc에서 패키지 메타데이터를 읽습니다. 패키지 프로필이 없으면 생성을 제안합니다. 프로필은 있지만 delegated-release 설정이 없으면 기존 패키지 메타데이터를 유지한 채 추가를 제안합니다.모노레포에서는 플러그인 패키지 안에서 명령을 실행하거나
--dir <plugin-directory>를 전달하세요. 매니페스트에repo가 없으면 설정이 GitHuborigin원격을 감지하고 저장소 프롬프트를 미리 채웁니다.설정은 릴리스에 승인이 필요한 시점을 묻습니다.
- When plugin permissions increase가 기본값입니다. 선언된 접근이 최신 릴리스보다 확대되면 릴리스가 승인을 기다립니다.
- For every release는 모든 버전에 승인을 요구합니다.
설정은 릴리스에 검증 가능한 provenance가 필요한지도 묻습니다. 자동 릴리스의 기본값은 Require provenance입니다. 같은 프로필이 신뢰할 수 있는 로컬 환경에서 직접 게시한 릴리스도 받아야 할 때만 Allow releases without provenance를 선택하세요.
로그인한 Atmosphere 계정이 초기 승인자가 됩니다. 프로필은 패키지를 정규 GitHub 저장소 URL에 바인딩하고 선택한 provenance 정책을 기록합니다.
워크플로 파일이 이미 있으면 프로필 단계만 실행하세요.
pnpm exec emdash-plugin profile setup패키지 프로필을 게시한 후 이 명령은 수동 및 GitHub Actions 릴리스 명령을 표시합니다.
비대화형 터미널에서는
--yes를 전달하여 기본 정책을 수락하세요. 매니페스트와 Git 원격 모두 저장소를 제공하지 않으면--repository <https-url>을, provenance 없는 릴리스를 허용하려면--provenance optional을, 모든 릴리스에 승인을 요구하려면--confirmation always를 전달하세요. -
생성된 워크플로를 검토하고 커밋합니다.
명령은
.github/workflows/emdash-release.yml을 만듭니다. 파일을 푸시하지 않으며--force를 전달하지 않으면 기존 워크플로를 교체하지 않습니다.저장소에
.changeset/config.json이 있으면 대화형 설정이 Follow Changesets releases를 제안합니다. Changesets가emdash-plugin.jsonc를 포함한 패키지를 릴리스하면 재사용 가능한 EmDash 워크플로가 같은 버전을 게시합니다. 아래 설명대로 기존 Changesets 워크플로에 연결하세요. 그렇지 않으면 생성된 워크플로는<slug>@<version>과 일치하는 패키지 태그에서 실행됩니다. 두 변형 모두 수동 실행을 지원하며--trigger changesets|tags|manual로 명시적으로 선택할 수 있습니다.워크플로는 각 작업에 필요한
contents,id-token,attestations권한만 부여하고, 타사 Actions를 전체 커밋 식별자에 고정하며, 파일을 생성한 정확한 플러그인 CLI 버전을 실행하고, 각 패키지를 매니페스트에서 해석하며, 하나의 플러그인 번들을 빌드하고, 해당 정확한 바이트에 대한 GitHub 빌드 provenance를 만든 뒤, 두 파일을 EmDash 릴리스 Action에 전달합니다.워크플로는 저장소 루트에 있으며 해당 저장소의 모든 플러그인 패키지가 공유합니다. 중첩된 패키지에서
release setup을 실행해도 루트에.github/workflows/emdash-release.yml을 씁니다. -
릴리스 서비스 대시보드를 열고 같은 Atmosphere 계정으로 로그인합니다.
Authorize publishing을 선택합니다. 계정 제공자가 정확한 위임 권한을 표시합니다. 유지된 권한은 패키지 릴리스 레코드를 만들고 패키지 또는 목록 이미지 blob을 업로드할 수 있습니다. 패키지 프로필을 만들거나 편집하거나, 릴리스를 업데이트하거나 삭제하거나, 다른 컬렉션에 쓸 수는 없습니다.
-
릴리스 워크플로를 시작합니다.
Changesets를 사용할 때는 버전 풀 리퀘스트를 병합하고 게시 작업이 완료되게 하세요. Changesets Action은 게시한 패키지를 재사용 가능한 EmDash 워크플로에 전달합니다. 일반 npm 패키지는 무시되며,
emdash-plugin.jsonc를 포함한 패키지는 같은 버전을 EmDash에 게시합니다.패키지 태그 트리거를 사용할 때는 버전 태그를 만들기 전에 패키지 버전을 업데이트하세요. 다음 명령은
1.2.3릴리스를 시작합니다.git tag gallery@1.2.3 git push origin gallery@1.2.3저장소의 GitHub Actions 페이지에서 Run workflow를 선택할 수도 있습니다.
-
첫 실행 시 각 저장소 ref 범위를 승인합니다.
서비스는 연결 요청을 만들기 전에 시작 패키지 프로필이 GitHub 저장소를 지정하는지 확인합니다. Action은 GitHub 작업 요약에 링크를 쓰고 대기합니다. 링크를 열고 저장소, 워크플로 파일, 브랜치 또는 태그, 환경을 확인하세요.
태그로 트리거된 실행에서는 All package version tags 또는 Only this tag를 선택하세요. 수동 실행은 해당 브랜치를 처음 사용할 때 승인을 요청합니다. 다른 태그 또는 브랜치 범위를 확인하면 기존 범위를 제거하지 않고 저장소 연결에 추가합니다. 서비스는 GitHub 저장소와 소유자 ID, 승인된 ref와 환경을 저장합니다. 이후 패키지는 서명된 프로필이 같은 저장소를 지정할 때만 이 범위를 재사용합니다.
이전 생성 워크플로가 만든 패키지 승인은 원래 패키지로 제한된 채로 남습니다. 첫 번째 불일치 패키지 또는 ref는 저장소 연결을 요청합니다. 서비스는 기존 패키지 승인을 자동으로 넓히지 않습니다.
-
필요할 때 릴리스를 승인합니다.
플러그인 권한을 확대하는 릴리스, 또는 모든 릴리스에 확인하도록 구성된 프로필은 Awaiting approval 상태가 됩니다. Action 출력 또는 릴리스 대시보드에서 승인 URL을 여세요. 승인 계정에 패스키가 없으면 등록하고, 권한 변경을 검토한 뒤 릴리스를 승인하거나 거부하세요.
기본 Action 설정은 릴리스가 Awaiting approval에 도달하면 성공을 반환합니다. 서비스 워크플로는 브라우저 결정을 계속 기다렸다가 승인 후 게시합니다.
Changesets 워크플로 연결
생성된 .github/workflows/emdash-release.yml은 workflow_call을 통해 Changesets Action의 게시 패키지 JSON을 받습니다. 기존 Changesets 작업에 출력을 추가한 다음 종속 작업에서 EmDash 워크플로를 호출하세요. 기존 작업이나 단계가 다른 ID를 사용하면 release와 changesets를 바꾸세요.
Changesets Action v2는 published-packages 출력을 사용합니다. Changesets CLI v3를 사용하는 워크플로에 다음 작업 출력과 호출자를 추가하세요.
jobs:
release:
# Keep the existing runner, permissions, and steps.
outputs:
published: ${{ steps.changesets.outputs.published }}
published-packages: ${{ steps.changesets.outputs['published-packages'] }}
publish-emdash-plugins:
needs: release
if: needs.release.outputs.published == 'true'
uses: ./.github/workflows/emdash-release.yml
with:
published-packages: ${{ needs.release.outputs['published-packages'] }}
permissions:
contents: read
id-token: write
attestations: write
Changesets Action v1은 camel-case publishedPackages 단계 출력을 사용합니다. Changesets CLI v2를 사용하는 워크플로에는 이 식을 사용하세요.
jobs:
release:
# Keep the existing runner, permissions, and steps.
outputs:
published: ${{ steps.changesets.outputs.published }}
published-packages: ${{ steps.changesets.outputs.publishedPackages }}
publish-emdash-plugins:
needs: release
if: needs.release.outputs.published == 'true'
uses: ./.github/workflows/emdash-release.yml
with:
published-packages: ${{ needs.release.outputs['published-packages'] }}
permissions:
contents: read
id-token: write
attestations: write
버전 풀 리퀘스트와 패키지 게시는 Changesets가 담당하게 두세요. EmDash 호출자는 Changesets가 published: true를 보고할 때만 실행됩니다. EmDash 전용 비공개 패키지의 경우 .changeset/config.json에서 privatePackages.version과 privatePackages.tag를 모두 true로 설정하세요. 관련 없는 비공개 애플리케이션과 테스트 픽스처는 ignore에 추가하세요.
다른 패키지 추가
소스 디렉터리에서 패키지 프로필을 준비합니다. 기존 루트 워크플로와 저장소 연결이 재사용됩니다.
pnpm exec emdash-plugin profile setup --dir packages/comments
Changesets를 사용할 때는 패키지를 changeset에 추가하고 버전 풀 리퀘스트를 병합하세요. 패키지 태그 트리거를 사용할 때는 패키지 버전을 업데이트하고 태그를 푸시하세요.
git tag comments@1.0.0
git push origin comments@1.0.0
워크플로는 comments를 하나의 emdash-plugin.jsonc로 해석하고, 선택한 버전을 확인한 뒤, 아티팩트 업로드를 수락하기 전에 서명된 프로필이 연결된 저장소를 지정하는지 검증합니다. 중복 패키지 ID와 버전 불일치는 attestation 전에 실패합니다.
릴리스 서비스가 검증하는 항목
서비스는 릴리스를 기록하기 전에 다음 검사를 완료합니다.
- GitHub OpenID Connect(OIDC) 토큰이 승인된 저장소, 소유자, 워크플로, ref, 환경, 커밋, 실행, GitHub 호스팅 러너를 지정합니다.
- 패키지 프로필이 존재하고, 게시자가 서명했으며, delegated-release 설정이 포함되어 있고, 같은 정규 GitHub 저장소를 지정합니다.
- 요청된 패키지와 버전이 빌드된 플러그인 번들과 일치합니다.
- 패키지 체크섬이 업로드된 바이트와 일치합니다.
- GitHub provenance가 같은 번들, 저장소, 워크플로, 커밋, 실행을 포함합니다.
- 릴리스 레코드의 선언된 접근이 번들 매니페스트와 일치합니다.
- 버전 레코드가 아직 존재하지 않습니다.
- 필요한 패스키 승인이 정확한 검증 결과와 현재 프로필 리비전을 포함합니다.
Action은 서비스 호출마다 새 GitHub OIDC 토큰을 요청합니다. 번들과 provenance 파일은 워크플로가 승인된 후에만 비공개 임시 저장소에 들어갑니다. 서비스는 검증된 패키지와 이미지 바이트를 게시자의 개인 데이터 서버(PDS)에 업로드하고, 거기에 릴리스 레코드를 만든 뒤, 체크섬으로 주소가 지정된 불변 URL을 통해 검증된 provenance를 노출합니다.
권한 경계
각 자격 증명에는 하나의 역할이 있습니다.
| Credential | Used by | Authority |
|---|---|---|
| Local CLI OAuth session | emdash-plugin profile setup | Create or update the publisher-owned package profile after local confirmation. |
| GitHub OIDC token | Release Action | Identify one GitHub workflow run to the service. It grants no AT Protocol write access. |
| Release-service delegation | Release service | Create package release records and upload the required blobs. |
| Publisher application session | Release dashboard | Authorise workflow connections and revoke delegated publishing. |
| Approver session and passkey | Approval page | Approve or reject one checksum-bound release verification. |
| Cloudflare Access identity | Service operator console | Operate the hosted service. It does not represent a publisher or approver. |
서비스는 게시자와 승인자 상태를 따로 저장합니다. 릴리스를 보기 위해 로그인해도 운영자 접근이 부여되지 않으며, 운영자 신원은 게시자로서 릴리스를 승인할 수 없습니다.
Action 동작
생성된 워크플로는 apps/release-action의 Action을 사용합니다. Action은 빌드된 번들 + 원시 Sigstore provenance, 또는 체크섬에 바인딩된 HTTPS 아티팩트 소스가 포함된 호환 release-file을 받습니다. release-file을 번들 또는 provenance 입력과 함께 사용하지 마세요.
표준 생성 워크플로는 다음 입력을 제공합니다. 각 값이 무엇을 승인하는지 추론하지 않고 생성된 파일을 검토할 수 있도록 여기에 표시합니다.
| Input | Value |
|---|---|
service-url | Release-service HTTPS origin. |
publisher-did | DID that owns the package profile and releases. |
bundle-file | The single tarball produced by emdash-plugin release prepare. |
provenance-file | Raw bundle-path output from actions/attest-build-provenance. |
Action은 다음 출력을 반환합니다.
| Output | Meaning |
|---|---|
connection-url | Browser URL for first-run workflow approval. |
intent-id | Release intent identifier. |
state | Published, terminal, or awaiting_approval state. |
approval-url | Browser URL when passkey approval is required. |
release-uri | Published release AT URI. |
release-cid | Published release record CID. |
reason-code | Stable reason for a terminal intent. |
선택 입력, 사용자 지정 URL 소스 워크플로, 폴링 제어, 정확한 출력 동작은 Action 참조를 보세요.
문제 해결
PACKAGE_PROFILE_REQUIRED
패키지 프로필이 없거나, delegated-release 설정이 없거나, 비정규 저장소 URL을 사용하거나, GitHub 워크플로와 다른 저장소를 지정합니다.
게시자 계정으로 로컬에서 프로필 설정을 실행한 뒤 워크플로를 다시 시작하세요.
pnpm exec emdash-plugin profile setup
이 검사는 서비스가 번들 또는 provenance 업로드를 수락하기 전에 실행됩니다.
공개 저장소 필요
GitHub는 비공개 및 내부 저장소에 비공개 Sigstore 신뢰 루트를 사용합니다. 릴리스 검증기는 현재 공개 GitHub provenance만 신뢰합니다. 릴리스 워크플로를 공개 저장소로 옮기거나 emdash-plugin publish로 로컬에서 게시하세요.
WORKLOAD_NOT_ALLOWED
GitHub 저장소, 소유자, 워크플로 파일, ref 또는 환경이 승인된 워크플로 정책과 일치하지 않습니다. 릴리스 대시보드를 열고 의도한 범위로 새 워크플로 연결을 승인하세요.
PROFILE_FETCH_FAILED
서비스가 게시자의 PDS에서 프로필을 검증하지 못했습니다. 계정 제공자가 사용 가능해지면 다시 시도하세요. 프로필이 제거되거나 변경된 경우 emdash-plugin profile setup을 실행하세요.
POLL_TIMEOUT
Action이 워크플로 승인, 릴리스 승인 또는 게시가 완료되기 전에 timeout-minutes에 도달했습니다. 다시 실행하기 전에 릴리스 대시보드에서 intent 상태를 확인하세요. 같은 GitHub Actions 실행을 다시 실행하면 멱등 키를 재사용합니다.
자동 게시 철회
릴리스 대시보드에서 Turn off automated publishing을 선택하세요. 철회는 유지된 릴리스 위임을 지웁니다. 기존 패키지 프로필, 릴리스, 중재 라벨, 설치된 플러그인, 대시보드 로그인은 변경되지 않습니다.
다음 자동 릴리스 전에 게시를 다시 연결하고 워크플로를 다시 승인하세요.
관련 문서
- Bundling and publishing은 로컬 게시와 번들 검증을 다룹니다.
- The plugin manifest는 패키지 메타데이터와 선언된 접근을 정의합니다.
- Capabilities and security는 릴리스 승인과 설치 시 검토되는 권한을 설명합니다.
- The plugin registry는 검색, 중재, 설치 검증을 설명합니다.