Apache OpenDAL 周度源码发布生命周期:从候选生成、ATR 投票到自动发布的完整实践指南 数据存储后端【免费下载链接】opendalApache OpenDAL: One Layer, All Storage.项目地址https://gitcode.com/gh_mirrors/op/opendal点击查看免费下载Apache OpenDAL 通过一套每周自动化的发布流水线将源码候选生成 → 签名上传 ATR → 社区投票 → 自动发布 → 版本同步全流程收敛为可重复执行的工程实践。本文以仓库中的 weekly.md 为骨架结合.github/workflows下的实际工作流与dev/src/release、scripts中的发布工具源码完整还原这套周度源码发布Weekly source releases生命周期的设计原理、操作步骤与故障恢复方法。读完本文你将掌握 OpenDAL 发布管理者Release Manager下称 RM如何借助 ATRApache Trusted Releases与 GitHub Actions 完成从周四切割到周一发布的自动化流程并能在投票失败、构建缺失、发布中断等场景下准确干预。工作流总览周四切割、周一发布的目标与边界周度发布由定时任务驱动weekly_release.yml 中定义了schedule: cron 0 0 * * 4即每周四 00:00 UTC触发。其基本流程是从周四 00:00 UTC 的main分支切割点准备一条发布分支调用 release-compose.yml 构建、签名并把候选上传到 ATRRM 依照 手动发布流程 验证候选并在 ATR 中开启自动决议 自动发布的投票每小时同步任务完成发布并开启版本同步version-syncPR。两个关键设计约束贯穿始终准备阶段不创建版本 PR、不需要手工合并版本号由脚本根据已合并 PR 的破坏性变更声明直接计算并提交在候选分支上周一只是目标、不是强制期限72 小时投票期从 RM 开启投票那一刻起算而不是从准备开始起算。定时任务延迟、投票开启晚、票数不足都可能导致发布推迟。从源码看weekly_release.yml由prepare、compose、builds、notify四个 job 组成prepare产出候选 SHA 与 RC 版本号compose以workflow_call方式复用release-compose.ymlbuilds显式派发各语言绑定与文档的 RC 构建notify在 GitHub Discussions 发布候选说明。整条链路的权限模型是最小化默认contents: read仅在实际需要写引用、开 PR、写 Discussions 的 job 上按需放大。候选准备Preparation源提交选择与版本决策源提交选择以 push 到达时间而非提交日期为准定时运行会选择截止点cutoff之前最后一条被记录的 main push作为发布源提交。这一点在weekly_release.yml的preparejob 中有明确实现脚本通过 GitHub API 查询weekly_release.yml自身在main上的 push 事件运行记录再用max_by(.created_at, .id)选取created_at cutoff的最新一条并取其head_sha。这条逻辑背后有两个必须理解的细节push 运行时间戳记录的是提交到达 main 的时间不是提交作者日期因此不要用git commit日期推断是否落在截止点内必须保留这段运行历史直到准备完成首次启用周度流程的那一周需要有一条截止点之前被记录的 push否则脚本会以no push recorded before cutoff报错。手动派发workflow_dispatch则走完全不同的路径不要求历史 push直接使用派发时选定的分支提交——即使运行排队期间分支继续前进仍以派发时的 commit 为准。版本决策破坏性变更驱动周度补丁兜底准备阶段会读取上一次已发布源码提交与固定截止点之间合并进 main 的所有 PR逐条校验其可选的破坏性变更声明然后为每个受影响的包调用update-version --patch --breaking package。这一逻辑落在 scripts/release_impact.py 的prepare()与 dev/src/release/mod.rs 的update_version()中版本计算的核心规则如下场景版本处理兼容 PR无破坏性声明维持正常补丁策略不附加任何发布元数据声明破坏性变更的0.x包不兼容增量 minor 1如0.58.x→0.59.0声明破坏性变更的稳定1.x包不兼容增量 major 1如1.2.3→2.0.00.0.x包遵循 Cargo 的补丁兼容边界patch 1多个破坏性 PR 命中同一包只递增一次幂等配置中已更高的版本 / 新包保留配置值不做覆盖实现细节可对照 bump.rs 的next_incompatible_version()major ! 0走major1minor ! 0走minor1否则走patch1与文档规则完全一致。prepare_versions()的单元测试package.rs还验证了同一发布范围重复准备不会重复消耗补丁号以及破坏性声明对未知包直接报错的行为。两条容易被忽略但影响全局的规则公共依赖兼容性变化会连带提升受影响的集成包版本但core 的破坏性变更并不会自动要求绑定包bindings做不兼容版本提升——绑定只要公共行为不变就只需正常补丁。集成包如integrations/object_store、integrations/parquet在 package.rs 中声明了public_compat_dependenciesbump.rs的prepare_public_dependencies()会检测其公共依赖跨过 Cargo 兼容线后强制提升集成版本现有清单与依赖更新代码update_cargo_version、update_maven_version、update_nodejs_version、update_dotnet_version等见 package.rs会应用最终版本计划各语言包按各自的清单格式Cargo.toml、pom.xml、package.json、csproj写入新版本。.release/plan.json冻结版本计划的单一快照候选提交会写入.release/plan.json包含baseline基线版本、source SHA、PR 声明含破坏性变更与迁移说明、版本决策。这个文件是整个发布周期的关键状态载体候选 Discussions 与最终 release notes 读取的是这份快照而不是 PR 的实时描述——因此准备之后的讨论不会因 PR 描述被修改而失真恢复下游 job 时候选保持不变如果声明有误准备另一个 RC而不是在同一候选上修补可以收集修正后的声明下一个周度范围从已发布 plan 的 source SHA 开始与 version-sync PR 是否已合并无关对于没有 plan 的旧版本起始点取最终 tag 与截止点的 merge baseDraft 与 prerelease 状态的 GitHub Release 不会推进 baseline如果某个 commit 关联不到唯一 PR或破坏性声明格式错误准备会立即中止并指出受影响的 commit/PR。声明破坏性变更Declaring breaking changes这是版本决策的输入契约全部围绕 PR 的可选元数据展开兼容 PRPR 模板中的Breaking changes一节留空即可无需列出包名或声明none破坏性 PR必须同时满足两点——添加breaking-changes标签并填写模板中的声明格式如下# Breaking changes Affected packages: core, bindings/java Migration: - Replace old_api() with new_api().填写要求Affected packages使用逗号分隔包名必须来自 dev/src/release/package.rs 中的发布清单core、integrations 与各 bindings即使绑定包源文件没有变化只要公共行为发生变化也必须列入Migration必须给出迁移方式或已删除功能的替代方案。CI 侧由 ci_release_impact.yml 的Breaking change declarationjob 在 PR 变更及标签/描述编辑时提供反馈运行python3 scripts/release_impact.py check。注意它不是强制合并检查required check真正的强制校验发生在每周准备阶段选择版本之前。校验逻辑见 release_impact.py它会剥离 PR 正文中的注释与代码块、定位 Breaking changes 小节、检查标签与内容的一致性、校验受影响包名合法性并拒绝none/todo/tbd之类的占位迁移文本。对审查者reviewer而言API 变更、行为变更、默认值变更和运行时依赖变更都属于需要识别的破坏性变化——这套契约不会自动检测未标记的破坏性变更。因此在第一次启用周度流程前需要人工复核所有未发布的破坏性 PR补齐缺失的标签与迁移声明已经发布的历史 PR 无需回填。候选引用Candidate refs与 RC 编号每次准备尝试会把版本、依赖与 changelog 更新提交到releases/version-rc.N分支例如releases/0.59.3-rc.1并在同一 commit 上原子地推送该分支和轻量标签v0.59.3-rc.1。之后把 SHA 传给 compose——compose 负责签名源码归档而 RC 标签本身不签名。关键约束RC 编号取自已抓取标签中第一个未使用的正整数包括手工准备的候选因此保留 RC 标签可防止分支清理后编号被复用若推送发生冲突conflicting push则整体失败绝不会替换已有标签正确修复准备失败后再重跑准备新候选不会取消已有投票也不会替换已批准的产物。RM 必须在开启新一轮投票前解决既有投票或待发布的候选废弃分支与 ATR 草稿可以单独清理。生命周期配置Configuration首次启用前的五项准备以下配置大多属于外部仓库 / ATR / Nexus 设置合并工作流代码并不会自动生效且绝不能仅为了测试凭据而发布一个版本。首次启用前需要完成GPG复用GPG_SECRET_KEY与SOURCE_SIGNING_FINGERPRINT用于源码归档与签名的最终 tag源码签名同时接受 schedule 与手动 dispatch 事件ATR compose 调用方注册 .github/workflows/weekly_release.yml 为 ATR 的 compose caller同时注册 .github/workflows/release-compose.yml 以支持直接 compose 运行ATR finish 调用方注册 release_lifecycle.yml 与 release_publish.yml 为 ATR 的finishcallers。每小时运行会直接调用发布工作流从而保留调用方身份供 OIDC 使用——而不是以github-actions[bot]身份去 dispatch 发布账号权限定时任务的 owner 与手动派发者必须拥有关联了 ASF 的 GitHub 账号并具备 OpenDAL 所需权限RM 应维护 cron 表达式因为它决定了定时任务的执行者身份Nexus 凭据现有NEXUS_STAGE_DEPLOYER_USER/NEXUS_STAGE_DEPLOYER_PW必须既能上传 staging又能提升 OpenDAL 已关闭的 staging 仓库。此外还需允许 GitHub Actions 创建 PR、写入发布引用与 Discussions既有的包发布者凭据与 release 环境规则继续适用。构建派发与候选通知Builds and preparation notice由于GitHub 不会为GITHUB_TOKEN创建的 tag 触发下游 push 工作流推送 RC 标签后weekly_release.yml的buildsjob 会显式 dispatch既有的 tag 构建、绑定检查与文档工作流。派发时保留 RC 语义包RC 阶段行为Java上传到 Nexus stagingPython使用 TestPyPINodeJS仅执行发布 dry runRuby / .NET保留产物Rust不发布文档保留 RC staging不部署到 nightlies禁用的工作流会被跳过并记录在运行摘要中重试会跳过已经为该候选 commit 派发过的工作流失败的下游 job 应从其自身运行中重跑。ATR 上传与派发成功后notifyjob 会在 General Discussions 创建Release candidate: RC作为共享发布入口包含精确 commit、ATR revision、检查项、下载与构建链接、RM 操作清单、CLI 命令、最终公告草稿、包版本决策以及破坏性变更迁移说明。上传与派发成功并不代表构建或 ATR 检查通过——RM 必须在开启投票前独立验证候选。投票与社区通知Vote and community notification投票操作既可用官方 ATR CLI也可用 ATR 的浏览器控件。候选 Discussion 会把真实 RC 与 revision 代入以下命令atr check status opendal 0.59.3-rc.1 00001 uv run --python 3.13 --with apache-trusted-releases githttps://github.com/apache/tooling-releases-client python - PYTHON from atrclient import api from atrclient.models.api import VoteStartArgs task api.vote_start(VoteStartArgs( projectopendal, version0.59.3-rc.1, revision00001, email_todevopendal.apache.org, automatic_resolve_when_finishedTrue, automatic_publish_when_resolvedTrue, notify_when_finishedTrue, )).task print(task.model_dump_json(indent2)) assert task.task_args[automatic_resolve_when_finished] is True assert task.task_args[automatic_publish_when_resolved] is True PYTHON注意事项这是文档反复强调的坑Python 脚本运行的是官方 ATR 客户端认证配置与atr相同并在返回的 task 中校验两个自动化标志这段脚本同样出现在 release_lifecycle.py 生成的候选通知正文中atr vote start --auto-publish只开启发布、不开启自动决议通用atr api post发送的是字符串而非布尔值无法满足要求如果标志校验失败去 ATR 检查该 task不要重复执行 start 命令要重新读取 task 用atr api get /task/get/TASK_ID对已活跃的投票绝不重复开启。投票结束时 ATR 检查其 Trusted Vote 选票投票通过则自动决议并发布已批准的源码文件未通过则保持未决议状态等待人工跟进且后续补投的票不保证会触发另一次自动尝试。GitHub 与邮件列表的讨论回复不计入ATR Trusted Vote 选票需按 ATR 指引投票。人工恢复流程atr vote tabulate opendal 0.59.3-rc.1 atr vote resolve opendal 0.59.3-rc.1 passedCLI 不可用时用 ATR 浏览器控件取消投票或查看计票。Agent 可在 RM 授权投票动作后使用同一 CLI凭据放在 CLI 的隐藏提示中CI 则只读 ATR 的 JSON API并通过其 trusted-publisher 公告端点工作。每小时同步任务 release_lifecycle.yml 在每小时的第 17 分钟运行GitHub 可能延迟定时任务。它保持候选 Discussion 的开帖不变、以评论追加状态变化每个 ATR 投票轮次至多提醒一次状态未变化则不产生新评论。同步更快的手动命令gh workflow run release_lifecycle.yml --repo apache/opendal --ref mainGitHub 同步永远不会开启或决议投票——这些动作归 ATR 所有失败或取消的投票不可能触发发布已开始的投票保留其原始设置未来候选修改命令不会给已开始的投票开启自动决议。恢复既有候选Recovering an existing candidate在假设自动派发可用之前先检查周度运行的 revision 与各 job工作流变更必须存在于该运行使用的 revision 中——合并修复不会回填旧候选。列出既有 tag 的运行时要不过滤push事件因为自动派发产生的是workflow_dispatch事件gh run list --repo apache/opendal --branch v${release_candidate_version} \ --limit 100 --json name,event,headSha,status,conclusion,databaseId,url随后核对每个运行的 head SHA 与候选 commit失败的下游 job 从既有运行重跑若某工作流没有运行则针对同一 RC tag 派发。例如恢复缺失的 Python 发布构建gh workflow run release_python.yml --repo apache/opendal \ --ref v${release_candidate_version}派发前先读取 RC tag 上的工作流版本——它必须在该 tag 处支持workflow_dispatch而不只是在 main 上。以周度buildsjob 的工作流列表与输入为权威参照NodeJS 使用nodejs-publishfalse与nodejs-publish-dry-runfalseRC tag 本身会启用其 dry runDocs 以 RC tag 作为release_version并带deploy-nightliesfalse缺少必需输入或派发触发器的旧 tag 需要单独做恢复决策不要移动它。派发成功只代表被接受仍需找到对应运行并跟进到完成候选通知不能替代对全部必需构建、registry staging 与 ATR 检查的核验。compose 权限失败时修正 ATR 的允许调用方/actor 配置并在原运行已完成输出仍可用时重跑失败 job、复用既有签名产物——重跑准备或启动新周度运行只会创建新候选而不是恢复旧候选。投票通过之后After the vote passes对新的releases/version-rc.N候选每小时工作流一旦发现 ATR 报告决议通过的投票就会调用 release_publish.yml其核心执行体是python3 scripts/release_lifecycle.py publish --rc $RC。完整流程共五步创建最终引用校验 RC 分支与 tag 指向同一 commit在该 commit 上创建保留的releases/version分支与签名的vversiontag。已存在的最终引用必须一致且绝不移动。这里不使用 ATR OIDC 的commit_hash因为上传工作流在生成 RC 之前就已从 main 启动创建 GitHub Release 并公告创建 GitHub Release并请 ATR 向announceapache.org发送公告ATR 会检查源码发布与下载传播情况。审核后的公告发布在 GitHub Announcements仓库会将其镜像到 devopendal.apache.org开启版本同步 PR从最新 main 打开草稿 version-sync PR。update-version --baseline vversion --sync按包取 main 与已发布版本中的较高者保留新包与开发中的变更并重新生成依赖、lockfiles 与 changelog 条目。工作流不会合并 release 分支、也不会自动合并 PR由于GITHUB_TOKEN不会触发 PR CI维护者需关闭再重开审核后的 PR或推送一次更新来启动检查跟进可选的语言分发在最终 tag 上派发既有的 Rust、Python、Node.js、Ruby、.NET、Dart 与 Docs 工作流跳过禁用的并提升已批准的 Java Nexus staging 仓库。Go 属于独立仓库。待处理或失败的包 job 不会阻塞 GitHub Release、公告或 version-sync PR汇报与清理在候选 Discussion 中汇报可选分发的进度。分发需要跟进时保留 RC 分支便于每小时发现恢复完成后删除同版本的 RC 分支——每次删除都要求其 RC tag 仍保留该 commit且被批准的分支最后删除保证部分清理仍可被发现。最终分支、最终 tag 与 RC 标签保留。每个小时运行会检查外部完成记录并恢复未完成工作。可选包失败仍可见于其自身 Actions 运行与候选通知——源码发布此时已成功只需重跑失败的包 job再等待下一个小时周期或显式恢复gh workflow run release_publish.yml --repo apache/opendal --ref main \ -f rc0.59.3-rc.1如果 version-sync PR 被关闭而未合并恢复前先重开如果分支推送成功但 PR 创建失败重试会复用该分支。一次成功的发布运行仍可能是在等待包分发——需检查候选 Discussion 与下游结果确认完成。包工作流成功是自动门禁RM 也可以按发布流程用每个包的版本在 registry 中核验传播情况。与手动流程的衔接旧式候选的边界这套生命周期只发现新的releases/分支命名空间。既有的release-candidates/weekly-*候选包括 0.59.2继续走 手动官方发布流程不要重命名或迁移它们来纳入自动化。无论新旧源码归档在整个流程中始终是 ATR 批准的 revision手动 SVN 流程仅适用于 SVN staging 的源码。另外值得说明的是对于生命周期之外的候选手动发布流程 仍然是权威操作手册——周度文档与它通过weekly.md#declaring-breaking-changes、weekly.md#after-the-vote-passes等锚点互相引用二者共同构成 OpenDAL 发布体系的完整文档面。本文涉及的候选通知模板、版本计划渲染与发布恢复逻辑均可在 scripts/release_lifecycle.py 与 scripts/release_impact.py 中直接核对适合作为自动化发布链路二次开发与故障排查的起点。赞分享数据存储后端【免费下载链接】opendalApache OpenDAL: One Layer, All Storage.项目地址https://gitcode.com/gh_mirrors/op/opendal点击查看免费下载相关推荐Apache OpenDAL Release CandidateRC发布全流程实战指南从每周 ATR 候选到 Nexus 投票就绪Apache OpenDAL Release CandidateRC发布全流程实战指南从每周 ATR 候选到 Nexus 投票就绪 Apache Open数据存储后端Apache OpenDAL 发布管理实操指南从 RC 候选、ATR 投票到官方发布全流程Apache OpenDAL 发布管理实操指南从 RC 候选、ATR 投票到官方发布全流程 Apache OpenDAL 的每一次版本发布都不是普通的 CI数据存储后端Apache OpenDAL 发布投票Release Vote完整实操指南ATR 自动化投票与手动 SVN 投票路径Apache OpenDAL 发布投票Release Vote完整实操指南ATR 自动化投票与手动 SVN 投票路径 导读 Apache OpenDAL数据存储后端上一篇Czkawka终极重复文件清理神器5分钟释放你的硬盘空间下一篇asyncpg中的查询参数日期范围创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考