Apache Arrow 开发者工具实战:PR 自动合并脚本与 Docker 集成测试完全指南
【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址: https://gitcode.com/gh_mirrors/arrow13/arrow
本篇指南围绕 Apache Arrow 仓库 dev/README.md 所定义的开发者工具链展开,系统讲解两大核心工作流:如何使用dev/merge_arrow_pr.sh以命令行方式安全、规范地合并 Pull Request,以及如何使用 Docker Compose 运行 HDFS、Apache Spark 等跨组件集成测试。读完本文,你将掌握 Arrow Committer 的完整合并流程、令牌配置方法、交互式合并的输出解析,以及基于 conda 镜像栈的集成测试命令与底层执行逻辑,可直接对照本仓库源码逐行验证。
一、dev 目录与开发者脚本概览
dev/目录承载着 Apache Arrow 项目面向开发者(尤其是 Committer 与 Release Manager)的一系列工具脚本,覆盖打包、测试与代码提交(commit)三大场景。其中与日常协作最密切相关的是:
- dev/merge_arrow_pr.sh:合并 PR 的入口包装脚本,自动创建 Python 虚拟环境并调用主脚本;
- dev/merge_arrow_pr.py:合并 PR 的核心实现,负责调用 GitHub REST API 完成 squash 合并、更新关联 issue 与 milestone;
- dev/merge.conf.sample:令牌配置文件模板;
- dev/requirements_merge_arrow_pr.txt:合并脚本的 Python 依赖清单(
jira、requests); - dev/test_merge_arrow_pr.py:针对合并脚本逻辑的单元测试。
此外,dev/下还包含 dev/archery(CI/发布辅助工具集)与 dev/release(发版脚本)等目录,本文聚焦 README 明确阐述的合并与集成测试两条主线。
二、合并 Pull Request 的前置条件
合并 PR 需要满足两个硬性条件:
- 必须是项目 Committer:合并操作要求使用者拥有项目的 committer 权限;
- 必须在 GitBox 完成账号关联:需要将 GitHub 账号与 ASF 账号在 GitBox 设置页完成绑定,绑定后才能以 GitHub 作为主远端进行 push。
需要特别留意的是:GitBox 设置完成与 GitHub 账号正式获得 committer 身份之间存在数小时的延迟,刚完成绑定后立即操作可能失败,这是文档明确标注的已知注意事项。
项目同时强调:不要通过 GitHub Web 界面直接合并 PR,所有合并都应走统一的命令行脚本,以保证提交信息格式(如GH-#xxx前缀、作者信息、Signed-off-by等)的规范化。
三、启动合并脚本:一条命令完成环境准备
在仓库根目录下直接运行:
dev/merge_arrow_pr.sh该包装脚本会自动完成两件事(见 dev/merge_arrow_pr.sh):
- 根据当前
python3版本,在dev/.venv[PY_VERSION](如dev/.venv3.8)下创建 Python 虚拟环境; - 使用该虚拟环境中的
pip静默安装 dev/requirements_merge_arrow_pr.txt 中的依赖(jira、requests),然后调用 dev/merge_arrow_pr.py。
脚本实现细节值得关注:它通过git rev-parse --show-toplevel定位仓库根目录(而非假定当前目录),因此可在仓库任意子目录下安全调用;set -e保证任何一步失败立即中止;若虚拟环境损坏(python3不可执行),会明确提示并退出。若安装失败,脚本会提示删除dev/.venv[PY_VERSION]目录后重试。
Windows 注意事项:项目目前未提供 Windows 包装脚本,Windows 用户需自行安装 Python 依赖后直接运行:
python dev/merge_arrow_pr.py四、令牌配置:环境变量与配置文件两种方式
合并脚本需要通过 REST API 访问 GitHub(读取 PR、执行合并、更新 issue),并通过 JIRA 客户端访问 ASF JIRA(更新 ARROW 相关 issue)。令牌配置支持两种方式,且配置文件优先级高于环境变量(见 dev/merge_arrow_pr.py 与 dev/merge_arrow_pr.py)。
4.1 环境变量方式
| 环境变量 | 用途 | 备注 |
|---|---|---|
ARROW_GITHUB_API_TOKEN | GitHub API 令牌 | 必须为 Personal Access Token,且需勾选workflowscope |
APACHE_JIRA_TOKEN | ASF JIRA 令牌 | 若不设置,脚本会以交互方式询问 |
export ARROW_GITHUB_API_TOKEN=ghp_xxx export APACHE_JIRA_TOKEN=xxx dev/merge_arrow_pr.sh说明:项目合并仅需要 GitHub 令牌即可完成主流程;Parquet 相关 PR 则可能同时使用 GitHub 或 JIRA 令牌(PARQUET-前缀 issue 走 JIRA 更新)。
4.2 配置文件方式
从仓库根目录复制模板并修改:
cp dev/merge.conf.sample ~/.config/arrow/merge.conf配置文件为 INI 格式,模板内容如下(见 dev/merge.conf.sample):
[jira] # issues.apache.org Jira personal access token token=abc123 [github] # GitHub's personal access token. "workflow" scope is needed. api_token=ghp_ABC脚本通过configparser读取~/.config/arrow/merge.conf(见 dev/merge_arrow_pr.py)。若文件与环境变量都未提供令牌,脚本会回退到交互式输入提示,避免流程中断。
4.3 其他可选环境变量
从源码头注释与实现(dev/merge_arrow_pr.py)可以看到以下高级配置:
ARROW_GITHUB_ORG:GitHub 组织名,默认apache(兼容旧变量名PR_REMOTE_NAME);ARROW_PROJECT_NAME:项目名,默认arrow;DEBUG:调试模式开关,设为1时只打印将执行的合并标题、提交信息等内容,而不会真正 push 到 Apache 或修改 issue 状态,非常适合演练验证。
五、合并流程的交互式输出详解
启动脚本并输入 PR 编号(也可直接用命令行参数传入,如dev/merge_arrow_pr.py 34,见 dev/merge_arrow_pr.py)后,脚本首先打印 PR 概览:
Which pull request would you like to merge? (e.g. 34):输入编号并回车后,脚本拉取 PR 与关联 issue 信息:
=== Pull Request #X === title GH-#Y: [Component] Title source repo/branch target master url https://api.github.com/apache/arrow/pulls/X === GITHUB #Y === Summary [Component] Title Assignee Name Components Python Status open URL https://github.com/apache/arrow/issues/Y Proceed with merging pull request #X? (y/n): y确认无误后输入y并回车,脚本进入合并与提交信息组装阶段:
Author 1: Name Pull request #X merged! Merge hash: #hash Would you like to update the associated issue? (y/n): y Enter fix version [11.0.0]:直接回车即可使用默认的 fix version(脚本会根据未发布的 milestone 自动推荐),随后脚本通过 JIRA/GitHub API 关闭关联 issue:
Successfully resolved #Y! === GITHUB #Y === Summary [Component] Title Assignee Name Components Python Status closed URL https://github.com/apache/arrow/issues/Y六、合并脚本的源码级原理
6.1 PR 标题解析规则
脚本通过 PR 标题判断其关联 issue(dev/merge_arrow_pr.py):
- 标题以
GH-#数字开头:关联 GitHub issue; - 标题以
MINOR:开头:视为 minor 变更,无关联 issue,合并后不更新任何 issue; - 标题以
PARQUET-数字开头:关联 PARQUET JIRA issue; - 标题以
ARROW-数字开头:脚本会直接报错,提示将旧 JIRA 编号迁移为 GitHub issue 编号(并尝试从 JIRA 迁移评论中推断对应 GH 编号)。
此外,脚本还会在提交前检查 PR 的 merged / mergeable 状态(见 dev/merge_arrow_pr.py):已合并的 PR 直接退出;不可合并的 PR 以非零状态退出。
6.2 合并方式与提交信息组装
合并使用squash(压缩合并)方式(dev/merge_arrow_pr.py),提交标题为原PR标题 (#编号)。提交信息体由以下部分组装:
- 清理后的 PR 描述(剔除 HTML 注释,并在
@用户名后插入空格避免触发 GitHub 提醒); Authored-by:或Lead-authored-by:(多作者时)字段;- 所有
Co-authored-by:信息(从各 commit 消息中提取); - 使用
git config读取的 committer 的Signed-off-by: 姓名 <邮箱>。
多作者场景下,脚本会提示确认主作者(Enter primary author in the format of "name <email>"),格式校验不通过会反复提示重试。
6.3 合并完成后的清理
合并成功后,脚本会调用 GitHub API 删除 PR 上以awaiting开头的状态标签(如awaiting-change-review等),保持 PR 工作流标签整洁(dev/merge_arrow_pr.py)。随后询问是否更新关联 issue,确认后根据推荐的 fix version 将其关闭,并在注释中附上合并该 PR 的链接。
七、Docker 集成测试总览
dev/README.md的第二个主题是集成测试:验证 Arrow 各语言实现与外部系统(HDFS、Spark 等)的协同工作。仓库根目录的 docker-compose.yml 定义了整套镜像服务,其层级关系(见 docker-compose.yml)为:
conda └─ conda-cpp └─ conda-python ├─ conda-python-hdfs ├─ conda-python-spark └─ ...也就是说,conda-cpp以conda为基础,conda-python又基于conda-cpp,HDFS 与 Spark 集成测试镜像再叠加在conda-python之上。各层对应镜像定义位于 ci/docker 目录(如 ci/docker/conda.dockerfile、ci/docker/conda-cpp.dockerfile、ci/docker/conda-python.dockerfile),默认构建参数由根目录 .env 提供(如PYTHON=3.8、HDFS=3.2.1、SPARK=master、JDK=8、MAVEN=3.8.7)。
原文档记载,集成测试存在一个被多个测试复用的基础镜像,构建命令为:
docker build -t arrow_integration_xenial_base -f docker_common/Dockerfile.xenial.base .需要说明的是,当前仓库已将镜像构建定义统一收敛到根目录 docker-compose.yml 与 ci/docker 之下,历史命令中的docker_common目录在本仓库中已不存在;实际操作请以下面各节的 docker-compose 命令为准。
八、HDFS C++ / Python 集成测试
HDFS 集成测试用于验证 Arrow C++ 与 Python 的 HDFS 文件系统支持。按依赖顺序依次构建并运行:
docker-compose build conda-cpp docker-compose build conda-python docker-compose build conda-python-hdfs docker-compose run --rm conda-python-hdfsconda-python-hdfs服务的关键配置(见 docker-compose.yml):
- 构建参数:
hdfs: ${HDFS}(默认 3.2.1)、jdk: ${JDK}、maven: ${MAVEN}; - 环境变量:
ARROW_HDFS=ON,测试目标ARROW_HDFS_TEST_HOST=impala、端口8020、用户hdfs; - 通过
links关联impala服务作为 HDFS 测试集群; - 容器内依次执行 ci/scripts/cpp_build.sh、ci/scripts/python_build.sh,最后运行 ci/scripts/integration_hdfs.sh。
从 ci/scripts/integration_hdfs.sh 可以看到测试的真实内容:它会以use_hadoop_home(走 Hadoop 的libhdfs)与use_libhdfs_dir(走ARROW_LIBHDFS_DIR指定路径)两种方式分别执行 C++ 测试程序arrow-io-hdfs-test、arrow-hdfs-test,再以PYARROW_TEST_HDFS=ON运行 Python 侧的pyarrow.tests.test_fs文件系统测试。
九、Apache Spark 集成测试
Spark 集成测试用于验证当前快照的 Arrow Java 与 Python(PyArrow)实现能与 Spark 协同工作。流程为:在 Conda 环境中构建 Arrow C++ 与 Python → 将 Arrow Java 安装到本地 Maven 仓库 → 使用新 Arrow 构件构建 Spark → 运行 Spark 中与 Arrow 相关的 Java 与 Python 单元测试,任何错误都会以非零状态退出。
执行命令(见 dev/README.md):
docker-compose build conda-cpp docker-compose build conda-python docker-compose build conda-python-spark docker-compose run --rm conda-python-spark9.1 复用本地 Maven 缓存
如果本机已经构建过 Spark,可以将本地 Maven 仓库映射进容器,避免重复下载全部依赖:
docker-compose run --rm -v $HOME/.m2:/root/.m2 conda-python-spark重要提醒:容器内文件以 root 身份写入,映射本地~/.m2后可能因文件属主变为 root 而在宿主机上产生 Maven 权限问题,使用前需自行权衡。
9.2 测试的源码级执行细节
conda-python-spark服务(docker-compose.yml)在容器内依次执行 C++ 构建、Python 构建、Java 构建,最后运行 ci/scripts/integration_spark.sh。从该脚本可以看出测试的关键逻辑:
- 通过
SPARK_VERSION环境变量选择 Spark 分支(默认master); - 对 Spark 2.x 系列设置
ARROW_PRE_0_15_IPC_FORMAT=1以兼容旧 IPC 格式,并设置PYARROW_IGNORE_TIMEZONE=1; - 读取 Arrow Java 的实际版本号,用 Maven 的
versions:set-property将 Spark 的arrow.version属性更新为该版本,再打包构建 Spark; - 运行 Spark 侧 Java 测试(如
org.apache.spark.sql.execution.arrow相关套件、ColumnarBatchSuite、ArrowColumnVectorSuite); - 按 Spark 版本选择对应路径,运行 PySpark 侧测试(
pyspark.sql.tests.test_arrow及 pandas UDF 系列测试); - 支持
test_pyarrow_only=true参数:仅用最新 PyArrow 测试 Spark,跳过重新构建 Arrow Java。
注意事项:如果 Arrow Java API 发生破坏性变更,可能需要使用打过补丁的 Spark 版本才能成功构建(README 中明确提示)。此外,Spark 构建耗时较长,需保证容器拥有充足的内存与磁盘资源。
十、参考文件速查
- 合并流程: dev/merge_arrow_pr.sh、dev/merge_arrow_pr.py、dev/merge.conf.sample、dev/requirements_merge_arrow_pr.txt、dev/test_merge_arrow_pr.py
- 集成测试编排: docker-compose.yml(
conda-cpp/conda-python/conda-python-hdfs/conda-python-spark服务)、.env(默认版本参数) - 集成测试脚本: ci/scripts/integration_hdfs.sh、ci/scripts/integration_spark.sh
- 镜像定义: ci/docker 目录下的
conda*.dockerfile
【免费下载链接】arrowApache Arrow is a multi-language toolbox for accelerated data interchange and in-memory processing项目地址: https://gitcode.com/gh_mirrors/arrow13/arrow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考