Skip to content

[canary-publish] Add missing await and extract correct commit logs. #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 9, 2025
Merged
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
57 changes: 56 additions & 1 deletion canary-publish/README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
57 changes: 56 additions & 1 deletion canary-publish/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
35 changes: 33 additions & 2 deletions canary-publish/dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
});
Expand Down Expand Up @@ -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) {
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion canary-publish/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
Expand Down
39 changes: 38 additions & 1 deletion canary-publish/src/utils/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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 생성
Expand Down