
Apache Arrow Crossbow 打包与集成测试系统架构原理与 arc 实战指南【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrowApache Arrow 的 Crossbow 是一套基于 Git 分支作为任务队列的持续集成调度系统它把打包conda 包、Python Wheel、Linux 发行版包、Homebrew Formula 等和集成测试Pandas、Dask、Spark、HDFS、Turbodbc 等自动化为可复现、可追踪的构建任务。本文以仓库文档 crossbow.rst 为骨架结合dev/tasks与dev/archery下的真实实现完整讲解 Crossbow 的安装、提交、状态查询、产物下载与报告机制并深入剖析其Git 分支即任务队列的调度原理帮助你像 Arrow 维护者一样按需触发任意平台的构建与测试。Crossbow 是什么dev/tasks目录的使命Crossbow 的出发点位于arrow/dev/tasks目录它承载了 Apache Arrow 打包与集成测试的全套自动化。按功能划分它主要覆盖两大类别打包PackagesC 与 Python 的 conda-forge 包覆盖 Linux、macOS、WindowsPython Wheel覆盖 Linuxmanylinux / musllinux、macOS、WindowsC 与 GLib 的 Linux 发行版包面向多个发行版apt、yum 体系Java面向 Gandiva相关构建。集成测试Integration tests各类 Docker 容器测试C、Python、R、Ruby、GLib 等镜像Pandas、Dask、Turbodbc、HDFS、Spark 的兼容性测试。这些任务并不是一次性脚本而是以结构化配置存在任务定义集中在 dev/tasks/tasks.ymlCI 工作流模板分散在dev/tasks下的子目录如 python-wheels、docker-tests、verify-rc、r 等真正的调度逻辑则由archery crossbow子命令实现代码位于 dev/archery/archery/crossbow/。架构总览Executor、Queue 与 SchedulerCrossbow 的架构可以拆成三个角色Executors公网 CI 执行器单个构建任务最终在公共 CI 服务上执行当前仓库所依赖的执行器组合为LinuxGitHub Actions、Travis CI、Azure PipelinesmacOSGitHub Actions、Azure PipelinesWindowsGitHub Actions、Azure Pipelines。从 tasks.yml 的实际任务看绝大多数任务标注为ci: github即默认走 GitHub ActionsTravis、CircleCI、Azure 的配置模板.travis.yml、.circleci/config.yml在 core.py 中仍作为跳过分支的默认骨架保留用于让不参与某次构建的 CI 服务自动跳过对应分支。Queue作为任务队列的 Git 仓库由于 CI 服务按分支推送触发Crossbow 把调度抽象成一个额外的 Git 仓库——队列仓库Queue Repository任何人都可以托管一个队列仓库惯例命名为ghuser/crossbow。在 Crossbow 中一个任务本质上就是队列仓库里的一个 Git 提交它位于某个特定分支上分支内包含触发对应构建所需的配置文件如.travis.yml、azure-pipelines.yml或 GitHub Actions 用的crossbow.yml。CI 服务监听到队列仓库出现新的匹配分支就会拉取并执行其中的构建。Schedulerarchery crossbow调度器调度器负责三件事版本生成、任务渲染、任务提交。版本号基于setuptools_scm从当前 Git 提交推导任务定义与任务组来自tasks.yml渲染通过 Jinja2 模板完成。在 core.py 中可以看到渲染时使用jinja2.Environment加载模板并以StrictUndefined模式执行——这意味着模板中任何未定义的参数都会直接报错从而保证渲染即校验。安装 Crossbow从零到archery crossbow --help以下步骤以 GitHub 为例理论上任意 Git 服务器均可。如果你使用官方的ursacomputing/crossbow队列仓库可直接跳到第 3 步否则需要先完成前两步。1. 创建队列仓库新建一个 GitHub 仓库作为你的任务队列例如crossbow。参考仓库创建流程即可GitHub 的仓库创建向导。2. 为队列仓库启用 Azure Pipelines 集成在 Azure Pipelines 中为新建的队列仓库启用构建集成这样队列仓库上的分支推送事件才能触发 Azure 上的构建。3. 克隆 Crossbow 仓库将官方ursacomputing/crossbow或你刚创建的仓库克隆到 arrow 仓库旁边git clone https://github.com/user/crossbow crossbow默认情况下脚本会在arrow目录旁寻找名为crossbow的克隆该路径也可以通过命令行参数--queue-path覆盖。从 cli.py 可以看到队列路径默认值就是ArrowSources.find().path.parent / crossbow同时支持通过CROSSBOW_QUEUE_PATH环境变量指定。重要提示Crossbow 只支持基于 GitHub Token 的认证。虽然代码内部会把 SSH 协议的远程地址重写为 HTTPS见 core.py 的_git_ssh_to_https但文档仍建议直接使用 HTTPS 仓库地址避免不必要的坑。4. 创建 Personal Access Token在 GitHub 上创建一个 Personal Access Token只需要repo与workflow两个权限其他权限不需要。5. 导出 Token将 Token 导出为环境变量export GH_TOKENtoken或者在使用 CLI 时通过--github-token参数传入。此外 cli.py 也支持CROSSBOW_GITHUB_TOKEN环境变量三个来源的优先级顺序为--github-tokenCROSSBOW_GITHUB_TOKENGH_TOKEN。如果最终未提供 Tokencore.py 的push()会直接抛出RuntimeError提示缺少凭据。6. 安装 Python需要 Python 3.11 及以上版本。文档建议优先使用 Miniconda 管理环境参见 conda 官方安装指南。7. 安装 archery含 Crossbow 子命令pip install -e arrow/dev/archery[crossbow][crossbow]extra 会额外引入pygithub、pygit2等 Crossbow 依赖在 dev/archery/setup.py 中声明。-e表示可编辑安装便于跟随仓库开发迭代。8. 验证安装archery crossbow --help看到命令帮助即说明安装成功。整个crossbow命令组还提供了子命令级帮助如archery crossbow submit --help。核心用法submit 提交构建任务基本流程archery crossbow submit的执行流程与 cli.py 中submit的实现一一对应自动检测当前仓库脚本检测当前 checkout 的 arrow 仓库及其 remote因此天然支持 fork。例如在 kszucs 的 fork 下执行构建的就是 kszucs/arrow 而非上游 apache/arrowgit clone https://github.com/kszucs/arrow git clone https://github.com/kszucs/crossbow cd arrow/dev/tasks archery crossbow submit --help # 查看可用选项 archery crossbow submit conda-win conda-linux conda-osx读取 HEAD 并生成版本号脚本取当前 checkout 分支的 HEAD 提交基于setuptools_scm推导版本号。因此要构建某个特定分支请先 checkout 再提交git checkout ARROW-ticket number archery crossbow submit --dry-run conda-linux conda-osx注意目标分支必须先推送到远程因为脚本以及后续 CI 上的克隆会拉取该分支。渲染构建配置读取tasks.yml中对应的任务定义用参数替换后渲染出 CI 配置如crossbow.yml、.travis.yml等。为每个任务创建分支按任务创建以 job id 为前缀的分支例如 Linux 上构建 conda recipes 会创建crossbowbuild-id-conda-linux。从源码看实际分支命名格式为job.branch-task.ci-task_namecore.py即在任务分支末尾附加 CI 类型与任务名便于 Travis/CircleCI 使用分支名做跳过匹配。推送分支触发构建将修改后的分支推送到 GitHub 触发 CI认证使用上文安装步骤中的 GitHub OAuth Token。常用参数一览以下参数来自submit命令的实现cli.py可配合--help对照参数说明tasks位置参数任务名列表支持多个如conda-win conda-linux--group, -g按tasks.yml中定义的任务组批量提交可多次指定--param, -p附加的任务参数格式keyvalue用于渲染 CI 模板--job-prefix分支名的任意前缀默认build如 nightly 用--job-prefix nightly--config-path, -c任务配置文件 YAML默认dev/tasks/tasks.yml--arrow-version, -v显式指定目标版本--arrow-remote, -r显式指定要克隆的 GitHub remote不本地校验如https://github.com/apache/arrow--arrow-branch, -b显式指定分支名如ARROW-1949--arrow-sha, -t显式指定提交 SHA 或 Tag如f67a515、apache-arrow-0.11.1--fetch/--no-fetch是否从远程 fetch 引用默认 fetch--dry-run/--commit仅渲染展示不提交默认 dry-run 为 False即会提交--no-push/--push是否推送变更--no-push只在本地创建分支和提交任务组机制大大简化了批量调度例如--group conda只会挑选tasks.yml中conda组列出的任务。完整任务组定义见 dev/tasks/tasks.yml 顶部的groups:段其中包括wheel、homebrew、packaging、test、cpp、c-glib、python、r、ruby、vcpkg、integration、example、fuzz、verify-rc系列以及nightly、nightly-tests、nightly-packaging、nightly-release等。示例多种提交方式提交多个指定任务archery crossbow submit debian-stretch conda-linux-gcc-py37-r40 Repository: https://github.com/kszucs/arrowtasks Commit SHA: 810a718836bb3a8cefc053055600bdcc440e6702 Version: 0.9.1.dev48g810a7188.d20180414 Pushed branches: - debian-stretch - conda-linux-gcc-py37-r40仅渲染不提交dry-runarchery crossbow submit --dry-run task_name只跑 conda 打包任务加一个 C 测试任务archery crossbow submit --group conda test-ubuntu-24.04-cpp跑全部 Wheel 构建archery crossbow submit --group wheel此外tasks.yml中还有docker、integration、cpp-python等多个任务组用于运行基于 Docker 的测试矩阵。任务配置结构速览在tasks.yml中每个任务由任务名 → 定义组成其基本结构为tasks: # 任意任务名: # template: 指向 jinja2 模板的路径 # params: 可选的额外参数如镜像名、Python 版本、架构、环境变量 # artifacts: 正则模式列表每个模式需匹配单个 GitHub release 资产 # 版本变量会替换进模式例如 # - pyarrow-{no_rc_version}-py38(h[a-z0-9])_0-linux-64.tar.bz2以真实任务为例tasks.yml 中的 manylinux wheelwheel-manylinux-2-28-cp311-cp311-amd64: ci: github template: python-wheels/github.linux.yml params: arch: amd64 linux_wheel_kind: manylinux linux_wheel_version: 2-28 python_abi_tag: cp311 python_version: 3.11 wheel_platform_tag: manylinux_2_28_x86_64 artifacts: - pyarrow-{no_rc_version}-cp311-cp311-manylinux_2_28_x86_64.whl大量任务通过 Jinja2 的 for 循环批量生成例如 Python 3.11–3.15 的 Wheel 矩阵、Ubuntu/Debian/Fedora 的 C 与 Python 容器测试、Pandas/Dask/Spark/HDFS 集成测试等维护成本被压缩到极低。查询构建状态status 命令submit会返回一个 build id对应队列仓库中的一个分支用它即可查询状态archery crossbow status build id / branch name实现层面cli.pystatus会 fetch 队列仓库、按 job 名取出任务再以ConsoleReport逐任务渲染状态。它支持以下选项--fetch/--no-fetch查询前是否 fetch默认 fetch--task-filter, -fGlob 模式过滤关心的任务可多次指定--validate/--no-validate只要存在任一非成功任务就返回非零退出码便于接入脚本做门禁判断。状态判断依据task.status().combined_state是否为error或failurecli.py。下载构建产物artifacts 命令构建完成后产物会作为资产上传到队列仓库对应的 GitHub release用以下命令下载archery crossbow artifacts build id / branch name对应实现是download_artifactscli.py行为要点默认下载到arrow 仓库/packages/job-name可用-t/--target-dir覆盖支持--dry-run只展示过程不下载下载前按资产大小与本地文件比对已存在且大小一致的会跳过下载失败自动重试最多 5 次每次间隔 60 秒支持--task-filter过滤任务、--validate-patterns/--skip-pattern-validation控制资产名校验。报告机制邮件、聊天与 CSVCrossbow 还内置了一套报告体系把构建结果推送到合适的地方便于夜间构建nightly无人值守时自动通知。邮件报告reportarchery crossbow report job-name \ --send \ --sender-name Arrow CI --sender-email ciexample.com \ --recipient-email devexample.com \ --smtp-user ciexample.com --smtp-password pass \ --smtp-server smtp.gmail.com --smtp-port 465关键选项cli.py--send/--dry-run控制是否真正发送--poll/--no-poll支持在任务未完成时轮询等待--poll-max-minutes默认 180 分钟、--poll-interval-minutes默认 10 分钟邮件主题由NightlyEmailReport生成形如[NIGHTLY] Arrow Build Report for Job branch: N failed, M pendingcli.py。聊天报告report_chatarchery crossbow report_chat job-name \ --send --webhook https://hooks.slack.com/... \ --extra-message-success All green \ --extra-message-failure Please investigate把构建结果以文本形式发送到 Slack / Zulip 等 Webhook 地址-s/-f两个参数分别指定成功、失败时追加的额外消息。CSV 报告report_csvarchery crossbow report_csv job-name --save生成 CSV 格式的逐任务报告便于导入表格工具或做历史分析。进阶主题夜间构建、发布验证与队列仓库维护定时触发夜间构建Crossbow 支持用 CI 的 cron 能力驱动周期性调度。dev/tasks/nightlies.sample.yml 给出了 Travis cron 的样板把该文件以.travis.yml的名字放到 crossbow 仓库的某个分支上配置该分支的每日 cron 任务然后在script段调用if [ $TRAVIS_EVENT_TYPE cron ]; then archery crossbow submit -g conda -g wheel -g linux else archery crossbow submit --dry-run -g conda -g wheel -g linux fi即cron 触发时真实提交打包任务手工触发时仅 dry-run 演练。tasks.yml中也预置了nightly、nightly-tests、nightly-packaging、nightly-release等组配合--job-prefix nightly使用latest_prefix命令archery crossbow latest_prefix nightly可快速取得某个前缀的最新 job。发布候选验证verify_release_candidateCrossbow 深度参与 Apache Arrow 的发布流程。verify_release_candidate命令cli.py会自动创建或查找一个 PR并通过在 PR 上添加github-actions crossbow submit --group verify-rc-xxx --param releaseversion --param rcrc形式的评论来触发验证任务archery crossbow verify_release_candidate \ --version 9.0.0 --rc 0 \ --verify-source --verify-binaries --verify-wheels \ --create-pr --head-branch release-9.0.0-rc0verify-rc-source、verify-rc-binaries、verify-rc-wheels三组任务在 tasks.yml 中展开为覆盖 Linuxconda/almalinux/ubuntu 各发行版、macOSIntel/arm64与 Windows 的验证矩阵使用 verify-rc 目录下的模板执行。队列仓库维护队列仓库长期使用后分支会越积越多Crossbow 提供清理命令archery crossbow delete_old_branches --dry-run --days 90 --maximum 1000它删除超过指定天数默认 90 天的旧分支每次最多删除--maximum默认 1000个且跳过origin/pr/*引用——这是为了避免触发 GitHub 的引用保护限制cli.py。Token 过期提醒GitHub Token 有有效期Crossbow 提供notify_token_expiration命令在 Token 距过期不足指定天数默认 30 天时发送提醒邮件主题形如[CI] Arrow Crossbow Token Expiration in datecli.py。底层机制剖析从提交到分支推送理解 Crossbow 的调度本质关键在于 core.py 中的几个核心类Repo对本地 Git 仓库的高层封装既用于读取 arrow 仓库的版本信息head、branch、remote_url也用于向队列仓库推送任务core.py。它强制 HTTPS如果 origin 是gitgithub.com形式会抛错并要求提供 GitHub TokenCROSSBOW_GITHUB_TOKEN或GH_TOKEN。Queue(Repo)队列仓库专用类负责 job 分支的自动编号build-85这类自增 id或build-41d017af40这类随机 hex id、按名取 job、按模式枚举 job、查询某个前缀的最新 jobcore.py。job 元数据以job.yml形式存在分支提交里Queue.get()读取并反序列化该文件。Target描述构建哪个版本可由当前仓库自动推导也可通过--arrow-version/--arrow-remote/--arrow-branch/--arrow-sha覆盖这正是发布流程需要精确锁定某个 RC 提交时的关键设计。Job/Taskjob 是一次提交的集合一个 build id 对应一个 jobtask 是其中某个具体任务Job.from_config根据tasks.yml与命令行参数展开任务集渲染模板后为每个任务生成独立分支并加入推送列表。一次典型的提交链路为Target.from_repo()确定目标 →Job.from_config()加载并展开任务 →queue.put(job)在本地队列仓库创建各任务分支与提交 →queue.push()用 OAuth Token 推送到远程 → 各 CI 服务按分支名匹配并执行 → 结果回传到队列仓库 →status/artifacts/report*命令消费结果。分支创建时以默认分支main的提交为父提交core.py这样能复用 GitHub Actions 的缓存。小结Crossbow 用一套极简而优雅的思路解决了多语言、多平台、多任务类型下的打包与集成测试调度问题Git 分支即任务队列CI 服务天然按分支触发tasks.yml Jinja2 模板把成百上千的构建矩阵压缩为可维护的声明式配置archery crossbow系列命令则覆盖了从提交、查询、下载到报告、清理、发布验证的完整生命周期。无论你是想复现 Arrow 的某次构建、为 fork 跑自己的打包任务还是在自己的项目里借鉴这种以 Git 分支做 CI 队列的调度模式crossbow.rst 连同 dev/tasks/tasks.yml、dev/archery/archery/crossbow/cli.py 与 core.py 都是最佳的起点。【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考