diff --git a/.github/workflows/release_note_check.yml b/.github/workflows/release_note_check.yml new file mode 100644 index 00000000..fad40cbd --- /dev/null +++ b/.github/workflows/release_note_check.yml @@ -0,0 +1,125 @@ +name: PR 发布说明检查 + +on: + pull_request: + types: + - opened + - synchronize + - edited + +jobs: + release-note-check: + runs-on: ubuntu-latest + + steps: + - name: 检出代码 + uses: actions/checkout@v3 + + - name: 设置 Octokit + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const { Octokit } = require("@octokit/rest"); + const octokit = new Octokit(); + + - name: 安装 Node.js + uses: actions/setup-node@v2 + with: + node-version: '14' + + - name: 安装依赖 + run: npm install + + - name: 导入 Core 模块 + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const core = require('@actions/core'); + core.exportVariable('PATH', `${process.env.PATH}:${process.env.RUNNER_TEMP}/_github_home/node_modules/.bin`); + + - name: 检查发布说明 + uses: actions/github-script@v5 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const core = require('@actions/core'); + const { Octokit } = require("@octokit/rest"); + const octokit = new Octokit(); + const pr = context.payload.pull_request; + const releaseNoteRegex = /(fix|feat)/i; + const releaseNoteTitle = pr.title.toLowerCase(); + const releaseNoteBody = pr.body.toLowerCase(); + const approvedLabel = 'approved'; + + function getIssueComment(username) { + const comment = `@${username}, 请在 PR 的标题或正文中添加包含 'fix' 或 'feat' 的发布说明。Please add a release note with 'fix' or 'feat' in the PR title or body.`; + return comment; + } + + async function addLabelToPR(label) { + await octokit.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: [label] + }); + } + + async function addCommentToPR(comment) { + await octokit.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: comment + }); + } + + // 检查是否提供了发布说明 + if (releaseNoteRegex.test(releaseNoteTitle) || releaseNoteRegex.test(releaseNoteBody)) { + console.log("找到发布说明。Release note found."); + + // 检查 PR 是否有 'approved' 标签 + const labels = await octokit.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + + const hasApprovedLabel = labels.data.some(label => label.name.toLowerCase() === approvedLabel); + if (!hasApprovedLabel) { + // 添加 'do-not-merge/release-note-label-needed' 标签 + const label = 'do-not-merge/release-note-label-needed'; + await addLabelToPR(label); + console.log(`已向 PR 添加标签 '${label}'。Label '${label}' added to the PR。`); + + // 添加评论请求批准 + const issueComment = getIssueComment(pr.user.login); + await addCommentToPR(issueComment); + core.setFailed("需要发布说明。无法合并 PR。Release note required. PR cannot be merged."); + } else { + console.log(`PR 有 '${approvedLabel}' 标签。可以合并。PR has the '${approvedLabel}' label. It can be merged.`); + } + } else { + console.log("未找到发布说明。Release note not found."); + + const labels = await octokit.issues.listLabelsOnIssue({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number + }); + + let hasApprovedLabel = labels.data.some(label => label.name.toLowerCase() === approvedLabel); + if (!hasApprovedLabel) { + const label = 'do-not-merge/release-note-label-needed'; + await addLabelToPR(label); + console.log(`已向 PR 添加标签 '${label}'。Label '${label}' added to the PR。`); + + const issueComment = getIssueComment(pr.user.login); + await addCommentToPR(issueComment); + core.setFailed("需要发布说明。无法合并 PR。Release note required. PR cannot be merged."); + } else { + console.log(`PR 有 '${approvedLabel}' 标签。可以合并。PR has the '${approvedLabel}' label. It can be merged.`); + } + }