- 后端
- 认证鉴权
- 云原生
【免费下载链接】opa
Open Policy Agent (OPA) is an open source, general-purpose policy engine.
本篇指南以 OPA 仓库官方发布文档(docs/devel/RELEASE.md)为主线,系统讲解 OPA 项目的发布流程:包括版本化(versioning)与发布(publishing)两个阶段、候选版(RC)与稳定版双轨节奏、release-prepare/dev-prepare两个 Make 目标的完整操作步骤,以及缺陷修复(bugfix)分支的发布规范。读完本篇,你将掌握从修改版本号、生成 CHANGELOG、更新能力集制品(capabilities)到打标签发布 GitHub Release 的端到端实操,并理解背后 build/release 工具链的源码级工作机理。
发布流程总览:版本化与发布两个阶段
OPA 的发布流程由两个阶段组成:版本化(Versioning)与发布(Publishing)。
- 版本化:维护一组记录版本与能力(capability)信息的文件,并对仓库打上标识该版本的语义化版本号(Semantic Version)标签;
- 发布:在 GitHub 上创建新的 Release,附上对应的 CHANGELOG 片段并上传构建阶段产出的二进制文件。
版本化阶段需要维护的核心文件如下:
| 文件 | 作用 |
|---|---|
| CHANGELOG.md | 记录每个版本的所有重要变更 |
| v1/version/version.go | 定义Version变量,即项目当前版本号;Makefile 的VERSION从该文件读取 |
| capabilities.json | 当前版本支持的内置函数(builtins)、特性(features)与未来关键字(future keywords)清单 |
| capabilities/v<version>.json | 每个历史版本的 capabilities 快照文件 |
| builtin_metadata.json | 内置函数的元数据(引入版本、可用版本、Wasm 支持、参数与返回值类型等),供参考文档生成使用 |
| v1/ast/version_index.json | 从 builtin/feature/keyword 到"最小引入版本"的索引 |
这些文件由release-prepare和dev-prepare两个 Make 目标维护,它们封装了 build/release 目录下的工具。官方文档同时给出重要提示:本发布流程可能在不另行通知的情况下变更,因此执行发布前应以当前仓库中的文档与工具行为为准。
当前仓库的 v1/version/version.go 中
Version = "1.21.0-dev",即处于开发(dev)状态;CHANGELOG.md 顶部带有## Unreleased小节,这正是发布前的典型形态。
发布节奏:候选版与稳定版双轨并行
OPA 项目存在两条版本轨道:
- 候选版(Release Candidate):形如
vX.Y.Z-rc.A; - 稳定版(Stable):形如
vX.Y.Z。
OPA 计划在每个月的最后一个周五发布一个新版本。在该周开始时,会从main分支创建候选版分支release-<major>.<minor>-rc.0,并基于该候选版分支创建预发布标签v<major>.<minor>.0-rc.0。
预发布发布后,社区被鼓励试用候选版中的新特性与缺陷修复。如果发现回归或 Bug,需要在切割稳定版之前完成修复。官方明确建议:不建议在生产环境中使用 OPA 发布候选版。如果在此期间main分支没有引入其他特性或修复,随后的稳定版可能与候选版内容完全一致。
版本化:从准备到合并的完整操作步骤
以下步骤假设你已经按照开发环境指南(见 docs/devel/DEVELOPMENT.md)配置好标准 GitHub fork 工作流。
1. 配置 upstream 远端
以下步骤假设存在名为upstream的远端,指向 OPA 源码仓库。如有需要,为仓库添加upstream远端并拉取标签:
git remote add upstream git@github.com:open-policy-agent/opa.git git fetch --tags upstream注意:如果你没有在 GitHub 账号上注册 SSH 公钥,此步骤可能失败。
2. 创建发布分支
基于main创建发布分支,避免在发布过程中弄乱自己的 fork:
git checkout -b release-v<version> origin/main3. 完成 GitHub 认证
通过gh auth login登录,或将带有public_repo权限范围的 personal access token 导出到GITHUB_TOKEN环境变量。认证是必需的:后面生成的 CHANGELOG 需要调用 GitHub API 解析提交关联的 PR 与 Issue。
4. 执行 release-prepare
传入本次发布的语义化版本号:
make release-prepare VERSION=1.19.0该命令会完成两件事:
- 填充本次发布范围的 CHANGELOG 小节;
- 更新
v1/version/version.go、capabilities.json、capabilities/v<version>.json、builtin_metadata.json与v1/ast/version_index.json。
所有改动都直接落在工作区(working tree)中,供你审查。
默认情况下,发布范围从
HEAD可达的最近标签开始。可通过LAST_VERSION=v<previous>覆盖起始点。
从 Makefile 的release-prepare目标源码可以看到其内部行为:
release-prepare: @case "$(VERSION)" in \ *-dev) \ echo "error: VERSION is '$(VERSION)', read from v1/version/version.go."; \ echo " Pass the release version explicitly, e.g. make release-prepare VERSION=1.19.0"; \ exit 1;; \ esac @cd build/release && $(GO) run . changelog \ --version=$(VERSION) \ --update=$(CURDIR)/CHANGELOG.md \ $(if $(LAST_VERSION),--from=$(LAST_VERSION),) \ $(if $(REL_TO),--to=$(REL_TO),) \ $(if $(REL_REPO),--repo=$(REL_REPO),) @cd build/release && $(GO) run . artefacts \ --version=$(VERSION) \ $(if $(REL_SKIP_GENERATE),--skip-generate,)值得注意的两个细节:
- Make 目标首先校验
VERSION不能以-dev结尾——因为 v1/version/version.go 中当前版本通常是<next>-dev,如果忘记显式传入VERSION,会直接报错退出,防止误用开发版本号发布; - 额外支持
LAST_VERSION(覆盖 changelog 起始 ref)、REL_TO(覆盖结束 ref)、REL_REPO(覆盖 GitHub 仓库)与REL_SKIP_GENERATE(跳过代码生成)等高级参数。
另外,Makefile 中的VERSION变量本身来自 build/get-build-version.sh,其实现是用 awk 从v1/version/version.go中提取:
awk -F'"' '/^var Version/{print $2}' v1/version/version.go这印证了官方文档所说"Makefile 的VERSION从 v1/version/version.go 读取"。
5. 审查改动
git status git diff需要特别注意人工修订 CHANGELOG:
- 许多条目并非面向用户(应删除);
- 条目值得按主题重新分组;
- 如果有任何重要的 API 变更,应在独立小节中单独说明;
- 工具会在 stderr 输出一份审查清单(review checklist),提交前值得通读。
6. 提交并推送到 fork
git add . git commit -s -m "Prepare v<version> release" git push origin release-v<version>7. 为发布准备提交创建 Pull Request
将该发布准备提交提交为 Pull Request 并等待合并。
8. 合并后拉取最新代码并打标签
PR 合并后,拉取最新改动并为发布打标签:
git fetch upstream git tag v<semver> upstream/main注意:务必确认标签指向正确的提交 ID!它必须是已合并的发布准备提交,而不是其他提交。
9. 创建开发准备分支
为下一个版本的开发准备工作创建新分支:
git checkout -b dev-v<next_semvar> origin/main10. 执行 dev-prepare
传入下一个版本的语义化版本号:
make dev-prepare VERSION=1.20.0下一个版本的语义化版本号通常是将点版本号加一(即上一个版本若是 1.19.0,下一个就是 1.20.0)。
该命令会把Version设置为<next_semvar>-dev,并在 CHANGELOG 中添加## Unreleased标题。从 Makefile 可以看到dev-prepare要求必须通过命令行显式传入VERSION($(origin VERSION) != "command line"时报错),并支持REL_DRY_RUN与REL_ALLOW_EXISTING_UNRELEASED两个开关。
11. 审查改动
git diff12. 提交并推送开发准备分支
git commit -a -s -m "Prepare v<next_semvar> development" git push origin dev-v<next_semvar>随后为开发准备提交创建 Pull Request。
深入 release-prepare:build/release 工具链源码解析
make release-prepare实际执行的是 build/release 这个独立 Go module 中的命令行工具(入口为 build/release/main.go),它包含三个子命令:changelog、artefacts和dev。该工具的设计原则是:不直接修改 git、不写入 GitHub,所有产物都落在工作区供git status/git diff审查。
changelog 子命令:CHANGELOG 生成的完整流水线
changelog子命令支持以下参数:
changelog [--version X.Y.Z] [--from ref] [--to ref] [--repo owner/name] [--out path | --update path] [--include-local] [--record dir]其生成流水线(核心逻辑见 build/release/internal/changelog/generate.go)分为七个阶段:
- 枚举提交:列出
--from..--to范围内的非合并提交(默认范围是<最新标签>..HEAD,最新标签通过git describe --tags --abbrev=0获取,见 build/release/internal/git/git.go); - GitHub 解析:对每个提交向 GitHub 查询作者、关联的 PR,以及首个 PR 的
closingIssuesReferences(即 PR 面板的 "Development" 关联,REST API 不暴露该信息,需走 GraphQL)。若提交在远端不存在(HTTP 422),则回退解析本地提交消息中的Fixes/Closes/Resolves #N尾注,默认排除这类"仅本地"提交,除非传入--include-local; - 推导 area 前缀:优先使用提交主题中已有的
<area>:前缀,否则按变更路径表推导(如v1/ast/→ast、v1/server/→server),同时规范化主题首字母大写,并标记依赖升级类提交(实现见 build/release/internal/changelog/area.go); - 过滤:丢弃发布机制类提交(如
Release vX.Y.Z、Prepare vX.Y.Z development、Integrate X.Y.Z patch release,正则见 build/release/internal/changelog/filter.go),丢弃 bot 作者的依赖提交,以及仅改动.github/、e2e/、docs/路径的依赖提交; - go.mod 依赖差异合成:对比范围内的 go.mod 直接依赖(
require)变化,对没有被任何保留提交覆盖的模块变更合成独立的 changelog 条目("Bump X from A to B"),实现见 build/release/internal/changelog/synthesis.go 与 build/release/internal/changelog/gomod.go; - 渲染:输出一个
### Miscellaneous列表,按主题排序,依赖升级作为子条目嵌套;链接优先指向 Issue,其次 PR,最后是提交(见 build/release/internal/changelog/render.go)。注意工具刻意不生成单独的 "### Fixes" 等主题小节——主题分组留给维护者人工完成,避免机器判断需要反复撤销; - 拼接(splice):
--update模式把## Unreleased标题改名为## X.Y.Z,并把生成的条目追加到该小节末尾(位于任何手写说明文字之后);若没有## Unreleased标题,则在最顶部版本小节之上插入新小节;若## X.Y.Z已存在则报错,防止重复(见 build/release/internal/changelog/splice.go)。
每个阶段(3–5)的决策都会记录到 stderr,并输出一份人工审查清单,提示需要关注:关联多个 PR 的提交、关闭多个 Issue 的 PR、无 PR 的提交、仅本地提交等。
官方工具说明(build/release/README.md)明确写道:"Expect to edit the result."(务必编辑生成结果)——area 前缀是猜测的,工具无法推断哪些条目值得列出、如何按主题分组。
artefacts 子命令:版本制品文件
artefacts子命令负责版本号与能力制品的更新,参数如下:
artefacts --version X.Y.Z [--repo-root path] [--dry-run] [--skip-generate]执行顺序(见 build/release/internal/artefacts/artefacts.go 的Prepare):
- 更新
v1/version/version.go:将Version设置为指定版本。SetVersion要求文件中恰好存在一个var Version = "..."赋值,否则报错而不是静默改坏文件; - 重新生成
capabilities.json; - 将其复制为
capabilities/vX.Y.Z.json快照; - 重新生成
builtin_metadata.json和v1/ast/version_index.json。
顺序是强制的:capabilities.json必须先是最新的才能被快照;而版本索引读取的是go:embed嵌入的capabilities/目录,因此只有新快照落盘后它才能看到(对应 v1/ast/capabilities.go 的//go:embed version_index.json与 capabilities/capabilities.go 的//go:embed *.json)。
artefacts直接运行三个生成器(go run -tags generate ...),而非make generate——后者依赖wasm-lib-build,会通过 Docker 重建opa.wasm并把无关二进制带入发布 diff:
- internal/cmd/genopacapabilities/main.go:生成
capabilities.json(对内置函数调用Minimal()去除类型名与描述); - internal/cmd/genbuiltinmetadata/main.go:生成
builtin_metadata.json(含每个 builtin 的引入版本、可用版本、Wasm 支持、参数/返回值类型、其他 Rego 解释器的实现情况等); - internal/cmd/genversionindex/main.go:生成 v1/ast/version_index.json,从所有历史 capabilities 快照中为每个 builtin / feature / keyword 计算最小引入版本。
--skip-generate用于只调试版本号更新;重复运行是安全的。--dry-run则只报告将要发生的改动而不写任何文件。
认证与限流
CHANGELOG 生成需要 GitHub 访问:优先读取GITHUB_TOKEN环境变量,其次尝试gh auth token。public_repo权限范围即足够。GraphQL 接口对未认证请求直接拒绝,而 REST 接口限制为每小时 60 次——一个发布范围大约 20 个提交就会耗尽配额,因此认证事实上是必需的。瞬时故障(超时、5xx、限流)会以指数退避重试最多 3 次。
dev 子命令:重开开发
make dev-prepare对应dev子命令,参数为--version X.Y.Z(注意:这是下一个发布版本,不是刚切割的版本)。其执行顺序刻意安排为:
- 在 CHANGELOG.md 最顶部版本之上添加
## Unreleased标题(若已存在则报错,可用--allow-existing-unreleased降级为警告); - 将 v1/version/version.go 的
Version设置为X.Y.Z-dev。
先拼 CHANGELOG、后改版本号:这样当 CHANGELOG 已存在## Unreleased(属于错误状态)时,会在触碰version.go之前就失败,保持工作区干净。
发布:推送标签与创建 GitHub Release
版本化的 PR 合并并打标签后,进入发布(Publishing)阶段:
推送发布标签到源码仓库:
git push upstream v<semver>注意:只有 OPA 维护者拥有执行此步骤的权限。
打开浏览器前往项目的 Releases 页面;
更新草稿版 Release(草稿最多可能需要 20 分钟才可用,可在 Actions 页面跟踪其进度),确认一切正常后发布。
草稿中需要附带对应版本的 CHANGELOG 片段并上传构建产物(各平台二进制及.sha256校验文件,由 Makefile 的ci-build-*系列目标产出到_release/<version>目录,见 Makefile)。另外,从 Makefile 的release-ci目标可以看出:如果版本号包含rc或当前分支是发布分支,则不会把镜像推为latest标签——这保证了候选版与 bugfix 分支不会覆盖稳定版的latest镜像。
发布后的自动化运维:镜像、文档与搜索索引
- Docker 镜像:
openpolicyagent/opa镜像由 CI 流水线自动构建并发布到 Docker Hub,无需任何人工步骤; - 文档与网站:正常情况下会自动更新并发布。如果未自动更新,可通过两种方式手动触发:
- 登录 Netlify(需要项目权限)手动触发一次构建;
- 调用构建 webhook:
curl -X POST -d {} https://api.netlify.com/build_hooks/612e8941ffe30d2902bcce80
- Algolia 搜索索引:站点每日 20:30(UTC)被爬取时自动更新,爬取过程约需 25 分钟,也可在 crawler.algolia.com 手动触发(需登录凭据)。
缺陷修复(Bugfix)发布流程
Bugfix 发布流程与常规发布相似,但有几点关键差异:
- 配置 upstream 远端(同上):
git remote add upstream git@github.com:open-policy-agent/opa.git git fetch --tags upstream - 分支策略:如果是该发布线的首个 bugfix,从发布标签创建发布分支并推送到源码仓库:
git checkout -b release-0.14 v0.14.0 git push upstream release-0.14否则,检出发布分支并按需与
upstream同步:git fetch upstream git checkout release-0.14 git reset --hard upstream/release-0.14 - Cherry-pick 修复:将来自
main或其他分支的变更拣选到 bugfix 分支:git cherry-pick -x <commit-id>使用
-x有助于追溯提交的原始来源。 - 更新版本与 CHANGELOG,与常规发布相同的工作流:
make release-prepare VERSION=0.14.1 - 审查改动:
git status git diff生成的 CHANGELOG 在 bugfix 发布时很可能需要人工调整!
- 提交并推送到 fork:
git commit -s -a -m 'Prepare v0.14.1 release' git push origin release-0.14 - 打开 PR:针对 upstream 的发布分支提交 PR。务必小心:PR 要指向正确的 upstream 发布分支,绝不能打开或合并到
main或其他发布分支。注意:合并该 PR 时必须使用"Rebase and merge"(变基合并)而非 squash(压缩合并),以保留 cherry-pick 的提交。另一种做法是直接在提交 PR 前把 cherry-pick 推送到
upstream。 - 合并后打标签发布:拉取最新改动并为发布打标签,按常规发布的 发布 指南操作(务必给正确的提交打标签)。
- 同步回 main:最后一步是把该版本的 CHANGELOG 片段和生成文件(
builtin_metadata.json与capabilities.json)复制到main,新建一个 PR,把版本信息添加到Unreleased小节之下。如果 bugfix 发布中包含任何Unreleased说明,需将其移除。
附录:常用命令速查表
| 场景 | 命令 |
|---|---|
| 常规版本化 | make release-prepare VERSION=1.19.0 |
| 指定 changelog 起始版本 | make release-prepare VERSION=1.19.0 LAST_VERSION=v1.18.2 |
| 重开开发 | make dev-prepare VERSION=1.20.0 |
| 仅预览 changelog(不写文件) | cd build/release && go run . changelog --version 1.19.0 |
| 仅预览制品更新 | cd build/release && go run . artefacts --version 1.19.0 --dry-run |
| 发布标签 | git push upstream v<semver> |
| Bugfix cherry-pick | git cherry-pick -x <commit-id> |
| 工具链自检 | make check-release-tool(vet、test、lint) |
关于工具链的测试保障:build/release 是一个独立 module,根目录的test与check目标不会覆盖它,需要单独执行make check-release-tool。build/release/internal/changelog 内置了一个基于 build/release/testdata/scenarios 夹具的 golden 测试:该测试是封闭的(hermetic),无网络(GitHub client 为录制回放)、无 git(提交列表、消息与 go.mod 快照均来自磁盘),数据为虚构内容,可通过--record捕获真实运行作为新夹具。
整个发布流程的核心思想可以概括为:用自动化工具生成可审查的草稿(CHANGELOG 与版本制品),人工完成内容修订与最终发布,再通过 CI 自动化完成镜像、文档与索引的收尾——理解 Makefile 中release-prepare/dev-prepare目标与 build/release 工具链的实现,是安全、正确地执行 OPA 版本发布的基础。
- 后端
- 认证鉴权
- 云原生
【免费下载链接】opa
Open Policy Agent (OPA) is an open source, general-purpose policy engine.
相关推荐
PROJ项目发布流程详解:从候选版本到正式版本
PROJ项目发布流程详解:从候选版本到正式版本 前言 PROJ作为地理空间数据处理的核心库,其版本发布流程对于维护软件质量和用户信任至关重要。本文将详细介绍PR
GIS科学计算react-native-macos 版本发布指南:Release Train 分支、RC 候选版与 Stable 稳定版全流程
react native macos 版本发布指南:Release Train 分支、RC 候选版与 Stable 稳定版全流程 导读 本文基于仓库根目录的 R
桌面应用跨平台Genkit Python SDK 版本发布全流程实战指南:从 RC 候选版到 PyPI 稳定发布
Genkit Python SDK 版本发布全流程实战指南:从 RC 候选版到 PyPI 稳定发布 导读 本文围绕 Genkit 开源仓库中 Python 发布
人工智能大模型后端AI AgentRAG工具调用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考