一个健康的开源项目或企业仓库,PR 流程是质量的第一道关卡。但人工维护 PR 流程是枯燥且易出错的——标签忘打、审查人未分配、合并条件未检查、发布版本号手填。GitHub Actions 可以把这些全部自动化:PR 创建时自动打标签、审查通过且 CI 绿时自动合并、合并后自动生成 changelog 和版本发布。本文从 PR 创建到发布后,构建完整的自动化流水线。
一、PR 规范检查
1.1 Semantic PR
# .github/workflows/semantic-pr.yml
name: Semantic PR
on:
pull_request_target:
types: [opened, edited, synchronize]
jobs:
semantic:
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
types: |
feat
fix
docs
style
refactor
perf
test
chore
requireScope: false
subjectPattern: ^[A-Z].+$
subjectPatternError: |
Subject must start with a capital letter
1.2 标题模板
规范格式:<type>(<scope>): <subject>
示例:
feat(auth): add OAuth2 login support
fix(api): resolve race condition in user cache
docs(readme): update installation instructions
refactor(db): migrate from MySQL to PostgreSQL
二、自动标签系统
2.1 基于文件路径
# .github/labeler.yml
# PR 标签自动匹配
"area:docs":
- "docs/**/*"
- "**/*.md"
"area:ci":
- ".github/**/*"
"area:frontend":
- "src/**/*"
- "*.tsx"
- "*.ts"
"area:backend":
- "api/**/*"
- "server/**/*"
"type:dependencies":
- "package.json"
- "package-lock.json"
- "poetry.lock"
# .github/workflows/labeler.yml
name: Labeler
on:
pull_request:
types: [opened, synchronize]
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v4
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
2.2 基于 PR Size
- name: Size Label
uses: codelytv/pr-size-labeler@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
xs_max_size: '50'
s_max_size: '200'
m_max_size: '800'
l_max_size: '2000'
三、审查分配
3.1 CODEOWNERS
# .github/CODEOWNERS
# 全局默认
* @team/frontend
# 后端代码
api/ @team/backend
*.go @team/backend
# 基础设施
infra/ @team/devops
.github/ @team/devops
# 文档
docs/ @team/docs
3.2 Round-robin 分配
- name: Assign Reviewers
uses: kentaro-m/auto-assign-action@v1.2.5
with:
configuration-path: .github/auto_assign.yml
# .github/auto_assign.yml
addReviewers: true
addAssignees: author
numberOfReviewers: 2
reviewers:
- alice
- bob
- charlie
skipKeywords:
- wip
- draft
四、自动合并
4.1 条件自动合并
# .github/workflows/auto-merge.yml
name: Auto Merge
on:
pull_request:
types: [labeled, synchronize]
check_suite:
types: [completed]
jobs:
auto-merge:
runs-on: ubuntu-latest
if: contains(github.event.pull_request.labels.*.name, 'auto-merge')
steps:
- name: Auto-merge
uses: pascalgn/automerge-action@v0.15.6
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
MERGE_LABELS: "auto-merge"
MERGE_REMOVE_LABELS: "auto-merge"
MERGE_METHOD: "squash"
MERGE_COMMIT_MESSAGE: "pull-request-title"
MERGE_REQUIRED_APPROVALS: "1"
MERGE_DELETE_BRANCH: "true"
4.2 合并条件矩阵
| 条件 | 必须 | 可选 |
|---|---|---|
| CI 通过 | ✅ | - |
| 审查批准 | ✅ | - |
| 无冲突 | ✅ | - |
| 标题合规 | ✅ | - |
| 无 stale 标签 | - | ✅ |
| 大小 < 1000 行 | - | ✅ |
五、发布自动化
5.1 semantic-release
# .github/workflows/release.yml
name: Release
on:
push:
branches: [main]
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # 需要完整历史分析提交
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
run: npx semantic-release
// .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
]
]
}
5.2 Changesets(Monorepo)
- name: Create Release Pull Request
uses: changesets/action@v1
with:
publish: npm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
六、Draft PR 与 WIP 管理
6.1 WIP 检查
- name: Check WIP
uses: wip/action@v1
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6.2 Draft PR 自动提示
- name: Comment on Draft PR
if: github.event.pull_request.draft == true
uses: actions/github-script@v6
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '📝 This PR is in draft mode. Please mark as ready when complete.'
})
七、冲突检测与提示
7.1 自动检测冲突
- name: Check merge conflicts
uses: eps1lon/actions-label-merge-conflict@v3
with:
dirtyLabel: "merge-conflict"
removeOnDirtyLabel: "ready"
repoToken: ${{ secrets.GITHUB_TOKEN }}
总结
PR 自动化是现代软件工程的基础设施——规范检查保证提交质量、自动标签加速分类检索、审查分配减少等待时间、自动合并释放人力、发布自动化消除手误。semantic-release 让版本号遵循 semver 自动生成,changesets 让 Monorepo 发布可控。关键是「渐进式引入」:先加 PR 标题检查,再加标签系统,最后做自动合并和发布。每一步都能单独运行、单独回滚。GitHub 的 PR 流程与 Actions 深度集成,给了团队构建完整质量门禁的能力。
延伸阅读:
- GitHub Actions Python CI — CI 门禁
- GitHub Actions 依赖安全 — 安全自动化
- GitHub Actions 定时任务 — 维护自动化
- semantic-release 文档
- Changesets 文档
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。