Skip to content
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
647 changes: 382 additions & 265 deletions dist/index.mjs

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions fixtures/release_comment/confirm-merged.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!-- eslint-disable markdown/no-multiple-h1 -->
# 🎉 Release pkg-a

## 🌈 1.0.1 `2025-4-7`

### 🚀 Features

- Button:
- 新增属性c @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
- 新增属性a,新增属性b @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
- Link: 新增属性c @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))

### 🐞 Bug Fixes

- Button: 修复属性b @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))

---

# 🎉 Release pkg-b

## 🌈 2.0.0 `2025-4-7`

### 🚀 Features

- Input:
- 新增 size 属性 @liweijie0812 ([#5](https://github.com/liweijie0812/test-mono-log/pull/5))

### 🐞 Bug Fixes

- Select: 修复禁用态样式 @liweijie0812 ([#6](https://github.com/liweijie0812/test-mono-log/pull/6))

---

# 🎉 Release pkg-c

## 🌈 3.0.0 `2025-4-7`

### 📝 Documentation

- 更新 README @liweijie0812 ([#7](https://github.com/liweijie0812/test-mono-log/pull/7))
30 changes: 16 additions & 14 deletions src/github-event/issue-comment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as core from '@actions/core'
import { exec } from '@actions/exec'
import * as github from '@actions/github'
import { globSync } from 'tinyglobby'
import { checkIsForkPr, extractChangelog, extractReleaseLog, getConfiguredPackages, getInputPkgs, getPrCommentWhitelist, getPullRequestNumber, getPullRequestReleaseDirs, stashPackageChangelog } from '../utils/common'
import { checkIsForkPr, extractChangelog, extractReleaseLogs, getConfiguredPackages, getInputPkgs, getPrCommentWhitelist, getPullRequestNumber, getPullRequestReleaseDirs, stashPackageChangelog } from '../utils/common'
import useGit from '../utils/git'
import useGithub from '../utils/github'

Expand Down Expand Up @@ -152,10 +152,12 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
changelogFileName = 'CHANGELOG.en-US.md'
}

const { pkgName, changelog } = extractReleaseLog(log)

core.info(`pkgName: ${pkgName}`)
core.info(`changelog: ${changelog}`)
const releaseLogs = extractReleaseLogs(log)
core.info(`releaseLogs: ${JSON.stringify(releaseLogs, null, 2)}`)
const changelogMap = new Map(releaseLogs.map(item => [item.pkgName, item.changelog]))
if (changelogMap.size !== releaseLogs.length) {
throw new Error('Release log contains duplicate package names')
}

const { getPullRequestData, getPullRequestFiles } = useGithub(token)
const prData = await getPullRequestData(prNumber) as PullRequestData
Expand All @@ -168,7 +170,8 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
const releaseDirs = await getPullRequestReleaseDirs(changeFiles, getConfiguredPackages(cwd()))
core.info(`releaseDirs: ${JSON.stringify(releaseDirs, null, 2)}`)
for (const release of releaseDirs) {
if (release.name !== pkgName) {
const changelog = changelogMap.get(release.name)
if (!changelog) {
continue
}
const files = globSync(`${release.dir}/.changelog/*.md`)
Expand All @@ -194,16 +197,15 @@ async function confirmReleaseLog(prNumber: number, log: string, token: string) {
newData = pkgChangelog.slice(0, index) + changelog + pkgChangelog.slice(index)
}
writeFileSync(`${release.dir}/${changelogFileName}`, newData, 'utf8')
}

await exec('git', ['add', '**/*.md'])
await exec('git', ['status'])
if (!await isNeedCommit()) {
core.info('无需提交')
return true
await exec('git', ['add', '-A', '--', release.dir])
await exec('git', ['status'])
if (await isNeedCommit()) {
const commitMsg = `chore: update ${release.name} ${changelogFileName}`
await exec('git', ['commit', '-m', commitMsg])
}
}
const commitMsg = `chore: update ${pkgName} ${changelogFileName}`
await exec('git', ['commit', '-m', commitMsg])

await exec('git', ['pull'])
await exec('git', ['push', 'origin', prData.head.ref])
}
29 changes: 21 additions & 8 deletions src/github-event/pull-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { PullRequestData } from '../types'
import { cwd } from 'node:process'
import { getInput, info, setOutput } from '@actions/core'
import * as github from '@actions/github'
import { extractChangelog, getConfiguredPackages, getInputPkgs, getPullRequestNumber, getPullRequestReleaseDirs, getStashChangelog, publishRelease, renderChangelogMarkdown, sortReleasePackages } from '../utils'
import { buildReleaseComments, extractChangelog, getConfiguredPackages, getInputPkgs, getPullRequestNumber, getPullRequestReleaseDirs, getStashChangelog, publishRelease, renderChangelogMarkdown, sortReleasePackages } from '../utils'
import useGit from '../utils/git'
import useGithub from '../utils/github'
import { translateText } from '../utils/translate'
Expand Down Expand Up @@ -54,34 +54,47 @@ export async function pull_request(token: string) {
info('没有更新发布版本')
return
}
const zhComments: string[] = []
const enComments: string[] = []
const logHead = '(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n'
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = String(currentDate.getMonth() + 1).padStart(2, '0')
const day = String(currentDate.getDate()).padStart(2, '0')

for (const release of releaseDirs) {
if (release.tag === 'latest') {
const changelogs = getStashChangelog(release.dir, release.type)
info(`changelogs: ${JSON.stringify(changelogs, null, 2)}`)
const md = renderChangelogMarkdown(changelogs.changelogs)
info(`markdownChangelogs: ${md}`)
const logHead = '(删除此行代表确认该日志): 修改并确认日志后删除这一行,机器人会提交到 本 PR 的 CHANGELOG.md 文件中\n'
const currentDate = new Date()
const year = currentDate.getFullYear()
const month = String(currentDate.getMonth() + 1).padStart(2, '0')
const day = String(currentDate.getDate()).padStart(2, '0')
// 中文日志
await addComment(prNumber, `${logHead}# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`)
const zhBody = `# 🎉 发布 ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${md}`
zhComments.push(zhBody)

const secretId = getInput('translate-secret-id', { trimWhitespace: true })
const secretKey = getInput('translate-secret-key', { trimWhitespace: true })
if (secretId && secretKey && md) {
// tmt 翻译
try {
const text = await translateText(secretId, secretKey, md)
info(`en_md: ${text}`)
await addComment(prNumber, `${logHead.replace('CHANGELOG.md', 'CHANGELOG.en-US.md')}# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`)
const enBody = `# 🎉 Release ${changelogs.pkg}\n## 🌈 ${changelogs.version} \`${year}-${month}-${day}\` \n\n${text}`
enComments.push(enBody)
}
catch (err) {
info(`翻译失败,${err}`)
}
}
}
}

for (const comment of buildReleaseComments(logHead, zhComments)) {
await addComment(prNumber, comment)
}
for (const comment of buildReleaseComments(logHead.replace('CHANGELOG.md', 'CHANGELOG.en-US.md'), enComments)) {
await addComment(prNumber, comment)
}
}
}

Expand Down
76 changes: 53 additions & 23 deletions src/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const USE_PASCAL_CASE_REG = /^Use(?=[A-Z])/
const RN_TO_LF_REG = /\r\n/g
const COMMON_PR_REG = /\[common#\d+\]/
const CONTRIBUTOR_WITH_SPACE_REG = /@.*\s$/
const GITHUB_COMMENT_MAX_LENGTH = 65536

export function pascalCase(str: string) {
if (str.toLowerCase() === 'qrcode') {
Expand Down Expand Up @@ -102,34 +103,63 @@ export function extractChangelog(markdown: string, pkgNames: string[]) {
* 提取 release 日志
*/
export function extractReleaseLog(markdown: string) {
const md = parseMarkdown(markdown.replace(RN_TO_LF_REG, '\n'))
let collectLogs = false
let pkgName = ''
const changelog: string[] = []
md.forEach((token) => {
return extractReleaseLogs(markdown)[0] || { pkgName: '', changelog: '' }
}

/**
* 提取单条或合并后的 release 日志
*/
export function extractReleaseLogs(markdown: string) {
const releaseLogs: Array<{ pkgName: string, changelog: string }> = []
let currentLog: { pkgName: string, changelog: string } | undefined

parseMarkdown(markdown.replace(RN_TO_LF_REG, '\n')).forEach((token) => {
if (token.type === 'heading' && token.depth === 1) {
if (token.text.startsWith('🎉 Release')) {
pkgName = token.text.replace('🎉 Release', '').trim()
collectLogs = true
}
else if (token.text.startsWith('🎉 发布')) {
pkgName = token.text.replace('🎉 发布', '').trim()
collectLogs = true
}
else {
collectLogs = false
const pkgName = token.text.startsWith('🎉 Release')
? token.text.replace('🎉 Release', '').trim()
: token.text.startsWith('🎉 发布')
? token.text.replace('🎉 发布', '').trim()
: ''
currentLog = pkgName ? { pkgName, changelog: '' } : undefined
if (currentLog) {
releaseLogs.push(currentLog)
}
return
}
if (collectLogs) {
if (token.type === 'heading' && token.depth > 1) {
changelog.push(`${token.raw.trimEnd()}\n\n`)
}
if (token.type === 'list') {
changelog.push(`${token.raw.trimEnd()}\n\n`)
}

if (currentLog && ((token.type === 'heading' && token.depth > 1) || token.type === 'list')) {
currentLog.changelog += `${token.raw.trimEnd()}\n\n`
}
})

return releaseLogs
}

export function buildReleaseComments(logHead: string, sections: string[], maxLength = GITHUB_COMMENT_MAX_LENGTH) {
const separator = '\n\n---\n\n'
const comments: string[] = []
let body = logHead

sections.forEach((section) => {
const addition = body === logHead ? section : `${separator}${section}`
if (body.length + addition.length <= maxLength) {
body += addition
return
}
if (body === logHead) {
throw new Error('A release changelog section exceeds the GitHub comment length limit')
}
comments.push(body)
body = `${logHead}${section}`
if (body.length > maxLength) {
throw new Error('A release changelog section exceeds the GitHub comment length limit')
}
})
return { pkgName, changelog: changelog.join('') }

if (body !== logHead) {
comments.push(body)
}
return comments
}

export function stashPackageChangelog(prData: PullRequestData, packages: Package[], prChangelog: PackagesChangelog) {
Expand Down
47 changes: 47 additions & 0 deletions test/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,53 @@ exports[`utils > extractReleaseLog 1`] = `
}
`;

exports[`utils > extractReleaseLogs (merged) 1`] = `
[
{
"changelog": "## 🌈 1.0.1 \`2025-4-7\`

### 🚀 Features

- Button:
- 新增属性c @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))
- 新增属性a,新增属性b @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))
- Link: 新增属性c @liweijie0812 ([#2](https://github.com/liweijie0812/test-mono-log/pull/2))

### 🐞 Bug Fixes

- Button: 修复属性b @liweijie0812 ([#4](https://github.com/liweijie0812/test-mono-log/pull/4))

",
"pkgName": "pkg-a",
},
{
"changelog": "## 🌈 2.0.0 \`2025-4-7\`

### 🚀 Features

- Input:
- 新增 size 属性 @liweijie0812 ([#5](https://github.com/liweijie0812/test-mono-log/pull/5))

### 🐞 Bug Fixes

- Select: 修复禁用态样式 @liweijie0812 ([#6](https://github.com/liweijie0812/test-mono-log/pull/6))

",
"pkgName": "pkg-b",
},
{
"changelog": "## 🌈 3.0.0 \`2025-4-7\`

### 📝 Documentation

- 更新 README @liweijie0812 ([#7](https://github.com/liweijie0812/test-mono-log/pull/7))

",
"pkgName": "pkg-c",
},
]
`;

exports[`utils > getMergedPullRequestReleaseDirs 1`] = `
[
{
Expand Down
Loading