昇腾CANN社区治理:一个PR从提交到合并的全过程
前言
昇腾CANN在AtomGit上开源了55个仓库,代码贡献者来自华为内部、高校、企业。这么多人在同一个项目里写代码,如果没有治理规范,仓库很快就会乱掉——commit message五花八门、代码风格不统一、未签协议的代码混入。
community和cann-agreements这两个仓库,就是昇腾CANN社区的"治理基础设施"。community定义了贡献流程和评审规则,cann-agreements管理贡献者许可协议(CLA)。一个PR从提交到合并,这两个仓库的规则贯穿始终。
这篇会把一个PR的完整生命周期拆清楚,从Fork到Merge,每一步该做什么、容易踩什么坑。
社区治理体系
两个仓库的分工:
| 仓库 | 职责 | 核心内容 |
|---|---|---|
| community | 流程治理 | 贡献指南、评审规则、行为准则、Issue模板 |
| cann-agreements | 法律治理 | CLA文本、签署流程、贡献者名单 |
CLA(贡献者许可协议)
CLA是开源社区的"入场券"。签了CLA,意味着你同意你的贡献遵循项目的开源协议(Apache 2.0)。不签CLA,PR直接被机器人关掉。
昇腾CANN的CLA分两种:
- 个人CLA:个人贡献者签署
- 企业CLA:企业代表签署(员工的贡献由企业协议覆盖)
PR完整生命周期
1. 签署CLA 2. Fork仓库 → 创建分支 3. 开发 + 测试 4. 提交PR(commit message规范) 5. CI自动检查 6. Reviewer审查 7. Maintainer合并第1步:签署CLA
# 访问CLA签署页面# https://atomgit.com/cann/cann-agreements# 点击"Sign Individual CLA"# 用AtomGit账号OAuth授权# 签署完成后,你的AtomGit ID会被记录到贡献者名单签署后,机器人会在你的PR下评论:
✅ CLA check passed. Thank you for signing the Contributor License Agreement.第2步:Fork仓库 → 创建分支
# Fork目标仓库到自己的账号# 在AtomGit页面点击Fork按钮# 克隆你的Forkgitclone https://atomgit.com/<your-username>/ops-math.gitcdops-math# 创建特性分支(命名规范:类型/简短描述)gitcheckout-bfeat/add-philox-random-engine# 分支命名规范:# feat/xxx → 新功能# fix/xxx → Bug修复# docs/xxx → 文档更新# refactor/xxx → 重构第3步:开发 + 测试
# 以给ops-math添加Philox随机数引擎为例# 新增文件:ops-math/random/philox_kernel.cpp# 编写代码(遵循昇腾CANN代码规范)# ...(省略具体实现)# 编写测试(必须有测试!无测试的PR不会被接受)# test_philox.pyimporttorchimportops_mathdeftest_philox_basic():"""测试Philox引擎的基本功能"""# 生成1000个随机数rng=ops_math.PhiloxRNG(seed=42)x=rng.uniform(shape=[1000],low=0.0,high=1.0)assertx.shape==(1000,)assert0.0<=x.min()<x.max()<=1.0print("✅ 基本功能测试通过")deftest_philox_reproducibility():"""测试相同种子的可复现性"""rng1=ops_math.PhiloxRNG(seed=42)rng2=ops_math.PhiloxRNG(seed=42)x1=rng1.uniform(shape=[1000])x2=rng2.uniform(shape=[1000])asserttorch.allclose(x1,x2),"相同种子应该产生相同的随机数序列"print("✅ 可复现性测试通过")if__name__=="__main__":test_philox_basic()test_philox_reproducibility()代码讲解:测试代码要覆盖功能正确性和边界条件。test_philox_basic验证基本shape和值域,test_philox_reproducibility验证相同种子生成相同序列。没有测试的PR会被Reviewer直接要求补充。
第4步:提交PR
# 添加改动gitaddops-math/random/philox_kernel.cpp test_philox.py# 提交(遵循Conventional Commits格式,必须有-s签名)gitcommit-s-m"feat(random): add Philox parallel random number engine Implement Philox RNG based on counter-based PRNG design. Supports parallel generation with independent counters per core. Performance: 100M random numbers in 0.3s (vs NumPy 6s). Closes #123"# 推送到Forkgitpush origin feat/add-philox-random-enginecommit message格式规范:
<type>(<scope>): <subject> <body> Closes #<issue-number>| type | 含义 |
|---|---|
| feat | 新功能 |
| fix | Bug修复 |
| docs | 文档 |
| refactor | 重构 |
| test | 测试 |
| chore | 构建/工具 |
代码讲解:-s参数自动添加Signed-off-by:行,这是DCO(Developer Certificate of Origin)要求。Closes #123会在PR合并时自动关闭对应的Issue。subject行不超过50字符,body详细描述改动内容和原因。
第5步:CI自动检查
提交PR后,CI机器人自动执行以下检查:
| 检查项 | 工具 | 失败后果 |
|---|---|---|
| DCO签名 | DCO bot | ❌ 直接拒绝 |
| CLA签署 | CLA bot | ❌ 直接拒绝 |
| 代码格式 | clang-format / black | ❌ 要求修复 |
| 编译 | CANN CI | ❌ 要求修复 |
| 测试 | pytest / CTS | ❌ 要求修复 |
| 代码安全 | 安全扫描 | ⚠️ 人工复查 |
CI结果会显示在PR页面:
✅ DCO check passed ✅ CLA check passed ✅ Code format check passed ✅ Build check passed ✅ Test check passed (42/42 passed)第6步:Reviewer审查
CI通过后,Maintainer会指定Reviewer。Reviewer按以下维度审查:
| 维度 | 关注点 |
|---|---|
| 功能正确性 | 逻辑是否正确,边界是否处理 |
| 性能 | 是否有性能回归 |
| 代码风格 | 是否符合项目规范 |
| 测试覆盖 | 测试是否充分 |
| 文档 | 是否更新了相关文档 |
Reviewer会在代码行内评论:
# 典型的Review评论 ❓ 这里用FP16会不会有精度问题?建议加个FP32的fallback。 → 回复:已添加FP32 variant,见commit abc1234 💡 这个循环可以用向量化替代,性能提升约3倍 → 回复:好建议,已修改第7步:Maintainer合并
Reviewer批准后(通常需要至少1个LGTM),Maintainer执行合并:
# Maintainer操作(在AtomGit Web界面)# 1. 确认CI全部通过# 2. 确认至少1个LGTM# 3. Squash and Merge(压缩为1个commit)# 4. 合并后自动删除分支合并后,贡献者会收到邮件通知,贡献记录出现在项目的贡献者列表中。
踩坑实录
坑1:未签CLA,PR被机器人秒关
现象:提交PR后1分钟内被关闭,机器人评论:“Please sign the CLA before submitting.”
原因:CLA必须先签,后提交。先提交再补签,机器人不会自动重新检查。
解决:先签CLA,再提交PR。如果已经提交了,签完CLA后关闭旧PR重新开一个。
# 签署CLA# 访问 https://atomgit.com/cann/cann-agreements → Sign CLA# 签完后重新提交gitcommit--amend-sgitpush-forigin feat/add-philox-random-engine# 关闭旧PR,创建新PR坑2:commit message没有Signed-off-by,DCO检查失败
现象:CI报错DCO check failed: Commit does not have Signed-off-by.
原因:git commit时忘了加-s参数。
解决:修改最后一个commit的签名。
# 补上签名gitcommit--amend-s# 强制推送(因为修改了历史)gitpush-forigin feat/add-philox-random-engine坑3:一个PR包含多个不相关改动,被要求拆分
现象:Reviewer要求"Please split this PR into separate ones for each feature."
原因:PR里同时改了算子实现、修了文档typo、加了个新测试——三个不相关的改动混在一个PR里,增加了Review难度和回滚风险。
解决:一个PR只做一件事。
# 错误:一个PR包含3个不相关改动gitcommit-s-m"feat: add Philox + fix typo + add test"# 正确:拆成3个独立PR# PR1: feat(random): add Philox engine# PR2: docs: fix typo in README# PR3: test(random): add Philox unit tests结尾
昇腾CANN的社区治理体系由community和cann-agreements两个仓库支撑,定义了从CLA签署到PR合并的完整流程。核心规则:先签CLA、commit格式规范、一个PR只做一件事、必须有测试。
如果想在昇腾CANN开源社区贡献代码,建议先从文档修复和小bugfix入手,熟悉流程后再提交功能PR。实测下来,从Fork到合并,规范提交的PR平均3-5天合并,不规范的PR要来回改2-3周。
昇腾CANN的开源社区还在持续完善治理流程。如果在贡献过程中遇到啥问题,欢迎去AtomGit上的昇腾CANN开源社区逛逛,里面有一手资料和活跃社区。
社区链接
https://atomgit.com/cann/community
https://atomgit.com/cann/cann-agreements
