HCCL 贡献流程参考手册:GitCode API、CI 失败诊断与构建验证的完整技术地图
【免费下载链接】hccl集合通信库(Huawei Collective Communication Library,简称HCCL)是基于昇腾AI处理器的高性能集合通信库,为计算集群提供高性能、高可靠的通信方案项目地址: https://gitcode.com/cann/hccl
本篇技术指南以 CANN 集合通信库(HCCL)开源仓库内置的贡献流程参考体系为主体,系统梳理从代码获取、本地构建、Issue/PR 提交到 CI 轮询、失败修复、检视意见处置的端到端链路。读者读完本篇后,将掌握 GitCode 双 API 层的正确用法与已验证行为规律、openlibing CI 平台上各类失败模式的定位与修复模式,以及如何借助仓库内置脚本(contribute.py)将重复性机械操作自动化,从而高效地完成一次从零到 PR 合入的贡献闭环。
一、贡献流程参考体系总览
仓库在.agents/skills/hccl-contribute/下内置了一套完整的贡献流程工作流(触发词覆盖“开发、上库、发 PR、过 CI、修 CI、处理检视意见”等场景),其中references/目录下的参考文档是整套体系的“查表入口”。入口文档(.agents/skills/hccl-contribute/references/README.md)以一张索引表定义了每份参考文档的覆盖范围与“何时加载”,如下所示:
| 文档 | 覆盖 | 何时加载 |
|---|---|---|
| gitcode-api.md | GitCode API 端点、认证、PR/Issue 创建、CI 标签语义、错误码与已验证行为规律 | 调 API(建 Issue/PR/评论/查状态)或排查 API 报错时 |
| ci-triage.md | CI 失败诊断:常见失败模式、codecheck 规则与修复模式、已知非阻塞判定 | CI failed 需要定位修复时 |
| 仓内 AGENTS.md | 构建命令、编码规范、贡献流程(权威来源) | Step 2/3 构建测试前 |
| 仓内 docs/zh/build/build.md | 前置依赖、CANN 安装、环境变量 | Step 2 依赖环境确认时 |
这套索引设计遵循“渐进式披露”原则:入口文档只给必须知道的硬约束与入口,详细内容通过链接渐进式披露(与仓根 AGENTS.md 第 1 节的设计哲学一致)。读者应把本索引当作工作记忆的缓存——在进入某个子流程(调 API、修 CI、构建测试)之前,先定位到对应文档精读。
二、贡献工作流全景:八个可独立运行的子流程
整套工作流定义在 SKILL.md 中,其核心设计是每个子流程可独立运行——本地已有最新代码可从 Step 3/4 起步;只修 CI 从 Step 7 起步;只处理检视意见从 Step 8 起步:
Step 1 代码获取与更新 → Step 2 依赖环境确认 → Step 3 本地构建与测试 ↓ Step 8 检视意见处置 ← Step 7 CI 失败修复 ← Step 6 CI 监控 ← Step 5 PR 创建与提交 ↑ Step 4 Issue 查重与创建八个子流程与参考文档的对应关系:
- Step 1 代码获取与更新:
--sync-repo,无需 token。已有仓执行 fetch 最新 master(干净则快进,脏工作区自动创建隔离 worktree 不动现有改动);全新环境则 clone 到<父目录>/hccl并配好 upstream remote。输出 JSON 的action字段区分cloned/fetched_rebase/fetched_worktree/up_to_date/noop。开发须在新分支进行,分支命名前缀为feature|fix|refactor|perf|docs|test/。 - Step 2 依赖环境确认:按 docs/zh/build/build.md 的「环境准备」节操作,最小校验命令为
source <CANN安装路径>/cann/set_env.sh && echo $ASCEND_HOME_PATH。环境类已知坑详见 ci-triage.md「环境坑」节。 - Step 3 本地构建与测试:按仓 AGENTS.md 第 4 节构建命令执行,推送前优先本地验证
--pkg+ UT + ST。 - Step 4 Issue 查重与创建:
--issue-ensure,需 token。先按标题关键词查重(open+closed),已有则复用,无则按仓惯例前缀创建。 - Step 5 PR 创建与提交:
--submit-pr,脚本自动完成 git 身份校验 → push fork(--force-with-lease)→ 创建 PR(head 用账号:分支格式)→ 评论/compile触发 CI → GET 回查。 - Step 6 CI 监控:
--ci-status(单次)与--ci-status --wait(轮询至终态,默认 60s 间隔 / 30min 超时)。 - Step 7 CI 失败修复:
--ci-logs收集失败信息,诊断修复按 ci-triage.md 失败模式表执行。 - Step 8 检视意见处置:
--list-review-comments列出未 resolved 的检视意见(含文件/行号/作者/内容),处置端点见 gitcode-api.md「检视意见处置」节。
按需配置:只 clone + 本地编译跑测试无需任何配置;要提交 Issue/PR、查 CI、处理检视意见则需 GitCode token,可通过环境变量export GITCODE_TOKEN=<token>(Windows 为$env:GITCODE_TOKEN或set)或 git credential 自动读取。可用python3 .agents/skills/hccl-contribute/scripts/contribute.py --check-env --repo-root <本仓路径>校验配置(token 未配置时记 WARN 不阻断)。验证脚本功能完好(无 GitCode API 依赖)可执行python3 -m unittest discover -s .agents/skills/hccl-contribute/scripts -p test_contribute.py,末行 OK 即正常——该测试文件包含 55 个用例,覆盖 URL 归一化、remote 探测等纯本地逻辑。
依赖环境为 Python 3.7+(仅标准库)、git、能访问 gitcode.com;本地构建须在 Linux 环境。commit 的git user.email必须与 CLA 签署邮箱一致,否则 PR 会被打cann-cla/no。
三、GitCode 双 API 层与端点速查
所有 API 操作细节均来自 gitcode-api.md,该文档是本 skill 调 API 的唯一权威数据源。核心结论是仓库存在两个 API 层,只有 v5 层被实际使用:
| API | 基址 | 认证 | 用途 |
|---|---|---|---|
| v5 | https://gitcode.com/api/v5/ | Bearer 头(脚本内置)或access_token查询参数 | PR/Issue 创建与查询、评论、标签、检视意见(本 skill 唯一数据源) |
| v4 | https://api.gitcode.com/api/v4/ | PRIVATE-TOKEN请求头 | 仅供扩展参考,本 skill 不调用(discussions 的 resolved 恒 None、翻页重复且数据不全,实测不可靠) |
v4 域名必须是api.gitcode.com(gitcode.com/api/v4返回 HTML 非 JSON),这是一个实测踩过的坑。
3.1 端点速查表
GET /api/v5/user token 账号校验 POST /api/v5/repos/cann/hccl/issues 创建 Issue GET /api/v5/repos/cann/hccl/issues?state=open Issue 查重 POST /api/v5/repos/cann/hccl/pulls 创建 PR GET /api/v5/repos/cann/hccl/pulls/{n} PR 元数据(labels/state/mergeable) GET /api/v5/repos/cann/hccl/pulls/{n}/comments PR 评论(流水线链接在 cann-robot 评论里) POST /api/v5/repos/cann/hccl/pulls/{n}/comments 评论(/compile 触发 CI) GET /api/v5/repos/cann/hccl/pulls/comments/{id} 单条评论详情(position.new_path 补文件路径)3.2 关键语义与已验证的坑
这部分是踩坑经验的结晶,直接决定 API 调用的正确性:
- owner 用
cann:PR/Issue 数据挂在官方仓,API 里{owner}不用 fork owner。 - PR 创建
head格式:{fork用户名}:{分支名};fork 改过名时用{fork_owner}/{fork_repo}:{branch}更稳。 - PR 已存在:POST 返回 422
already exist,按state=open列表查回已有 PR 复用,不要重复创建。 - Issue
labels禁数组:v5 创建 Issue 带labels数组必 400;标题按仓模板前缀即可,打标由 maintainer 处理(模板预设的 labels 网页创建时自动带上,API 创建不带)。 - CI 触发:POST 评论
{"body": "/compile"};每次 push 后须重新触发(push 自动移除ci-pipeline-passed标签,cann-robot 会发 Notification)。 - CI 标签流转:
ci-pipeline-failed→(触发)→ci-pipeline-running→(结束)→ci-pipeline-passed或ci-pipeline-failed。 - 终态判定须 saw_running:
ci-pipeline-passed/failed可能是旧 run 残留;必须先见running出现且消失,再看终态标签(脚本已内置状态机)。 - push 分支与 PR head 一致:PR 追踪 fork 的特定分支,push 目标分支必须与 PR head.ref 相同。
- commit 邮箱 = CLA 邮箱:不一致会被打
cann-cla/no,可评论/cla重查。
3.3 CI 日志直链(免登录)
pre-commit 与 markdownlint 两类日志可从 OBS 直链免登录下载,URL 模板为{PR号}:
https://ascend-ci.obs.cn-north-4.myhuaweicloud.com/hccl/package/{PR号}/pre-commit.txt https://ascend-ci.obs.cn-north-4.myhuaweicloud.com/hccl/package/{PR号}/markdownlint.csv流水线详情页的任务日志需浏览器打开(链接在 cann-robot 的触发评论里),该链接提取逻辑在 contribute.py 的parse_pipeline_links中实现——它过滤user == "cann-robot"的评论,用正则提取pipelineDetailURL。
3.4 检视意见处置(线程回复 + resolve)
POST /api/v5/repos/cann/hccl/pulls/{n}/discussions/{did}/comments 线程回复(did 为 hex discussion_id) PUT /api/v5/repos/cann/hccl/pulls/{n}/comments/{did} resolve(body {"resolved": true})两端点均须 Bearer 头认证。did从--list-review-comments输出的discussion_id字段获取。处置纪律:他人意见只回复不 resolve(关闭权在提出者);自提意见修复后 reply+resolve 一站式闭环。回复必须发到原意见线程,不要发独立顶层评论。从源码看(contribute.py 的cmd_list_review_comments),未 resolved 意见的过滤依赖 v5 comments 的resolved字段,文件路径用 v5 单条接口GET /pulls/comments/{id}的position.new_path补齐——因为 v5 列表接口的path常为 None,这是又一个实测确认的接口行为差异。
3.5 错误码与限速
| HTTP | 含义 | 处置 |
|---|---|---|
| 200/201 | 成功 | 写操作仍须 GET 回查 |
| 400 | 参数错误 | 检查 labels 数组 / head 格式 |
| 401 | token 无效 | 检查 GITCODE_TOKEN |
| 422 | 已存在 | 查列表复用已有 Issue/PR |
| 429 | 限速 | 等 60s 重试(脚本 api_request 已内置一次重试) |
两个使用细节:中文 payload 场景下,脚本用 Python urllib UTF-8 编码请求体;手动 curl 时写文件后--data-binary @file.json,禁止-d内联中文。Windows 触发/compile用 Python/PowerShell,不用 Git Bash(/compile会被路径转换毁掉)。
四、CI 失败诊断手册
CI 运行在 openlibing 平台,触发方式为 PR 评论/compile(仓库侧对应.gitcode/workflows/hccl_action.yml中pr_comment/pull_request_comment事件对^(?:\/)?compile*关键字的监听)。任务构成包括:Compile_Ascend_X86/ARM(_ubuntu24)、codecheck(+codestyle)、staticcheck(markdownlint 等)、UT、ST、API_Check、precommit(OAT)、PreSmoke。
4.1 诊断路径
--ci-logs取失败信息:pre-commit/markdownlint 日志从 OBS 直链免登录下载;其他任务看 cann-robot 评论里的流水线链接,浏览器打开任务详情页看日志。- 日志里
grep -E "error|Error|ERROR|FAILED|exit 1"定位根因行。 - 对照失败模式表修复;修不了的(平台问题)记录并重触发。
4.2 C++ 变更常见失败模式(仓主体语言)
| 失败模式 | 特征 | 修复 |
|---|---|---|
| 编译错误(Compile_X86/ARM) | 日志error: | 定位文件行号本地复现:Linux 环境bash build.sh --pkg(命令以仓 AGENTS.md 第 4 节为准);注意 CMake 缓存会掩盖错误,目录结构变更后须清 build 目录重编 |
| clang-format 风格(precommit) | precommit 失败,clang-format hook 报 diff | clang-format -i <文件>(版本须与.pre-commit-config.yaml的 rev 一致);只对本次改动的文件跑,勿全仓格式化 |
| OAT 许可头(precommit) | 日志License Header Invalid | 新增源文件头加 CANN-2.0 许可头,与仓内已有 C++ 文件逐字节一致(对照src/下任一.cc) |
| OAT 二进制误判(precommit) | Invalid File Type — Content: binary | 文件注释改纯英文 ASCII(中文多字节字符被 chardet 误判) |
| UT/ST 用例失败 | UT_Test/ST_Test 任务失败 | 先看是否环境抖动(见“已知非阻塞”);真实失败按日志定位用例,本地bash build.sh -u(-s)复现 |
| 链接错误 | undefined reference to | 检查新增符号是否漏加进 CMakeLists.txt 的目标源文件列表;acl* 符号未定义通常是本地 CANN 版本差异,CI 不报则不阻塞 |
| add_subdirectory 被注释 | 特定模块 .o 缺失、chmod 报错 | 恢复被注释的add_subdirectory(BUILD_OPEN_PROJECT 依赖完整目录树) |
| 目录重命名遗漏 | fatal error: xxx.h: No such file | 全仓 grep 旧路径(含 experimental/):CMakeLists、#include相对路径、cmake/、build.sh、classify_rule.yaml、blacklist.txt |
| CMake 缓存掩盖 | 本地增量通过 CI 失败 | rm -rf build*后干净重编验证 |
| codecheck 静态告警 | codecheck 任务失败,详情页G.*规则 | 浏览器打开 cann-robot 评论里的 entryCheckDashCode 链接看告警清单,按规则修复 |
4.3 codecheck 规则与修复模式
codecheck 对.agents/下 Python 亦全量检查;C++ 告警在 codecheck 任务详情页看规则与行号。新增脚本文件时最常命中以下规则:
| 规则 | 含义 | 修复模式 |
|---|---|---|
| G.LOG.02 | 禁 print | 用logging(basicConfig + LOG.info) |
| G.FMT.02 | 行宽超 120 | 拆行(按字符数算,中文 1 字符) |
| G.FMT.03 | 嵌套 def 前缺空行 | 函数体内定义函数前补空行 |
| G.FMT.04 | 标点后多余空格 | 删多余空格 |
| G.FMT.05/07 | import 位置/顺序 | import 全部放顶部 |
| G.FNM.03 | 函数参数过多(>5) | 用类(如 NamedTuple)封装参数 |
| G.CTL.03 | if 布尔表达式过多(>3) | 提取中间变量或辅助函数 |
| G.EDV.05 | 外部命令无绝对路径 | shutil.which("git")解析绝对路径 |
| G.VAR.03 | 覆盖外部标识符 | 改名避免覆盖顶部 import |
| G.EXP.04 | 推导式子句过多(>2) | 改普通 for 循环 |
| G.CLS.06 | 类的方法排列(helper 应在测试方法后) | helper 方法移到类定义末尾,或提升为模块级函数 |
| G.NAM.02 | 禁单字符变量名(l/I/o) | 改有含义名(item/entry 等) |
| G.ERR.09 | 同一 except 捕父子类异常(如 HTTPError+URLError) | 只捕父类 |
这些规则的实际落地可以从 contribute.py 源码中看到印证:GIT_EXECUTABLE = shutil.which("git") or "git"(对应 G.EDV.05 的修复模式)、顶部import logging后用LOG = logging.getLogger("contribute")(对应 G.LOG.02)、用NamedTuple风格的组织方式等。
4.4 markdownlint(staticcheck_md_check)
按行号修 Markdown 格式,常见三类问题:列表前缺空行(MD032)、有序列表编号风格(MD029)、标题层级跳跃(MD001)。
4.5 环境坑(本地跑 UT/ST 前先排查,全部实测踩过)
| 症状 | 根因 | 处置 |
|---|---|---|
编译报acl* 符号 was not declared | master 用了新版 CANN 才有的符号,本机 CANN 落后 | grep <符号> $ASCEND_HOME_PATH/include/acl/acl_rt.h确认后,按 build.md 镜像站最新时间戳目录下载 toolkit 更新;勿改代码迁就旧 CANN |
UT 的 aicpu 套件报ccl_kernel.json is not a valid real path | 未安装 device kernel:须build.sh --pkg --full并安装到 CANN(chmod -R u+w $CANN && bash build_out/cann-hccl_*.run --full --install-path=$CANN) | 装完重跑;执行测试的 shell 须已 source set_env.sh |
WSLsource set_env.sh后$ASCEND_HOME_PATH仍为空 | set_env.sh 内read -r需要 stdin,bash -c "source ..."内联方式静默失败 | 用 heredoc(wsl << EOF ... EOF)方式执行并回显校验变量 |
ARM 环境 UT 大面积SIGILL/Illegal instruction(37 个测试 dumped core)或 mockcppVirtual method address should be odd失败 | mockcpp 2.7 的自由函数打桩(MOCKER(<libc函数>)的 trampoline)在 aarch64 + gcc 10 系组合下生成非法指令(gdb 可见被桩函数首指令被udf #0覆盖);仓内 CI 的 ARM 通道用 gcc-14 镜像无此问题,master 代码本身支持 ARM | 工具链限制而非代码问题:用 master 干净 worktree 对照确认后可判定环境性失败;在 gcc-14 环境(CI 或 x86)同用例通过即非阻塞 |
4.6 已知非阻塞判定(避免无效返工)
- UT_Test FAILED ≠ 测试失败:日志里
[ PASSED ]/[ FAILED ]只看测试本身;增量覆盖率脚本get_ai_inc_cov.py报错导致的 FAILED 不影响ci_state_passed。先重触发一轮再判断。 - codecheck DEV-CODECI-35002:CI 平台级错误(“构建任务执行失败”),与代码无关,重触发即可。
api-check-failed与ci-pipeline-passed并存:后者是 stale 残留标签(聚合流水线成功已含 API_Check),不需要重触发。- 流水线“过期”提示:GitCode 门禁校验流水线 commitID == PR 当前 head;push 新 commit 后旧 passed 失效属正常,重新
/compile即可。
4.7 修复闭环
修复 → 本地验证(C++ 按仓 AGENTS.md 构建命令;skill 脚本跑单测)→ commit → push → 评论/compile(单次,勿重复)→--ci-status --wait轮询 → 直至passed。
五、saw_running 状态机:CI 终态判定的核心防误判逻辑
--ci-status之所以可靠,核心在于 contribute.py 中judge_ci实现的saw_running 状态机(约第 717 行):
def judge_ci(labels_history, labels_now): """saw_running 状态机判定 CI 终态。 必须出现过 running 且 running 已消失后,才认 passed/failed, 防旧 run 残留的 stale failed 标签误判。 """ saw_running = any(CI_LABEL_RUNNING in labels for labels in labels_history) running_now = CI_LABEL_RUNNING in labels_now passed_now = CI_LABEL_PASSED in labels_now failed_now = CI_LABEL_FAILED in labels_now if running_now: return "running" if saw_running and passed_now: return "passed" if saw_running and failed_now: return "failed" if saw_running: return "finishing" # running 消失但终态标签未上(出标签间隙) if passed_now or failed_now: return "stale" # 无 running 历史的残留标签,不能当本轮结论 return "not_triggered"state语义完整清单:running(流水线运行中)/passed(本轮通过)/failed(本轮失败,进 Step 7)/finishing(running 已消失、终态标签未上,稍等再查)/stale(无 running 历史的残留标签,不可作为本轮结论——此时若刚 push 过应确认 /compile 已触发)/not_triggered(从未触发,需评论/compile)/timeout(轮询超时未达终态,稍后重查)。此外--wait模式下 stale/not_triggered 前 3 个 interval 内不退出——因为/compile评论到 robot 打 running 标签之间有窗口期,立即退出会诱导重复触发。
每次 push 后必须重新/compile(push 会自动失效旧ci-pipeline-passed);触发后不要重复触发(会打断在跑轮次并留下误导性 failed 标签)。
六、CI 流水线在仓库中的实际配置
贡献流程参考索引指向的 CI 行为,在仓库 .gitcode/workflows/hccl_action.yml 中有对应的流水线定义,可从配置层面印证 ci-triage 文档描述的任务构成:
- 触发:
pr_comment/pull_request_comment事件的^(?:\/)?compile*关键字匹配——即评论/compile触发整条流水线。 - stage1 PreBuild:镜像修订(revise-img)+ 预构建(pre_action)。
- stage2 Compile:CodeCheck(codecheck 静态检查)、Compile_Ascend_X86、Compile_Ascend_X86_ubuntu24、Compile_Ascend_ARM、Compile_Ascend_ARM_ubuntu24(monitor 类任务仅 master 分支执行)、CodeCheck_staticcheck_md_check(即 markdownlint)。
- stage3 UT:API_Check(api-check action,校验对外 API 兼容性)、UT_TEST、ST_TEST。
- stage4 PreSmoke:PreSmoke_A2 / PreSmoke_A3 上板冒烟(仅 master 分支,依赖真实 NPU 环境)。
.gitcode/scripts/下还有compile.sh、ut.sh、pre_smoke.sh等被流水线引用的执行脚本。这解释了为什么 ci-triage 文档中api-check-failed与ci-pipeline-passed可以并存——API_Check 是聚合流水线 stage3 的一部分,聚合成功即已包含 API_Check 结果。
七、权威构建、编码规范与提交模板
7.1 构建与测试命令(AGENTS.md 第 4 节)
bash build.sh --pkg # 编译 host 包(默认) bash build.sh -u # 编译并运行 UT bash build.sh -s # 编译并运行 ST bash build.sh --static # 静态库构建 bash build.sh --asan # 启用 AddressSanitizer bash build.sh --custom_ops_path=<PATH> # 自定义算子工程 bash build.sh -j64 # 并行编译编码规范要点(AGENTS.md 第 5 节):命名采用类/函数 PascalCase、成员变量camelCase_、常量与宏UPPER_SNAKE_CASE;风格遵循根目录.clang-format(120 列、4 空格、指针右对齐、K&R 大括号);C++14;pre-commit 为 clang-format v18.1.8 + OAT 合规检查(可在 .pre-commit-config.yaml 中确认版本与 hook 配置),新增源文件须带 CANN-2.0 许可头。本地跑法:pip3 install pre-commit && pre-commit run --files <改动文件>。更完整的工具用法见 docs/zh/build/pre-commit-guide.md。
7.2 依赖环境(build.md)
编译前置依赖:python >= 3.7.0、pip3 >= 20.3.0、gcc & g++ 7.3.0 至 14.2.x、cmake >= 3.16.0、ccache(可选)、googletest(仅 UT,建议 release-1.14.0)。环境准备支持 Docker 部署与宿主机部署两种场景,安装完 CANN Toolkit 后用npu-smi info检查 NPU 设备、用cat /usr/local/Ascend/cann/<arch>-linux/ascend_toolkit_install.info检查 CANN 软件,最后source /usr/local/Ascend/cann/set_env.sh使环境变量生效。完整流程见 docs/zh/build/build.md。
7.3 提交模板
PR 描述必须按仓内 .gitcode/PULL_REQUEST_TEMPLATE.zh-CN.md 模板的六章节填写:描述(改动原因与方法)、关联的 Issue、测试(构造用例、二级冒烟、算子泛化等)、文档更新、类型标签(Bug修复/新特性/性能优化/文档更新/其他)。所有 PR 必须关联 Issue;PR 描述与实现保持一致(内容演进后同步更新描述与 Issue)。
八、执行纪律与建议
- 全自动执行,不中途询问“是否继续”;破坏性命令、
git commit、git push必须得到用户明确许可。 - 严禁向官方仓发测试 PR / 测试评论:验证一律走
--check-env、只读查询或自己的 fork 彩排。 - PR 必须关联 Issue;CI 触发后不重复触发
/compile。 - 构建命令、依赖版本、编码规范以仓内 AGENTS.md、docs/zh/build/build.md 为权威来源,skill 参考文档不复制其内容——这也是整套参考体系“渐进式披露”设计的用意:入口索引(本篇所依据的 README.md)负责导航,专项文档负责深度,权威文档负责唯一事实来源。
【免费下载链接】hccl集合通信库(Huawei Collective Communication Library,简称HCCL)是基于昇腾AI处理器的高性能集合通信库,为计算集群提供高性能、高可靠的通信方案项目地址: https://gitcode.com/cann/hccl
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考