软件包的生命周期
conda-forge 实施了一种特定的工作流程来构建、发布和维护 conda 软件包。然而,对于任何 conda 打包解决方案,其核心概念是相同的。
关于 conda 打包的一般概念
conda
软件包基于 conda
配方构建,配方包含元数据文件(如 meta.yaml
或 recipe.yaml
),以及可选的支持脚本和数据。构建工具(通常是 conda-build
或 rattler-build
)接受配方并生成一个或多个软件包(也称为输出和/或工件,具体取决于上下文)。
虽然您可以自行分发工件,但 conda 软件包通常会上传到托管在 Anaconda.org 等服务器上的 conda
频道。此频道服务器处理所有上传的软件包,并将软件包中包含的元数据聚合到每个平台或 subdir 的单个 repodata.json
文件中。例如,这是 Linux x64 系统的 conda-forge
repodata 的一个子集:current_repodata.json
。
这些是当用户键入 conda install ...
或类似命令时,conda
客户端获取的元数据文件。求解器将处理所有元数据,并将为用户提供最合适的软件包选择,然后下载、提取并链接到目标 conda 环境中。
发布后的特殊性
对于大多数软件包,以上段落足以描述其生命周期。然而,conda 生态系统中遵循的 repodata 优先方法在发布后阶段允许一些独特的功能。
对于像 conda-forge 这样的大容量频道,Anaconda.org 通过 CDN 网络交付工件以实现更快的访问。CDN 网络会定期与频道同步。因此,软件包在发布后大约需要 15 分钟才能可供安装。
这种 repodata 优先方法为发布后处理 repodata 文件提供了独特的机会。这样,我们可以在不重建软件包的情况下修复元数据问题。请注意,这些更改不会传播回软件包中包含的元数据。
Anaconda.org 还提供了频道标签的概念,实际上,频道标签的行为类似于子频道。默认标签是 main
。当添加新标签时,软件包在子频道 <channel>/label/<label>
中也可见。例如,上传到 conda-forge 并标记为 test
和 main
的软件包将在 conda-forge
频道中可用,同时在 conda-forge/label/test
子频道中也可用。
conda-forge 上的生命周期
任何人都可以运行 conda-build
在他们的计算机上,并手动将他们的软件包上传到 Anaconda.org。然而,这种方法存在一些问题
- 它不利于协作。
- 该过程缺乏透明度。
- 可重现性取决于系统。
- 不能保证软件包之间的兼容性。
- 它不能很好地扩展到少数软件包之外。
在 conda-forge 上,大多数软件包是使用公共 CI 服务构建的,并由数千名志愿者维护,这需要以不同的方式解决问题,以保证对权限的细粒度控制、独立的项目管理和自动化的批量更新。
主要思想是每个 conda 配方都由一个单独的 GitHub 存储库处理。这些存储库在 conda-forge 中被称为 feedstock,托管用户贡献的 conda 配方以及几个自动生成的必需脚本、配置文件和 CI 管道,用于构建和导出 conda 工件。在这种设置下,当需要发布全局更改或修复时,conda-forge 机器人可以遍历 conda-forge 存储库以根据需要重新生成和更新 feedstock。
要获得 conda-forge feedstock,贡献者必须首先将其配方提交到 staged-recipes
存储库以供审核。一旦审核通过,PR 将合并到 main
分支,从而触发 feedstock 的创建。
在接受 conda-forge 组织的邀请后,提交贡献者将被授予对该存储库的提交权限。届时,feedstock 创建机制将已在所需的 CI 服务中注册新存储库,并使用提交的配方以及支持脚本、配置文件和 CI 管道填充其内容。
这些管道将处理初始提交,以生成 conda 工件并将其上传到 cf-staging
频道。随后对 main
分支(例如,合并的 PR)或其他已启用分支的任何推送都将经历相同的过程。
对于现有的 feedstock,conda-forge 机器人通常会为新项目发布或维护任务发送自动化的 PR。您可以在自动化与机器人中找到有关它的更多详细信息。
验证服务器将检测 cf-staging
上的新上传,并将对这些工件执行一些检查。如果成功,这些工件将被复制到实际的 conda-forge
频道。
此时,频道服务器将处理新软件包的内容以检索其元数据并更新 repodata 文件。在下一个 CDN 同步周期中,工件将分发到交付网络以实现更快的访问。验证和 CDN 同步通常在 CI 在 main
分支上通过后大约需要 15 分钟。从那时起,用户可以从 CLI 安装新软件包。
发布后的特殊性
在理想的世界中,这将是生命周期的结束。但是,在某些情况下,某些软件包会经历一些发布后阶段。
如果发现软件包元数据错误或过时,则可以在不重建软件包的情况下对其进行修改。频道服务器可以直接将补丁应用于 repodata 文件,通过每周处理的 conda-forge-repodata-patches
中发布的说明。
有时,已发布的软件包存在无法通过 repodata 补丁修复的问题(例如,库构建错误并发生段错误)。在这些情况下,可以通过将软件包标记为 broken
来使其退役。这通过 admin-requests
存储库完成。作为 CDN 驱动的元数据修补的一部分,标记为 broken
的软件包不包含在最终的 repodata 索引中。但是,它们仍然可以通过直接 URL 访问获得。这允许组织从正常的、求解器驱动的安装中退役软件包,而不会影响锁定文件提供的可重现性。
最后,一个项目可能已达到不再需要或预期进一步更新的状态(例如,它已被新项目取代)。如果维护者愿意,可以将这些 feedstock 存档并标记为只读,这也是通过 admin-requests
完成的。
阶段摘要
这些阶段是 conda-forge 文档中的关键概念。在您查看文档的其余部分时,请随时参考此列表。
- 初步提交到
staged-recipes
- Feedstock 更改
- A. 存储库初始化
- B. 自动维护更新
- C. 用户提交的 PR
- 软件包构建
- 软件包验证
- 软件包发布
- 发布后
- A. Repodata 补丁
- B. 将软件包标记为 broken
- C. 存档 feedstock
如果您想了解有关这些阶段背后的基础设施细节的更多信息,请考虑阅读我们的基础设施指南。