指南
转移到 conda-forge
本文档旨在概述将 conda-recipes 和 anaconda-recipes 转移到 conda-forge 的一些指南。这些并非硬性规定,而是可以进行合理的解释和审阅者的判断。
预计几乎所有来自这些仓库的配方都将被提议添加到此处,尽管可能会决定少数配方实际上不属于此处或不应再受支持。
从任一位置添加软件包时,请检查提交历史记录,查看过去谁对配方进行了更改。任何修改过配方的人都应被提及,以便他们可以被添加到此处。还应就配方在添加之前是否需要进行任何调整咨询他们。此外,还应询问他们是否愿意被添加为维护者。只有当他们同意担任维护者角色时,才应将其添加到维护者列表中。
在移植配方时,在任何情况下都应将自己添加为维护者。这些仓库的一些贡献者可能非常多产,但可能没有那么积极参与。如果他们指定只希望就某些配方或完全不希望被联系,请尊重他们的意愿并将他们也添加进去。记下他们希望收到通知的配方(如果有)。如果他们不再对任何 conda 配方感兴趣,也请在此处注明。在联系任何人之前,请查阅此 issue 中的列表,查看该贡献者是否有任何限制。
移植时,请确保配方遵循 linting 规范。章节顺序应为 package
、source
、build
、requirements
、test
、about
、extra/recipe-maintainers
。建议添加一个 build
章节,并将 number
显式设置为 0
,即使其余部分不需要。如果 Windows 没有构建,请确保在 build
章节中添加 skip: true # [win]
。about
章节必须包含 home
URL(验证 URL 是否仍然正确)、license
(验证是否存在正确的许可证)以及一句(或几个词)summary
。在指定版本时,强烈建议使用 jinja 模板在顶部设置版本(例如 {% set version = "0.10.1" %}
),然后将所有版本使用替换为 {{ version }}
。应优先考虑压缩源包,而不是版本控制检出。确保所有压缩源包的链接都允许轻松更改版本(不接受使用 latest)。此外,所有压缩源包都应包含校验和,以便验证下载。
所有软件包都必须添加测试。这些测试可以包括但不限于:检查库是否已安装、python 导入、用于编译或运行基本测试的简单代码片段、命令行用法(检查帮助或版本)。建议让编译后的代码运行所有测试(例如 make check
),以确保它已正确构建。这通常应该在构建中完成。
尽管不建议,但可以将多个配方包含在 staged-recipes 上的单个拉取请求中。conda-build-all
用于确定构建顺序和必要的构建矩阵(例如,针对哪些 python 版本进行构建)。从实际角度来看,持续集成资源有限,审阅者在单个拉取请求中能够/愿意审阅的内容也有限。包含大量配方的大型拉取请求会使审阅更加困难。如果配方通过了这两个约束并被合并,则不同 feedstock 之间的竞争条件可能需要您和/或核心维护人员重新启动它们,以适当的顺序构建所有内容。这并不是说不能在单个拉取请求中添加多个配方。当然可以这样做,并且它可以工作,但建议首先打开一个包含一个配方的 PR,并 ping @conda-forge/core 询问是否同意添加一两个额外的配方。
预期用途
维护者的时间和 CI 资源是 conda-forge 的基石。它们和价值一样稀缺。conda-forge 有足够的能力支持发布软件包,但没有能力开发它们。
将软件包发布到 conda-forge 表明它适合未参与开发的用户。但是,发布并非总是无错误的。在调试发布过程本身的问题时,多次提交是可以接受的。
幸运的是,有一些优化软件包开发的选择。
- conda-smithy 是 conda-forge 本身用于管理 feedstock 的工具。conda-smithy 可用于创建与 conda-forge 分离的内部开发 feedstock。
- ci-helpers 是一组使用环境变量驱动各种 CI 服务的脚本。
重命名软件包
有时,软件包名称错误。要更正软件包的名称,请提交一个 PR 到 staged-recipes,其中包含正确的名称。在审查过程中,请务必注意软件包已重命名,并联系 conda-forge/core 的成员以删除旧的 feedstock(以及可能需要的软件包)。
有时,需要更新 feedstocks 中的 .gitmodules 文件以删除旧的 feedstock。目前尚不完全清楚具体情况。请参阅 conda-forge.github.io#1070。
如果现有的 feedstock 已经创建了同名的软件包,那么您可能需要将新的 feedstock 添加到 feedstock-outputs 映射中。
修复损坏的软件包
有时,您需要从 Anaconda.org 上的 conda-forge
频道中删除软件包。原因可能有很多,但立即想到的原因是
- 不正确的固定或元数据
- 软件包被重命名
- 损坏的软件包内容
由于以下原因,我们倾向于不删除软件包
- 未受影响的用户无法获取损坏的软件包。
- 无法撤销(如果我们错误地删除了它怎么办)。
- 失去可重现性(无法创建旧环境)。
- 对社区不太友好(没有机会审查决定)。
- 阻止任何人检查损坏的软件包。
相反,如果可能,我们倾向于采取以下措施之一
- 如果唯一问题在于软件包元数据,我们可以使用 repo data patches feedstock 直接对其进行修补。要更改软件包的 repo 数据,请在 feedstock 上创建一个 PR。
- 如果软件包内容本身已损坏,我们会向软件包添加一个额外的标签
broken
。带有此额外标签的软件包将从main
标签上的 repo 数据中删除。因此,求解器不会考虑它们,但它们的二进制文件仍然可以在 Anaconda.org 上找到。要将broken
标签添加到您的软件包,请参阅 Removing broken packages。
向软件包添加 broken
标签比修补 repo 数据更具破坏性,因此我们更喜欢 repo data patches 而不是将事物标记为 broken
。
成为维护者
conda-forge 是一个社区项目,因此可能会发生 feedstock 暂时被弃用的情况。您可以通过将您的 github-id 添加到配方的 meta.yaml
中的 recipe-maintainers
部分,加入 feedstock 的维护者团队。有关详细说明,请参阅 Updating the maintainer list。
语言版本
conda-forge 包含来自多种语言的软件包,包括 Python 和 R 等等。这些特定于语言的软件包子生态系统中的每一个都需要与语言本身保持同步,这使得为旧版本的语言保留多长时间制定统一的政策具有挑战性。当出现问题时,每个小组都应该能够定义自己关于旧版本的语言保留多长时间的政策。
Python
对于 Python 语言,conda-forge 旨在保持软件包构建处于活动状态,并可用于当前版本和至少前两个次要版本。每当 Python 4.0 发布时,我们需要弄清楚此策略是否应更改为同时支持多个版本的 3.x 和 4.x。幸运的是,我们现在可以暂时搁置这个问题。何时决定放弃旧版本语言的问题仍然存在。我们在此处可以提供的指导是双重的
- 我们将与社区保持一致。当我们的核心库停止支持旧版本时,conda-forge 也会如此。我们在决定放弃旧版本时考虑的核心库(非详尽列表)包括
- matplotlib
- numpy
- scipy
- pypy
- 核心团队可以决定暂时保留旧版本,直到满足某些特定标准。例如,在 pypy 发布 pypy3.7 之前,我们暂缓关闭 py36。
- 如果社区中有很多人依赖旧版本,核心团队可以决定保留旧版本。例如,即使在 numpy、scipy 放弃支持之后,我们仍然暂缓关闭 py27,因为社区中很多人有兴趣保持支持直到该版本的生命周期结束。
审查配方
要向 conda-forge 添加新软件包,用户可以向 staged-recipes
提交 PR(有关更多详细信息,请参阅 Contributing packages),它将在其中接受一系列自动化检查和代码审查。任何 conda-forge 成员都可以执行代码审查,但最终合并只能由 staged-recipes
或 core
团队完成。以下部分提出了关于如何执行成功的代码审查的指南。我们将“必需”和“推荐”区分如下
- 必需:这些指南非常重要,是 PR 接受的必要条件。例外情况很少见,通常需要
core
批准。 - 推荐:这些被认为是“锦上添花”的功能。理想情况下,所有配方都应遵守这些功能,但只要提供合理的理由,就可以容忍例外情况。
通用性
必需
- 审查中的所有互动都应遵守我们的行为准则。
conda-forge-linter
检查成功通过。有时,linter 还会建议被认为是可选的修改(提示);即使是推荐的,这些也不是接受提交的必要条件。- CI 检查在所需平台上成功通过。例外情况
noarch: python
在 Linux 以外的平台(例如,缺少依赖项)上可能会失败。对于非 noarch 软件包,应通过skip: true # [<平台选择器>]
跳过失败的平台- CI 超时或存储空间不足,因为它尝试在同一作业中构建所有 Python 版本。只要一个版本通过,就可以了,因为它们将在生成的 feedstock 中单独运行。
- 提交满足拉取请求模板清单。
- 许可证已正确识别并允许重新分发。
- 源代码不应包含 vendored 代码。如果包含
- 单独打包 vendored 项目,并在
requirements
部分指定所需的依赖项。如果 vendored 代码在运行时需要,则首选此方法。 - 允许 vendored 代码,但确保许可证文件包含在
about.license
字段中。如果它只是构建时依赖项(例如,仅标头库),通常可以接受
- 单独打包 vendored 项目,并在
推荐
- 应从提供稳定 tarball 的 URL 获取源代码(SHA 随时间不变)。Git 或其他 SVC 存储库应仅作为最后的手段使用。
- conda-forge pinnings 中包含的 Host requirements 应该是仅名称的;即,它们不指定单独的版本。
- 运行时 requirements 不应在没有正当理由的情况下被过度严格地固定。由于有了 repodata patches,我们可以对下限或上限保持乐观态度,而不是单版本固定:
>=1.4.2,<1.5
比==1.4.2
更好。 - 软件包应将其文件放置在标准位置下(例如,可执行文件位于
$PREFIX/bin
下),除非提供了正当理由。
Python 特定细节
必需
noarch: python
软件包满足被视为此类软件包的必需标准。
推荐
- 软件包不会意外包含
tests
(也包括test
、_tests
或类似名称)顶级软件包。文件列表通常由pip install
在adding license file
消息之后打印。如果发生这种情况,上游应相应地修改其setuptools.find_packages()
用法。或者,可以应用补丁。请参阅example。 test.imports
检查的模块不为空(这可能会发生在顶级软件包中的占位符__init__.py
文件中)。pip list
和conda build
日志报告的版本匹配。pip check
通过。有关更多详细信息,请参阅 pip check。- 如果一个项目可以被认为是
noarch
(请参阅 criteria),则应将其打包为 noarch。
编译对象
必需
- 源代码不包含编译后的文件。原则上,所有编译后的对象都需要在 CI 中从源代码生成。此规则的例外情况(例如,二进制重新打包)需要明确批准。
推荐
- SONAME 遵循上游给出的命名建议。
- 如果 ABI 兼容性对于软件包很重要,则应相应地设置
run_exports
。有关更多信息,请参阅 Pinned dependencies 和 conda-build 文档。