ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CapRover 发布流程全解:基于 `release` 分支的生产发布、热修复与自动回合并机制

CapRover 发布流程全解:基于 `release` 分支的生产发布、热修复与自动回合并机制 DevOps云原生运维【免费下载链接】caproverScalable PaaS (automated Dockernginx) - aka Heroku on Steroids项目地址https://gitcode.com/gh_mirrors/ca/caprover点击查看免费下载导读本文以 CapRover 仓库 release/README.md 为核心系统讲解该 PaaS 项目Scalable PaaS自动化 Docker nginx的发布工程体系release分支作为唯一生产发布分支的模型、正常发布与热修复Hotfix两条主流程、分支保护与 CI 检查的仓库配置要求以及部分失败发布的恢复方法。读完本文你将掌握 CapRover 生产镜像从 PR 合入release到 Docker Hub 多平台镜像发布、GitHub Draft Release 生成、以及自动回合并backmerge到master的完整链路并能结合 release 目录下的脚本与 .github/workflows 工作流在自有仓库中复刻这套发布体系。一、发布模型release是唯一的生产发布分支CapRover 的发布工程遵循一个核心原则release分支是唯一的生产发布分支正常发布Normal release和热修复Hotfix都必须通过指向release的 Pull Request 进入生产。合入master永远不会触发生产镜像的发布。从源码结构看这一模型由两个层面的机制共同保证分支保护release禁止直接 push必须通过 PR 进入且要求审批以及build、check-code-formatting、run-lint、validate-release-pr四项检查全部通过详见下文仓库设置要求。CI 触发publish_release.yml 仅在push到release分支时触发而 publish_edge.yml 则在master分支 push 时发布caprover/caprover-edge边缘镜像。两条流水线各司其职互不干扰。release分支在候选分支candidate branch创建时捕获master的状态候选分支只从master上某个提交点长出此后再合入master的提交不会被本次发布携带而是留到下一个版本。这保证了每个发布版本的快照可追溯、内容确定。二、发布配置中心release/release.conf无论是正常发布还是热修复都需要修改 release/release.conf它是整个发布流程的单一事实来源。以当前仓库为例其内容为CAPROVER_VERSION1.15.4 CAPROVER_IMAGE_NAMEcaprover/caprover EDGE_IMAGE_NAMEcaprover/caprover-edge EDGE_VERSION0.0.1 FRONTEND_REPOSITORYhttps://github.com/githubsaturn/caprover-frontend.git RELEASE_FRONTEND_COMMITc9005cc2e5ac1b6816cb983d2d3732338c546a94 EDGE_FRONTEND_COMMIT各配置项的含义与作用如下配置项含义使用方CAPROVER_VERSION本次发布的语义化版本号形如X.Y.Z被 validate-version.sh、create-draft-release.sh、create-backmerge-pr.sh 等脚本 source 引用用于生成 Git tagv${CAPROVER_VERSION}、GitHub Release 标题和 backmerge 分支名backmerge-v${CAPROVER_VERSION}CAPROVER_IMAGE_NAME生产镜像在 Docker Hub 上的仓库名即caprover/caprovervalidate-version.sh 用它拼接 Docker Hub API 检查版本是否已存在EDGE_IMAGE_NAME边缘镜像仓库名caprover/caprover-edgedockerfile.edge 在构建阶段通过config-override.json写入镜像名EDGE_VERSION边缘镜像版本当前为0.0.1配合docker build --pull等策略使用dockerfile.edgeFRONTEND_REPOSITORY前端代码仓库地址前端构建流程据此 clone 指定版本的前端代码RELEASE_FRONTEND_COMMIT本次发布锁定的前端提交 SHA当前为c9005cc...前端构建流程检出该提交确保发布版前端与后端版本严格对应EDGE_FRONTEND_COMMIT边缘构建锁定的前端提交 SHA当前为空表示跟随默认分支边缘构建流程注意版本号必须严格匹配X.Y.Z三位语义化格式。脚本 validate-version.sh 用正则^[0-9]\.[0-9]\.[0-9]$校验同时还会校验CHANGELOG.md 中存在## [X.Y.Z]标题对版本号做正则转义后匹配^## \$ESCAPED_CAPROVER_VERSION\Git tagvX.Y.Z尚未存在于 GitHub通过git ls-remote检查Docker Hub 上caprover/caprover的该版本 tag 尚未存在请求https://hub.docker.com/v2/repositories/${CAPROVER_IMAGE_NAME}/tags/${CAPROVER_VERSION}期望 HTTP 404。这层三查机制从根本上避免了版本号重复、CHANGELOG 缺失或已发布版本被覆盖的风险。三、正常发布Normal release流程正常发布面向master上累积的已合入工作完整步骤如下先完成回合并处理任何待处理的release→master回合并backmerge确保release分支已包含之前发布的所有内容。创建候选分支从master上期望的提交点创建短生命周期分支例如release-candidate/X.Y.Z。更新版本配置修改 release/release.conf 中的CAPROVER_VERSION与RELEASE_FRONTEND_COMMIT。更新变更日志在 CHANGELOG.md 中新增对应的## [X.Y.Z]小节记录该版本的用户可见变更。打开发布 PR以Release vX.Y.Z为标题创建目标为release的 Pull Request。合并 PR等待各项检查通过后合并。合并触发的 publish_release.yml 流水线是一个五阶段、有依赖关系的任务链needs声明run-pre-checks ──► prepare-frontend ──► build-publish-docker-hub ──► draft-github-release ──► backmerge-release阶段工作内容关键证据源码run-pre-checks在ubuntu-latest上以 Node.js 24 执行npm ci、npm run build、npm run lint、npm run formatter、npm run test其中测试会先创建/captain目录publish_release.ymlprepare-frontend调用./release/build-and-push.sh release frontend构建发布版前端产物上传为release-frontendartifact保留 1 天publish_release.ymlbuild-publish-docker-hub下载前端产物 →docker-setup准备多平台 builder → 用secrets.REGISTRY_USERNAME/REGISTRY_PASSWORD登录 Docker Hub →publish构建并推送镜像publish_release.ymldraft-github-release需要contents: write权限执行 create-draft-release.sh 创建 Draft GitHub Releasepublish_release.ymlbackmerge-release需要actions: write、contents: write、pull-requests: write权限执行 create-backmerge-pr.sh 打开回合并 PRpublish_release.yml3.1 关键点前端与后端分离构建prepare-frontend阶段在没有 registry 凭据的独立 job中构建前端依赖而后端与最终镜像的构建发布阶段才持有 Docker Hub 凭据。前端产物通过 artifact 在 job 间传递retention-days: 1这种职责分离降低了凭据泄露面。3.2 关键点发布后自动回合并镜像发布成功后自动化流程会创建一个钉在已发布提交上的backmerge-vX.Y.Z分支并向master打开回合并 PR在可行时启用自动合并auto-merge。这一步由 create-backmerge-pr.sh 实现其幂等逻辑如下校验GH_TOKEN、GITHUB_REPOSITORY、GITHUB_SHA三个环境变量必须存在否则退出通过gh api查询backmerge-v$CAPROVER_VERSION分支是否已存在若已存在但指向的 SHA 与当前GITHUB_SHA不一致则报错退出不存在则以当前 SHA 创建该分支查询是否已有指向master的该分支开放 PR排除 cross-repository 的 PR存在则复用否则用gh pr create创建标题为Backmerge vX.Y.Z from release into master的 PR显式针对该分支触发build_project.yml、format_project.yml、lint_project.yml三个工作流调用gh pr merge --auto --merge启用自动合并若自动合并不可用或需要手动解决冲突则输出::warning::日志提示人工介入。3.3 关键点为什么回合并 PR 需要显式触发检查GitHub 对使用内置GITHUB_TOKEN创建的 PR 有一个重要限制不会自动启动pull_request工作流。因此 backmerge 脚本在创建分支后先显式地对该分支 dispatch 构建、格式、lint 三个工作流再由仓库规则负责等待这些检查完成最后才启用自动合并。这是整个回合并环节中最容易踩坑的细节务必在自建仓库时复刻。四、热修复Hotfix流程热修复用于在生产环境发现紧急缺陷时只携带上次生产代码加本次修复发布不夹带master上尚未发布的新功能。步骤从当前release分支创建短生命周期分支在该分支上应用修复按前述方式更新 release/release.conf 与 CHANGELOG.md打开标题为Hotfix vX.Y.Z、目标为release的 PR检查通过后合并。合并后发布的是上一次生产代码 热修复不包含master上未发布的工作。随后的自动回合并会把修复及其发布元数据带入未来版本。热修复的合法性由 validate-release-pr.sh 中的专项逻辑把关当PR_TITLE匹配Hotfix vX.Y.Z时脚本遍历PR_BASE_SHA..HEAD之间的全部提交只要其中有任何一个提交是origin/master的祖先即已存在于master就判定Hotfix PR 不能包含 master 上未发布的提交并拒绝合并同时要求origin/master必须存在否则报错。五、PR 校验validate-release-pr.sh与 CI 检查链针对release的 PRopened/synchronize/reopened/edited事件会触发 validate_release_pr.yml它做两件事以fetch-depth: 0检出 PR head SHA注入PR_TITLEPR 标题与PR_BASE_SHAbase 分支 SHA两个环境变量后运行 validate-release-pr.sh运行 validate-version.sh 检查版本可用性。validate-release-pr.sh 的完整校验逻辑必填变量PR_TITLE、PR_BASE_SHA缺一即退出标题格式必须匹配^(Release|Hotfix)\ v([0-9]\.[0-9]\.[0-9])$即Release vX.Y.Z或Hotfix vX.Y.Z版本一致性PR 标题中的版本必须与release.conf中的CAPROVER_VERSION一致祖先检查git merge-base --is-ancestor $PR_BASE_SHA HEAD必须成立即发布 PR 必须包含当前 release 分支——这是先回合并再发新版规则的自动化落地热修复专项见上文第四节。整个 PR 合并门禁由以下检查组成build对应 build_project.yml、check-code-formattingformat_project.yml、run-lintlint_project.yml以及validate-release-prvalidate_release_pr.yml。六、发布镜像的构建方式发布镜像与边缘镜像各自使用独立的 Dockerfile生产镜像dockerfile.release边缘镜像dockerfile.edge两者结构类似都采用两阶段构建。以 dockerfile.release 为例# Build stage runs on the host platform to avoid QEMU SIGILL issues with Node.js 24 on arm64 FROM --platform$BUILDPLATFORM node:24-alpine AS builder RUN apk add --update --no-cache make gcc g git curl openssl WORKDIR /usr/src/app COPY . ./ # Build backend code RUN npm ci \ npm run build \ npm ci --omitdev \ npm cache clean --force # Final stage uses the target platforms Node.js runtime FROM node:24-alpine RUN apk add --update --no-cache git curl openssl openssh WORKDIR /usr/src/app COPY --frombuilder /usr/src/app . ENV NODE_ENV production ENV PORT 3000 EXPOSE 3000 CMD [node, ./built/server.js]值得注意的工程细节--platform$BUILDPLATFORM构建阶段运行在宿主平台上避免 Node.js 24 在 arm64 上触发 QEMU SIGILL 问题这是官方注释明确记录的原因最终阶段才使用目标平台的 Node.js 运行时。npm ci两次第一次含 devDependencies 完成 TypeScript 构建产物在./built/入口为node ./built/server.js第二次--omitdev仅装运行时依赖最后清空 npm 缓存最大化减小镜像体积。运行时能力最终镜像安装git curl openssl openssh对应 CapRover 运行时需要执行 git 操作、HTTPS 请求、SSL 处理与 SSH 等能力。边缘镜像 dockerfile.edge 在此基础上多了两步构建时 sourcerelease.conf并写入config-override.json内容形如{publishedNameOnDockerHub:caprover/caprover-edge,version:0.0.1}以及通过ADD https://www.google.com /time.now强制打破 Docker 层缓存注释写明quick hack invalidates the cache确保边缘镜像总是基于最新代码重建。七、仓库设置要求Repository Settings要让这套流水线在生产环境稳定运行仓库必须做如下配置保护release分支禁止直接 push强制走 Pull Request并要求审批approvals。release分支必需的检查build、check-code-formatting、run-lint、validate-release-pr四项。master分支规则对自动生成的 backmerge PR 要求build、check-code-formatting、run-lint三项检查。GitHub Actions 权限允许 Actions 创建 PR 和批准 PRworkflow permissions 需包含contents: write、pull-requests: write、actions: write这样发布工作流才能自动打开并自动合并 backmerge PR。如前所述由于GITHUB_TOKEN创建的 PR 不会触发pull_request工作流backmerge 脚本采用显式 dispatch 三个工作流的补偿手段仓库规则仍负责等待这些检查完成后再放行自动合并。八、恢复部分失败的发布Recovering a partial release发布是长链路前端构建 → 镜像构建推送 → GitHub Release → backmerge中间环节可能失败。恢复策略分两种情况情况一镜像构建已成功后续 draft-release 或 backmerge job 失败在既有工作流运行上使用Re-run failed jobs仅重跑失败任务。这样会保留已成功的镜像 job从失败阶段继续避免重复构建与推送。情况二带版本号的 Docker 镜像已发布但构建 job 上报失败或整个工作流被重启不要重建该版本绝不覆盖已存在的版本 tag。正确做法是对照成功的buildx输出确认已发布 manifest digest检出工作流运行中显示的确切GITHUB_SHA使用具有仓库写权限的 GitHub token 手动运行剩余脚本export GH_TOKENTOKEN_WITH_REPOSITORY_WRITE_ACCESS export GITHUB_REPOSITORYcaprover/caprover export GITHUB_SHA$(git rev-parse HEAD) ./release/create-draft-release.sh ./release/create-backmerge-pr.sh如果无法确认已发布镜像确实是该次发布尝试的输出产物立即停止并调查而不是移动或覆盖版本化 tag。手动执行时脚本自身也提供了充分的防护create-draft-release.sh 会用awk从 CHANGELOG.md 提取## [X.Y.Z]小节作为 release notes提取不到版本或 notes 则退出检查 Git tagvX.Y.Z是否已存在且指向的 SHA 必须等于GITHUB_SHA不一致则退出若 GitHub Release 已存在则直接退出幂等最后用gh release create --draft创建 Draft Release。create-backmerge-pr.sh 如前所述具备分支与 PR 的幂等检查不会重复创建。九、边缘镜像Edge发布与旧 tag 清理master分支的每次 push 会触发 publish_edge.yml构建并推送caprover/caprover-edge边缘镜像供用户在正式发布前尝鲜。流水线同样包含 pre-checks、前端构建edge frontend、多平台构建与推送推送成功后额外运行 cleanup-edge-tags.sh 清理旧 tag。cleanup-edge-tags.sh 的清理逻辑值得单独说明通过 Docker Hub v2 APIhttps://hub.docker.com/v2/auth/token用REGISTRY_USERNAME/REGISTRY_PASSWORD换取 access token分页拉取caprover-edge仓库的全部 tag筛选出名称恰为 40 位十六进制 commit SHA的 tagtest(^[0-9a-f]{40}$)记录其last_updated按更新时间倒序排序保留最新的KEEP_EDGE_COMMIT_TAGS个可通过环境变量配置默认 100且必须为正整数删除更早的 commit tag删除时对 HTTP 状态做分级处理2xx 视为成功404 视为已被删除其他状态码视为失败退出。边缘构建还通过 dockerfile.edge 中ADD https://www.google.com /time.now这一缓存失效技巧保证每次master提交都产出全新的边缘镜像。十、小结与故障排查速查CapRover 的发布体系可以用一张状态机概括master ──(候选分支)──► release PR (Release vX.Y.Z) ──合并──► push release │ publish_release.yml │ 镜像构建推送 → Draft Release → backmerge PR → master正常发布master→release-candidate/X.Y.Z→Release vX.Y.ZPR → 合入release→ 自动发布 回合并。热修复release→ hotfix 分支 →Hotfix vX.Y.ZPR → 合入release→ 发布不含 master 未发布内容 回合并。合并到master只发布caprover/caprover-edge边缘镜像绝不发布生产镜像。常见问题速查现象排查方向发布 PR 校验失败提示 does not contain the current release branch存在未完成的release→master回合并先完成 backmerge 再准备正常发布Hotfix PR 被拒提示 cannot include unreleased commits from masterHotfix 分支夹带了master上的未发布提交需基于release重新切分支版本校验失败检查CAPROVER_VERSION是否符合X.Y.Z、CHANGELOG.md是否有对应## [X.Y.Z]标题、GitHub tag 或 Docker Hub tag 是否已存在backmerge PR 无法自动合并查看流水线是否输出::warning::Auto-merge is unavailable...确认仓库规则已等待 build/format/lint 检查完成发布进行到一半失败镜像已发布则用 Re-run failed jobs镜像已发布但 job 上报失败则核对 digest 与GITHUB_SHA后手动执行 create-draft-release.sh 与 create-backmerge-pr.sh切勿重建已发布的版本这套发布体系的核心资产都沉淀在 release 目录的脚本配置、验证、发布、回合并、边缘清理与 .github/workflows 的六个工作流中理解它们之间的触发关系与幂等设计是安全、稳定地运营 CapRover 发布流程的关键。赞分享DevOps云原生运维【免费下载链接】caproverScalable PaaS (automated Dockernginx) - aka Heroku on Steroids项目地址https://gitcode.com/gh_mirrors/ca/caprover点击查看免费下载相关推荐oras-go 的 GitOps 发布流程解析基于 release 分支、PR 合并与自动化打标签的版本发布实战oras go 的 GitOps 发布流程解析基于 release 分支、PR 合并与自动化打标签的版本发布实战 导读 本文以当前仓库中 vendored 的云原生集群管理虚拟化多集群Mithril.js 自动化发布流程解析基于 pr-release 的 main→release 分支工作流Mithril.js 自动化发布流程解析基于 pr release 的 main→release 分支工作流 Mithril.js当前仓库 package.Grafana Loki 发布准备Prepare Release流程全解析基于 release-please 的自动化发布 PR 管线Grafana Loki 发布准备Prepare Release流程全解析基于 release please 的自动化发布 PR 管线 本篇指南以 Gra可观测性日志分析后端微服务对象存储云原生上一篇深入理解pdfrw对象模型PDF文件如何映射到Python数据结构下一篇FNF-PsychEngine核心功能详解为什么它是Friday Night Funkin modders的首选工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表