Conan通过user/channel字段约定区分包成熟度,推荐用testing/stable等channel标识环境属性,需在conan create中显式指定-u和-c参数,配合远程权限控制、CI校验及test_package动态注入确保一致性。

conan remote add 时 channel 名要体现环境属性
Conan 没有内置的“测试包 / 正式包”类型标识,区分完全靠 user/channel 这两个字段的约定。最直接、最被广泛采用的方式是用 channel 表示成熟度:testing、stable、ci、snapshot 等。
比如:
-
mylib/1.2.0@team/testing—— 供 CI 流水线验证或内部试用 -
mylib/1.2.0@team/stable—— 已通过 QA,允许下游项目引用
注意:user 字段建议统一用团队名(如 team)或组织名(如 acme),避免混用个人账号;channel 不要用时间戳或随机字符串,否则无法被自动化流程识别。
conan create 命令里必须显式指定 -u 和 -c 参数
如果你在本地打包时没传 -u 和 -c,Conan 默认会用 user/channel = demo/testing(旧版)或空值(Conan 2.x),这会导致包上传后渠道混乱,跟预期不符。
正确做法是每次打包都带全限定 reference:
conan create . mylib/1.2.0@team/testing
或者用参数形式(等价):
conan create . -u team -c testing
漏掉 -c 是常见错误,尤其在 CI 脚本中硬编码了 @team 却忘了补 /stable,结果把正式包发到了 testing 频道下,下游项目一拉就出问题。
远程仓库权限和 channel 过滤要配合使用
仅靠命名约定还不够——你得让团队成员“没法误操作”。实际落地时,建议:
- 为
stable频道配置只读权限(或仅限特定人员上传) - 在 CI 中用
conan upload时加--remote=my-private-remote,并检查conan remote list输出确保目标 remote 已启用且 verify_ssl 正确 - 禁止直接上传
@*/stable包到公共 remote(如conancenter),可用 pre-upload hook 或 CI 脚本做正则校验:if [[ "$ref" =~ @.+/stable$ ]]; then exit 1; fi
Conan 本身不拦截非法 channel,所有约束都要靠流程+脚本兜底。
test_package 目录里的 conanfile.py 不能写死 channel
很多人在 test_package/conanfile.py 的 requires 里写死 "mylib/1.2.0@team/testing",导致测试通过后,忘记改 reference 就直接 conan create . mylib/1.2.0@team/stable,结果测试的是 testing 包,发布的却是 stable 包——但 stable 包根本没跑过 test_package。
更稳妥的做法是:让 test_package/conanfile.py 的 requires 从环境变量或命令行参数注入,例如:
requires = "%s/%s@%s/%s" % (os.getenv("PKG_NAME", "mylib"),
os.getenv("PKG_VERSION", "1.2.0"),
os.getenv("PKG_USER", "team"),
os.getenv("PKG_CHANNEL", "testing"))
然后 CI 中统一控制:
PKG_CHANNEL=stable conan create . mylib/1.2.0@team/stable
这样能保证测试和发布用的是同一个 reference,channel 不会脱节。
真正容易被忽略的点是:channel 不是元数据,它不参与依赖解析逻辑,也不影响构建参数;它纯粹是人工约定 + 流程管控的组合技。一旦某次上传跳过了 channel 校验,整个区分体系就失效了。

















