diff --git a/canary-publish/README.ko.md b/canary-publish/README.ko.md index ab8acbe..ec38095 100644 --- a/canary-publish/README.ko.md +++ b/canary-publish/README.ko.md @@ -50,9 +50,64 @@ jobs: version_template: '{VERSION}-canary.{DATE}-{COMMITID7}' # (선택) Canary 버전명 템플릿 dry_run: false # (선택) true면 실제 배포 없이 시뮬레이션만 수행 language: 'en' # (선택) 메시지 언어 설정 (en, ko 등) - create_release: false # (선택) true면 Canary 배포 후 GitHub Release 자동 생성. 반드시 @action/checkout에 `fetch-depth: 0` with 옵션을 주세요. + create_release: false # (선택) true면 Canary 배포 후 GitHub Release 자동 생성 ``` +### ⚠️ `create_release: true` 사용 시 주의사항 + +이 액션을 `create_release: true` 옵션과 함께 사용할 때는 아래 사항을 반드시 지켜주세요. + +1. `actions/checkout`의 `fetch-depth: 0` 설정 + + 전체 git 히스토리를 받아와야 릴리즈 노트가 정확하게 생성됩니다. + + ```yml + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ``` + +2. `GH_TOKEN` 환경 변수 설정 + + gh CLI 사용을 위해 인증 토큰이 필요합니다. 아래와 같이 환경 변수로 지정해 주세요. + + ```yml + env: + GH_TOKEN: ${{ github.token }} + ``` + + (job 또는 workflow 전체에 지정해도 됩니다.) + +3. `permissions: contents: write` 권한 추가 + + 릴리즈 생성을 위해 해당 권한이 필요합니다. + + ```yml + permissions: + contents: write + ``` + +예시 워크플로우 + +```yml +permissions: + contents: write + +jobs: + release: + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: NaverPayDev/changeset-actions/canary-publish@main + with: + create_release: true +``` + +**위 설정이 누락되면 릴리즈 생성이 실패할 수 있습니다. 반드시 확인해 주세요!** + ## 실행 결과 ![example](./src/assets/example.png) diff --git a/canary-publish/README.md b/canary-publish/README.md index 2fcb772..25b6695 100644 --- a/canary-publish/README.md +++ b/canary-publish/README.md @@ -50,9 +50,64 @@ jobs: 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. Make sure to add `fetch-depth: 0` `with` option to @action/checkout. + create_release: false # (Optional) If true, creates a GitHub Release after canary publishing. ``` +### ⚠️ Important Notes for `create_release: true` + +When using this action with `create_release: true`, please make sure to: + +1. Set `fetch-depth: 0` for `actions/checkout` + + This ensures the full git history is available for generating release notes. + + ```yml + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + ``` + +2. Set the `GH_TOKEN` environment variable + + The gh CLI requires authentication. Set the token as an environment variable: + + ```yml + env: + GH_TOKEN: ${{ github.token }} + ``` + + Or at the job/workflow level. + +3. Add `permissions: contents: write` to your workflow + + This is required for creating releases via the GitHub API. + + ```yml + permissions: + contents: write + ``` + +Example Workflow Snippet + +```yml +permissions: + contents: write + +jobs: + release: + env: + GH_TOKEN: ${{ github.token }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: NaverPayDev/changeset-actions/canary-publish@main + with: + create_release: true +``` + +**If any of these are missing, the release creation step may fail.** + ## Execution Results ![example](./src/assets/example.png) diff --git a/canary-publish/dist/index.js b/canary-publish/dist/index.js index 0efd3d1..8f435ac 100644 --- a/canary-publish/dist/index.js +++ b/canary-publish/dist/index.js @@ -53401,7 +53401,7 @@ function main() { } catch (e) { core.error(e === null || e === void 0 ? void 0 : e.message); - issueFetchers.addComment(lang_1.LANGUAGES[language].error); + yield issueFetchers.addComment(lang_1.LANGUAGES[language].error); process.exit(1); // close with error } }); @@ -53658,6 +53658,37 @@ function getPublishedPackageInfos({ packagesDir, execOutput, language, }) { publishedPackages: uniqPackages, }; } +/** + * changeset 변경 파일 커밋만 제외하고 작업 커밋 로그만 추출 + */ +function getFilteredCommitMessages({ baseSha, headSha }) { + // 커밋 해시 목록만 추출 + const shas = (0, node_child_process_1.execSync)(`git log --reverse --pretty=format:"%H" ${baseSha}..${headSha}`, { encoding: 'utf8' }) + .split('\n') + .filter(Boolean); + const messages = [ + '## 🚧 Pre-release', + '', + `This release is a **pre-release** version.`, + 'Please make sure to thoroughly test it before deploying to production.', + '', + '### Changes', + '', + ]; + for (const sha of shas) { + // 해당 커밋의 변경 파일 목록 조회 + const files = (0, node_child_process_1.execSync)(`git show --pretty="" --name-only ${sha}`, { encoding: 'utf8' }) + .split('\n') + .filter(Boolean); + // .changeset/*.md 외에 변경된 파일이 하나라도 있으면 커밋 메시지에 추가 + const hasNonChangesetFile = files.some((file) => !/\.changeset\/.*\.md$/.test(file)); + if (hasNonChangesetFile) { + const msg = (0, node_child_process_1.execSync)(`git log -1 --pretty=format:"- %s" ${sha}`, { encoding: 'utf8' }); + messages.push(msg); + } + } + return messages.join('\n'); +} function createReleaseForTags(_a) { return __awaiter(this, arguments, void 0, function* ({ tags, baseSha, headSha, }) { for (const tag of tags) { @@ -53671,7 +53702,7 @@ function createReleaseForTags(_a) { // IGNORE: release가 없으면 진행 } // 커밋 로그 추출하여 릴리즈 노트 생성 - const notes = (0, node_child_process_1.execSync)(`git log ${baseSha}..${headSha} --pretty=format:"- %s"`, { encoding: 'utf8' }); + const notes = getFilteredCommitMessages({ baseSha, headSha }); /** * GitHub Release 생성 * @see https://cli.github.com/manual/gh_release_create diff --git a/canary-publish/src/index.ts b/canary-publish/src/index.ts index 4dfe3e3..b23bdfa 100644 --- a/canary-publish/src/index.ts +++ b/canary-publish/src/index.ts @@ -164,7 +164,7 @@ async function main() { core.setOutput('message', message) } catch (e) { core.error((e as Error)?.message) - issueFetchers.addComment(LANGUAGES[language].error) + await issueFetchers.addComment(LANGUAGES[language].error) process.exit(1) // close with error } } diff --git a/canary-publish/src/utils/publish.ts b/canary-publish/src/utils/publish.ts index 713c71d..cf80d7f 100644 --- a/canary-publish/src/utils/publish.ts +++ b/canary-publish/src/utils/publish.ts @@ -43,6 +43,43 @@ export function getPublishedPackageInfos({ } } +/** + * changeset 변경 파일 커밋만 제외하고 작업 커밋 로그만 추출 + */ +function getFilteredCommitMessages({baseSha, headSha}: {baseSha: string; headSha: string}) { + // 커밋 해시 목록만 추출 + const shas = execSync(`git log --reverse --pretty=format:"%H" ${baseSha}..${headSha}`, {encoding: 'utf8'}) + .split('\n') + .filter(Boolean) + + const messages = [ + '## 🚧 Pre-release', + '', + `This release is a **pre-release** version.`, + 'Please make sure to thoroughly test it before deploying to production.', + '', + '### Changes', + '', + ] + + for (const sha of shas) { + // 해당 커밋의 변경 파일 목록 조회 + const files = execSync(`git show --pretty="" --name-only ${sha}`, {encoding: 'utf8'}) + .split('\n') + .filter(Boolean) + + // .changeset/*.md 외에 변경된 파일이 하나라도 있으면 커밋 메시지에 추가 + const hasNonChangesetFile = files.some((file) => !/\.changeset\/.*\.md$/.test(file)) + + if (hasNonChangesetFile) { + const msg = execSync(`git log -1 --pretty=format:"- %s" ${sha}`, {encoding: 'utf8'}) + messages.push(msg) + } + } + + return messages.join('\n') +} + export async function createReleaseForTags({ tags, baseSha, @@ -63,7 +100,7 @@ export async function createReleaseForTags({ } // 커밋 로그 추출하여 릴리즈 노트 생성 - const notes = execSync(`git log ${baseSha}..${headSha} --pretty=format:"- %s"`, {encoding: 'utf8'}) + const notes = getFilteredCommitMessages({baseSha, headSha}) /** * GitHub Release 생성