Apache Arrow 发布候选版本验证流程:从源码签名校验到投票的完整指南
【免费下载链接】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
导读
本文基于 Apache Arrow 官方开发者文档 docs/source/developers/release_verification.rst,系统讲解 Arrow 发布候选(Release Candidate,简称 RC)在 Linux、macOS、Windows 三大平台上的验证方法,包括投票规则、源码与二进制的验证命令、测试开关矩阵、环境配置脚本以及投票的规范写法。读完本文,你将掌握如何独立下载并校验发布候选的签名与校验和、按需运行 C++/Python/GLib/Ruby/集成测试、验证 APT/YUM/Wheels/JAR 等二进制产物,并最终以合规方式在邮件列表中投出 +1 票。
投票规则与验证原则
Apache Arrow 的发布审批遵循 Apache 软件基金会(ASF)的发布批准政策。根据 release_verification.rst 的 Principles 一节,投票通过的硬性条件是:
- 至少需要三张具有约束力的正面投票(binding +1);
- 正面 binding 票数必须多于负面 binding 票数;
- 发布不允许被一票否决(Releases may not be vetoed);
- 只有 PMC 成员的投票才具有约束力(binding),但非约束性投票(non-binding)受到强烈鼓励,被视为项目健康的表现。
在实际投票中,无论投票者是否为 PMC 成员,想要投出有分量的 +1 票,都需要在自己的硬件上完成实质性的验证工作。文档明确要求:投 +1 票的个人必须下载所有带签名的源码包到自己的硬件上,验证全部密码学签名,按原样编译,并在自己的平台上运行测试。这就是verify-release-candidate.sh存在的意义——它把"下载 → 验签 → 编译 → 测试"整条链路自动化。
运行发布候选验证:Linux 与 macOS
验证脚本位于仓库的 dev/release/verify-release-candidate.sh,接受两个位置参数:$VERSION(版本号,如15.0.0)和$RC_NUM(候选轮次,如1)。该脚本同时支持三种调用形态(对应脚本第 41-70 行的参数解析):
| 调用形式 | 含义 |
|---|---|
verify-release-candidate.sh X.Y.Z RC_NUMBER | 验证发布候选(源码 + 二进制) |
verify-release-candidate.sh GIT-REF | 对远程 git 提交执行源码验证任务 |
verify-release-candidate.sh(无参数) | 对当前 Arrow checkout 执行源码验证任务 |
必须执行的源码验证
文档强调,源码验证是投出 +1 票的前提,其标准命令为:
# 创建并自动清理验证用临时目录,执行源码验证 TEST_DEFAULT=0 TEST_SOURCE=1 verify-release-candidate.sh $VERSION $RC_NUMTEST_DEFAULT=0表示关闭默认的全量测试开关,TEST_SOURCE=1显式开启源码验证组。源码验证组内部又细分为 C++、GLib、Ruby、Python 与集成测试等子任务(见脚本第 1004-1018 行的开关定义):
# 仅执行 C++ 测试 TEST_DEFAULT=0 TEST_CPP=1 verify-release-candidate.sh $VERSION $RC_NUM # 同时执行 C++ 与 Python 测试 TEST_DEFAULT=0 TEST_CPP=1 TEST_PYTHON=1 verify-release-candidate.sh $VERSION $RC_NUM # 执行 C++ 与 Java 集成测试 TEST_DEFAULT=0 TEST_INTEGRATION_CPP=1 TEST_INTEGRATION_JAVA=1 verify-release-candidate.sh $VERSION $RC_NUM这些开关的取值逻辑在脚本末尾(verify-release-candidate.sh)统一汇总:TEST_SOURCE、TEST_BINARIES默认继承TEST_DEFAULT;TEST_CPP、TEST_GLIB、TEST_RUBY、TEST_PYTHON、TEST_INTEGRATION默认继承TEST_SOURCE;而TEST_GLIB会被自动加上TEST_RUBY的值(因为 Ruby 绑定依赖 GLib),BUILD_CPP则是 C++、GLib、Python、集成测试任一开启即自动构建 C++ 基础库。因此从源码结构看,各测试组之间存在明确的依赖链:Ruby 测试会连带触发 GLib 与 C++ 的构建测试,集成测试也会联动构建 C++。
二进制的本地补充验证
二进制产物由已通过验证的源码生成,它们已在 CI 上测试过,但也可在本地进一步验证。文档明确说明:验证二进制并非投出正面票的必要条件。二进制验证命令为:
TEST_DEFAULT=0 TEST_BINARIES=1 dev/release/verify-release-candidate.sh $VERSION $RC_NUM二进制验证组同样支持细粒度开关(脚本第 999-1002 行):
TEST_DEFAULT=0 TEST_WHEELS=1 verify-release-candidate.sh $VERSION $RC_NUM # 仅验证 Python Wheels TEST_DEFAULT=0 TEST_APT=1 verify-release-candidate.sh $VERSION $RC_NUM # 仅验证 APT 软件包 TEST_DEFAULT=0 TEST_YUM=1 verify-release-candidate.sh $VERSION $RC_NUM # 仅验证 YUM 软件包 TEST_DEFAULT=0 TEST_JARS=1 verify-release-candidate.sh $VERSION $RC_NUM # 仅验证 JAR 包TEST_APT、TEST_BINARY、TEST_WHEELS、TEST_YUM均默认继承TEST_BINARIES。二进制验证的实际执行逻辑(verify-release-candidate.sh)是:调用download_rc_binaries.py从apache-arrow-$VERSION-rc$RC_NUMBER标签下载全部二进制产物,然后对下载目录执行verify_dir_artifact_signatures逐一校验签名与校验和。
值得注意的是,APK/YUM 验证在本地机器上并非真正安装软件包,而是依赖 GitHub Actions 上verify_rc.yml工作流的运行结果:脚本的check_verification_result_on_github函数(第 191-205 行)会查询apache-arrow-${VERSION}-rc${RC_NUMBER}分支上的工作流结论,只有success才继续。仅在GITHUB_ACTIONS=true环境(即 CI 自身)中,才通过docker run在debian:trixie、ubuntu:jammy、almalinux:9、amazonlinux:2023等一系列发行版镜像内执行 verify-apt.sh 与 verify-yum.sh 做真实安装验证。这解释了为什么文档强调"二进制已在 CI 上测试过"——本地跑TEST_BINARIES更多是复核签名与产物完整性。
签名与校验和的自动化校验
源码验证的第一步是校验密码学签名,脚本通过三个关键函数完成(verify-release-candidate.sh):
import_gpg_keys:从 Apache 官方 KEYS 地址下载并导入所有发布者公钥,导入结果由GPGKEYS_ALREADY_IMPORTED环境变量缓存,避免重复导入;fetch_archive:从https://dist.apache.org/repos/dist/dev/arrow/apache-arrow-${VERSION}-rc${RC_NUMBER}/下载tar.gz源码包及其.asc签名、.sha256、.sha512校验和文件,随后依次执行gpg --verify、shasum -a 256 -c与shasum -a 512 -c(在无shasum的系统上自动退化为sha256sum/sha512sum);verify_dir_artifact_signatures:遍历二进制下载目录中所有.asc签名文件,逐一验证对应产物及其 SHA-256/SHA-512 校验和,校验和文件与产物同目录存放。
Windows 11 上的验证方式
Windows 平台使用批处理脚本 dev/release/verify-release-candidate.bat。文档说明:Windows 上需要先从 SVN dist 系统下载待验证的源码 tarball,然后执行:
dev\release\verify-release-candidate.bat %VERSION% %RC_NUM%从批处理源码看,该脚本默认在C:\tmp\arrow-verify-release下建立隔离的验证环境,并做了以下工作:
- 使用GNU Wget下载候选 tarball 并解压(
wget --no-check-certificate -O %TARBALL_NAME% ...); - 克隆
arrow-testing与parquet-testing数据仓库,并设置ARROW_TEST_DATA、PARQUET_TEST_DATA环境变量; - 通过
conda create基于 ci/conda_env_cpp.txt 与 ci/conda_env_python.txt 创建验证环境(固定 Python 3.11); - 使用Visual Studio 17 2022生成器、x64、Release 配置执行 CMake 构建,开启
ARROW_DATASET、ARROW_FLIGHT、ARROW_PARQUET、ARROW_WITH_LZ4、ARROW_WITH_ZSTD等常用组件,然后运行ctest; - 构建并安装 pyarrow wheel,最后执行
pytest --pyargs pyarrow完成 Python 层验证。
值得留意的是,verify-release-candidate.bat同样支持无参数调用(此时使用当前 checkout 作为源码),以及以 git 版本号调用(此时会 clone 仓库并 checkout 指定 revision)。文档中"Windows 11:To be defined"一条表明该平台的环境配置指引仍在完善中,建议以脚本实际行为为准。
验证环境的系统配置
验证过程需要curl、git、编译器、Ruby 等工具,文档为 Ubuntu 与 macOS ARM 分别给出了环境准备方案。
Ubuntu:一键依赖安装
在 Arrow 克隆目录下执行工具脚本 dev/release/setup-ubuntu.sh:
# 在 arrow clone 目录下执行 sudo dev/release/setup-ubuntu.sh该脚本面向干净的 Ubuntu 系统,安装源码验证所需的全部软件包,包括:build-essential、clang、cmake、ninja-build、curl、git、gnupg、wget、libglib2.0-dev、libgirepository1.0-dev、ruby-dev、bundler、pkg-config、llvm-dev、libssl-dev、libsqlite3-dev、libcurl4-openssl-dev、nlohmann-json3-dev、tzdata等。从脚本逻辑看:
- Python 侧默认安装
python3-dev、python3-pip、python3-venv(可通过INSTALL_PYTHON=0关闭,因为 Ubuntu 22.04 的验证镜像会单独提供受支持的 Python); - 当系统版本高于 22.04 时额外安装
tzdata-legacy,因为部分测试依赖US/Pacific这类旧式时区别名; - 未包含 Java/Maven 等组件,做 Java 集成测试时需自行补充。
macOS ARM:Homebrew 工具链
文档给出的 macOS ARM 环境配置命令为:
# 在 arrow clone 目录下执行 brew install gpg brew bundle --file=cpp/Brewfile brew bundle --file=c_glib/Brewfile brew uninstall node # 安装后可能需要把 node、ruby、java 和 maven 加入 PATH,遵循 brew 的提示 brew install node@20 brew install ruby brew install openjdk brew install maven对应的依赖清单可参考仓库中的 cpp/Brewfile 与 c_glib/Brewfile。先卸载系统 node 再安装node@20,是为了让验证脚本拿到确定性的 Node.js 版本,避免 PATH 冲突。
投票的规范写法
完成验证后,需要在dev@arrow.apache.org的投票邮件线程中回复并附上结果。文档给出了成功验证后的投票模板:
+1 I've verified successfully the sources and binaries with: TEST_DEFAULT=0 TEST_SOURCE=1 dev/release/verify-release-candidate.sh 15.0.0 1 with: * Python 3.10.12 * gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0 * NVIDIA CUDA Build cuda_11.5.r11.5/compiler.30672275_0 * openjdk version "17.0.9" 2023-10-17 * ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux-gnu] * dotnet 8.0.204 * Ubuntu 22.04 LTS模板的要点是:附上实际执行的验证命令 + 本地工具链版本,这样其他投票者与 PMC 可以复现你的验证环境。如果验证中发现问题,同样要在邮件线程中报告,以便定位和修复问题后再进入下一轮投票。
临时目录与缓存行为
verify-release-candidate.sh的setup_tempdir函数(verify-release-candidate.sh)揭示了验证脚本的沙箱机制:
- 默认使用
mktemp -d创建arrow-${VERSION}.XXXXX临时目录,并在脚本结束时自动清理; - 如果设置了
ARROW_TMPDIR环境变量,则使用该目录且不会自动清理,便于复用构建产物、排查失败原因; - 验证失败时脚本不会删除临时目录,并会打印"See ${ARROW_TMPDIR} for details"提示保留现场。
此外,脚本头部注释还提示了几项环境变量:VERBOSE=1开启set -x调试输出;C++ 构建默认启用 ccache(ARROW_USE_CCACHE,默认 ON);USE_CONDA=1时会在临时目录安装短命 Miniforge 并基于 ci/conda_env_unix.txt、ci/conda_env_cpp.txt 等环境文件创建依赖环境;PYTHON_VERSION、CMAKE_BUILD_TYPE(默认 release)、CMAKE_BUILD_PARALLEL_LEVEL(默认取NPROC)等均可按需覆盖。C++ 测试通过ctest --label-regex unittest --parallel $NPROC --timeout 300运行,即只执行带unittest标签的用例,单测超时上限 300 秒。
验证流程全貌
综合文档与脚本,一次典型的发布候选验证包含以下阶段:
- 环境准备:Ubuntu 执行
sudo dev/release/setup-ubuntu.sh;macOS ARM 按 Homebrew 清单安装工具链; - 源码验证:执行
TEST_DEFAULT=0 TEST_SOURCE=1 verify-release-candidate.sh $VERSION $RC_NUM,脚本自动完成 tarball 下载、GPG 验签、SHA-256/SHA-512 校验、C++ 构建与 ctest、pyarrow 构建与 pytest、GLib/Ruby 构建测试以及跨语言集成测试(各子任务可用TEST_CPP、TEST_PYTHON、TEST_INTEGRATION_CPP等开关裁剪); - 二进制验证(可选):执行
TEST_DEFAULT=0 TEST_BINARIES=1或细分的TEST_WHEELS/TEST_APT/TEST_YUM/TEST_JARS,校验所有二进制产物的签名与校验和; - 投票:在 dev 邮件列表回复 +1(或报告问题),附上验证命令与本地工具链版本。
整个流程的设计目标是:让每一位投票者都能以可复现、可审计的方式确认候选版本确实是从可信源码构建、签名有效、且在自己的目标平台上可编译可运行——这正是 Apache 发布审批机制保障软件供应链可信度的核心所在。
【免费下载链接】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),仅供参考