diff --git a/.github/workflows/auto_label_pr.yml b/.github/workflows/auto_label_pr.yml new file mode 100644 index 00000000..334e35b2 --- /dev/null +++ b/.github/workflows/auto_label_pr.yml @@ -0,0 +1,103 @@ +name: Auto Label PR + +on: + pull_request_target: + types: [opened, edited] + +permissions: + pull-requests: write + issues: write + contents: read + +jobs: + auto-label: + runs-on: ubuntu-latest + steps: + - name: Auto label PR based on PR type + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const prBody = pr.body || ''; + const prNumber = pr.number; + const owner = context.repo.owner; + const repo = context.repo.repo; + + console.log(`Processing PR #${prNumber}`); + + // 如果是 edited 事件,检查是否是描述修改 + if (context.eventName === 'pull_request_target' && context.payload.action === 'edited') { + const changes = context.payload.changes; + if (!changes || !changes.body) { + console.log('PR edited but description not changed, skipping'); + return; + } + console.log('PR description was modified'); + } + + // 定义PR类型到标签的映射 + const typeToLabel = { + 'Feature(功能新增)': 'feature', + 'Bugfix(Bug 修复)': 'bugfix', + 'Docs(文档更新)': 'docs', + 'CI/CD(流水线工程)': 'ci/cd', + 'Refactor(代码重构)': 'refactor', + 'Perf(性能优化)': 'perf', + 'Dependency(依赖更新)': 'dependency', + 'Test-Cases(测试用例更新)': 'test-cases', + 'Other(其他)': 'other' + }; + + // 获取当前PR的所有标签 + const currentLabels = pr.labels.map(label => label.name); + console.log(`Current labels: ${currentLabels.join(', ')}`); + + // 解析PR描述,找到勾选的PR类型 + const selectedTypes = []; + for (const [type, label] of Object.entries(typeToLabel)) { + if (prBody.includes(`- [x] ${type}`)) { + selectedTypes.push(label); + console.log(`Found selected type: ${type} -> ${label}`); + } + } + + // 获取所有可能的PR类型标签 + const allPrTypeLabels = Object.values(typeToLabel); + + // 计算需要添加的标签(选中但不存在) + const labelsToAdd = selectedTypes.filter(label => !currentLabels.includes(label)); + + // 计算需要删除的标签(存在但未选中,且是PR类型标签) + const labelsToRemove = currentLabels.filter(label => + allPrTypeLabels.includes(label) && !selectedTypes.includes(label) + ); + + // 如果没有需要添加或删除的标签,跳过 + if (labelsToAdd.length === 0 && labelsToRemove.length === 0) { + console.log('No label changes needed, skipping'); + return; + } + + // 删除不再需要的标签 + for (const label of labelsToRemove) { + await github.rest.issues.removeLabel({ + owner: owner, + repo: repo, + issue_number: prNumber, + name: label + }); + console.log(`Removed label: ${label}`); + } + + // 添加新标签到PR + if (labelsToAdd.length > 0) { + await github.rest.issues.addLabels({ + owner: owner, + repo: repo, + issue_number: prNumber, + labels: labelsToAdd + }); + console.log(`Added labels: ${labelsToAdd.join(', ')}`); + } + + console.log(`Successfully updated labels for PR #${prNumber}`);