YARP 反向代理仓库运维操作手册:分支管理、版本发布、补丁回流与依赖流(Operations Playbook)
【免费下载链接】reverse-proxyA toolkit for developing high-performance HTTP reverse proxy applications.项目地址: https://gitcode.com/GitHub_Trending/re/reverse-proxy
本篇技术指南以 docs/operations 目录下的运维操作文档为核心,系统讲解 YARP(Reverse Proxy)仓库在日常维护中最关键的四大流程:分支创建与命名(Branching)、预览版/正式版发布(Release)、补丁向后移植到预览分支(Backporting)以及基于 Arcade/Maestro 的跨仓库依赖流(Dependency Flow)。阅读本文后,你将掌握 YARP 维护者如何从main分支切出release/*分支、如何用 Azure DevOps 流水线把构建产物发布到 NuGet.org、如何处理预览分支上的缺陷修复与内部安全问题,以及如何用darc命令行工具管理仓库间的依赖订阅,从而能够独立参与或复刻这套开源仓库的运维实践。
一、运维文档总览:这份 Playbook 覆盖了什么
仓库中的 docs/operations/README.md 是整个运维知识库的入口,它明确说明:本文档主要面向项目维护者(maintainers),贡献者也可阅读以了解项目流程。整个目录围绕四份文档展开:
| 文档 | 主题 | 解决的问题 |
|---|---|---|
| Branching.md | 分支任务 | 何时、如何从main切出release/*分支,以及如何更新main上的品牌版本号 |
| Release.md | 版本发布 | 如何从候选构建一路走到 NuGet.org 正式发布,含审批、打 Tag、发布说明与归档 |
| BackportingToPreview.md | 补丁回流 | 预览分支上的缺陷修复如何验证、打 Tag、发布,以及内部安全修复的私有流程 |
| DependencyFlow.md | 依赖流 | 如何用 Arcade/Maestro/darc管理 YARP 对 .NET 工程系统(Arcade)的依赖更新 |
从 eng/Versions.props 可以看到当前仓库版本为3.0.0-preview.1,且文件注释明确要求preview与编号之间必须保留一个点(如preview.1),以保证按 semver 排序时preview.10不会排在preview.1与preview.2之间——这是分支与发布命名背后需要遵守的语义化版本规则。
二、分支任务(Branching):从 main 切出 release 分支
2.1 创建发布分支
当代码准备进入分支阶段时,按以下步骤操作(命令均在本地 clone 中执行):
- 确保本地
main是最新的:git checkout main git pull origin main - 创建发布分支。预览版分支与正式版分支的命名规则不同:
git checkout -b release/1.1.0-previewX其中
X是 YARP 的预览编号。发布非预览版本时,分支名应使用release/1.1而不是release/1.1.0——这样分支可以被后续的补丁版本(patch)复用。 - 若发布的是非预览(正式)版本,还需要:
- 在 eng/Versions.props 中将
PreReleaseVersionLabel设置为rtw(release to web,即正式版标识); - 运行打包命令
build.cmd -pack(该命令由仓库根目录的 pack.cmd 间接调用eng\common\Build.ps1 -restore -build -pack完成); - 检查
artifacts/packages/Debug/Shipping目录下的包名是否不带后缀:例如应为Yarp.ReverseProxy.1.1.0.nupkg,而非Yarp.ReverseProxy.1.1.0-dev.nupkg。
- 在 eng/Versions.props 中将
- 推送分支到服务器:
git push origin release/1.1.0-previewX
2.2 同步更新 main 上的品牌版本号
分支建好后,main需要立刻推进到下一个预览编号,避免版本回退:
- 编辑 eng/Versions.props;
- 将
PreReleaseVersionLabel改为preview.X(X为下一个预览编号); - 提交 PR 并尽快合入(文档建议尽量用自动合并)。
2.3 同步更新 global.json 中的运行时与 SDK
在main上检查 global.json 中的tools.runtimes.dotnet与tools.runtimes.aspnetcore,确保包含最新的 .NET 8.0(当前为8.0.13)与 .NET 9.0(当前为9.0.2)运行时版本,SDK 使用11.0.100-preview.6.26359.118。这一步骤保证了新分支的构建环境与 .NET 官方发布节奏保持一致。
从源码结构看,eng/Versions.props 中的
<DotNetFinalVersionKind Condition="'$(PreReleaseVersionLabel)' == 'rtw'">release</DotNetFinalVersionKind>正是正式版包名不带后缀的底层开关:当PreReleaseVersionLabel为rtw时,Arcade 将版本定性为最终发布版本。
三、版本发布(Release):从候选构建到 NuGet.org
Release.md 描述了发布 YARP 预览版的完整指南。正式流程建议先开一个release checklist issue跟踪进度,清单包含:创建发布分支、更新PreReleaseVersionLabel、在dotnet-yarp-official流水线上定位并验证构建、发布构建、打 Tag、撰写并发布发布说明、关闭旧 milestone、社交媒体公告、保护预览分支、删除上一个预览分支、请求源码归档等步骤。
3.1 版本号确认(Versioning)
发布前必须确认 eng/Versions.props 中的版本与预发布标签符合预期;正式版发布时PreReleaseVersionLabel必须为rtw。
3.2 确保存在发布分支
参考 Branching.md 完成三件事:
- 创建下一个预览分支;
- 更新
main上的品牌版本号; - 更新
main上的global.json运行时与 SDK 版本。
3.3 定位最终构建(Identify the Final Build)
最终构建是 azure-pipelines.yml 定义的dotnet-yarp-official流水线(位于 dnceng/internal)中,在对应release/x分支上的最新一次成功构建。可借助 Azure DevOps 的 "Branches" 标签页定位。若该分支尚未镜像且无未合入变更,也可以使用main分支上对应 commit 的构建。
该流水线的构建配置要点(可在仓库的 azure-pipelines.yml 中核对):
- 触发分支包括
main、release/*、internal/release/*; - 在 Windows(1es-windows-2022)池上执行
eng\common\cibuild.cmd -configuration Release -prepareMachine; - 启用真实签名(
DotNetSignType=real)、SDL 安全扫描(policheck、codeql、binskim 等); - Release 配置下将
artifacts/packages/上传为名为artifacts的构建产物。
3.4 验证最终构建(Validate the Final Build)
验证方式可根据实际情况选择,最低限度是验证示例(samples)能用候选包运行:
- 从构建详情页的 "Related" 中的 "Artifacts" 下载最终构建产物;
- NuGet 包位于
PackageArtifacts产物中; - 消费 .nupkg 的两种方式:
- Visual Studio:把包放入本地文件夹,然后在 VS 中将该文件夹添加为 NuGet feed;
- 命令行:
dotnet nuget add source <directory> -n local
- 按 Getting Started 指南走一遍上手流程,并在发布分支上按需更新文档;
- 同时验证本次发布涉及的重大新场景及其配套文档。
3.5 发布构建(Release the build)
验证完成后进入发布阶段:
- 打开
dotnet-yarp-release流水线并选择 "Run Pipeline"; - 在 "Resources" 中选择已验证产物对应的流水线运行(dotnet-yarp-release.yml 中通过
resources.pipelines声明了对dotnet-yarp-official的引用); - 反复核对产物中包版本号与验证时一致;
- 点击 "Run"——除非你是发布审批人,否则你的工作到此结束。
从 dotnet-yarp-release.yml 可以看到发布流水线的实际逻辑:PreDeploymentApprovalJob使用ManualValidation@1任务向审批人列表(karelz@microsoft.com、samsp@microsoft.com 等)发送通知;审批通过后NuGetPush任务遍历$(Pipeline.Workspace)\Release\Shipping下的.nupkg,只推送以Yarp.ReverseProxy.或Yarp.Telemetry.Consumption.开头的包(跳过.symbols.nupkg),其余包会跳过并提示"update the script to change this"。
3.6 审批发布(Approve the release)
- Azure 流水线会向所有发布审批人发送邮件,等待其中一人批准;
- 点击 "Review Manual Validation" 或在 Azure DevOps 中直接打开发布流水线,会看到阶段处于 "Pending Approval";
- 输入类似
release for preview X的注释并批准; - 批准后包会自动发布,此时虽然理论上可以取消流水线,但可能为时已晚(详见"故障排查");
- 包被推送后,当 "NuGet.org" 阶段变绿即表示发布成功;
- 注意:NuGet 发布很快,但后台索引可能需要数小时,包才会在 NuGet.org 上完全可用。
3.7 打 Tag(Tag the commit)
为最终构建关联的 commit(不一定是当前 release 分支的 HEAD)创建并推送 git 标签,参考以往标签的格式,使用轻量标签(lightweight tag)而非附注标签:
git tag v1.0.0-previewX git push upstream v1.0.0-previewX注意推送到 upstream(上游仓库),而不是你的 fork。
3.8 发布说明与收尾
- 起草发布说明:使用新标签在 GitHub Releases 创建草稿,参考以往发布的推荐内容与格式;
- 发布发布说明:内容应引用最新的文档、包等;
- 关闭旧 milestone:此时应已清空;若还有遗留 issue,移到下一个 milestone;
- 社交媒体公告:发布说明链接发送给 David Fowler(其 Twitter 粉丝对 YARP 兴趣浓厚)并请其转发;
- 保护预览分支:避免对预览分支的意外推送或删除;
- 删除上一个预览分支:此后仓库上应只保留一个预览分支。
3.9 源码归档(Source Code Archival)
通过内部 dpsops 门户发起 "Source Code Archival" 请求,按步骤填写表单并等待归档报告,核对归档文件大小与数量是否与 YARP 仓库一致。推荐字段值:
| 字段 | 值 |
|---|---|
| Team Alias | dotnetrp |
| Business Group Name | Devdiv |
| Product Name | YARP |
| Version | <release version> |
| Production Type | dotNET |
| Release Type | <RC or Release> |
| Operating System(s) | Cross Platform |
| Product Language(s) | English |
| Release Date | <release date> |
| File Count | <repo 中大致文件数> |
| Back Up Type | Code Repo(Git URL/AzureDevOps) |
| Repo URL | <内部 AzDo YARP 仓库链接> |
| OwnerAlias | dotnetrp |
| File Collection | Build Scripts, Help Utility Source Code, Source Code |
| Data Size | <总大小约 MB 数> |
3.10 发布故障排查(Troubleshooting)
认证错误(Authentication Errors):流水线通过 Azure DevOps 的 "Service Connection" 认证。若出现认证错误,多半是 API Key 失效:
- 登录 NuGet.org(需
@microsoft.com账号且有权访问dotnetframework组织); - 生成新 API Key,Package Owner 选
dotnetframework,Package "glob" 填*; - 将新 Key 填入 Azure DevOps 的 "nuget.org (dotnetframework organization)" Service Connection;
- 无权限时联系
dnceng@microsoft.com。
意外过度发布(Accidental Overpublish):NuGet.org 设计上不允许删除包,只能 "unlist"(从搜索结果中移除)。直接引用该版本的下载仍可用,但不会再出现在搜索或"安装最新版"等非版本特定操作中:
- 登录 NuGet.org(同上权限要求);
- 进入包页面,点击右侧 "Info" 侧栏的 "Manage package";
- 展开 "Listing";
- 选择误发布的版本;
- 取消勾选 "List in search results";
- 点击 "Save"。
包被拒绝(Package was rejected):NuGet.org 对所有Microsoft.开头的包有特殊标准。若因不满足标准被拒,参考 "NuGet @ Microsoft" 页面了解必备标准与配置指南。
四、补丁回流(Backporting):修复预览分支
BackportingToPreview.md 说明:把修改回移植(backport)到预览分支,与常规发布的流程非常相似——在预览分支上做修改、验证构建、最终发布。
常规步骤:
# 1. 检出预览分支 git checkout release/1.0.0-previewX # 2. 修改并提交变更 # 3. 推送到自己的 fork,并对预览分支发起 PR # 4. PR 合并后,等待内部 microsoft-reverse-proxy-official 流水线产出构建 # 5. 按常规发布的验证方式验证构建 # 6. 该构建的 Package Artifacts 可用于验证补丁(也可选用公共流水线的产物) # 7. 在预览分支上持续迭代直到验证满意 # 8. 从预览分支发布构建为已发布的提交创建新标签(仍在预览分支上时):
git tag v1.0.0-previewX.build.d git push upstream --tags最后为这个版本创建新的 GitHub Release。
4.1 内部修复(Internal fixes)
涉及重大安全或披露问题的缺陷必须先私有修复,全部工作在内部 AzDo 仓库完成,到披露时再合并到公共 GitHub 仓库:
- 单独 clone内部仓库(https://dev.azure.com/dnceng/internal/_git/dotnet-yarp),避免误推送到公共仓库;
- 以上一次发布的 tagged commit为起点,创建名为
internal/release/{被修补版本}的分支; - 按需更新版本号;
- 创建功能分支、修复问题,并通过 AzDo 提交 PR;
- 从内部分支发布构建;
- 打 Tag 并推送到公共仓库——不要推送到内部镜像的常规
main或release/*分支; - 按需将变更 cherry-pick 到公共
main; - 完成标准发布清单。
五、依赖流(Dependency Flow):Arcade、Maestro 与 darc
5.1 机制概述
YARP 使用 .NET 工程系统 Arcade 构建本仓库。工程系统的一部分是名为Maestro的服务,它负责管理仓库之间的依赖流动:
- 当某个仓库构建完成后,可自动把构建发布到 Maestro 的Channel;
- 其他仓库可订阅该 Channel 以接收更新后的构建;
- Maestro 会自动为订阅了依赖变更的仓库打开更新依赖的 PR。
本仓库通过 eng/Version.Details.xml 记录了工具链依赖:Microsoft.DotNet.Arcade.Sdk与Microsoft.DotNet.Helix.Sdk均来自https://github.com/dotnet/arcade(当前版本11.0.0-beta.26407.8,对应 commit212960245c74330fbfb71776563638061e35446c),而 global.json 中的msbuild-sdks亦引用同一版本——两者共同保证全仓库使用一致的 Arcade SDK。
5.2 darc 的安装与基本用法
Maestro 可以用darc命令行工具查询与控制。使用前提是加入dotnet/arcade-contribGitHub Team。初始化步骤:
- 运行
.\eng\common\darc-init.ps1安装全局工具(仓库内还提供了对应的 eng/common/darc-init.sh); - 安装后运行
darc authenticate并按提示完成认证。
不带参数运行darc会显示命令列表;darc help [command]查看具体命令的帮助。
5.3 查看默认 Channel 映射
仓库可基于分支配置为自动把构建发布到某 Channel。查看某仓库的当前映射:
darc get-default-channels --source-repo [repo][repo]可以是匹配系统内完整 GitHub URL 的任意子串,最简便的方式是直接写[owner]/[name]。示例输出:
> darc get-default-channels --source-repo dotnet/aspnetcore (3796) https://github.com/dotnet/aspnetcore @ release/6.0 -> .NET 6 (5027) https://github.com/dotnet/aspnetcore @ release/8.0 -> .NET 8 (5731) https://github.com/dotnet/aspnetcore @ release/9.0 -> .NET 9 (5732) https://github.com/dotnet/aspnetcore @ main -> .NET 10 (6050) https://github.com/dotnet/aspnetcore @ release/10.0-preview1 -> .NET 10 Preview 15.4 管理订阅(Subscriptions)
订阅通过get-subscriptions、add-subscription、update-subscription命令管理:
darc get-subscription查看系统内所有订阅;- 用
--source-repo [repo]与--target-repo [repo]过滤。例如查看dotnet/yarp订阅了哪些源:
> darc get-subscriptions --target-repo dotnet/yarp https://github.com/dotnet/arcade (.NET Eng - Latest) ==> 'https://github.com/dotnet/yarp' ('main') - Id: 1751e896-c0f1-4247-3909-08d8c8762e9e - Update Frequency: EveryWeek - Enabled: True - Batchable: False ... https://github.com/dotnet/arcade (.NET Eng - Latest) ==> 'https://github.com/dotnet/yarp' ('release/2.2') - Id: ebd75d9f-8988-4f50-bd1d-83dfc79fb7ba - Update Frequency: EveryWeek - ...可见 YARP 的main与release/2.2分支都以EveryWeek的频率订阅 Arcade 的.NET Eng - LatestChannel。
新增订阅:不带参数运行darc add-subscription,会打开一个包含 TODO 脚本的编辑器:
Channel: <required> Source Repository URL: <required> Target Repository URL: <required> Target Branch: <required> Update Frequency: <'none', 'everyDay', 'everyBuild', 'twiceDaily', 'everyWeek'> Batchable: False Merge Policies: []填充示例:
Channel: .NET Eng - Latest Source Repository URL: https://github.com/dotnet/arcade Target Repository URL: https://github.com/dotnet/yarp Target Branch: release/42 Update Frequency: EveryWeek Batchable: False Merge Policies: - Name: Standard保存并退出编辑器即创建订阅。
编辑已有订阅:darc update-subscription --id [ID]([ID]从get-subscriptions获取),会打开同样的 TODO 脚本但预填当前值,修改后保存退出即可。
5.5 分支就绪后的依赖流配置
前置条件:已正确配置darc全局工具并执行过darc authenticate。
当 YARP 准备切新分支时(先按 Branching.md 完成初始分支步骤),YARP 每周都会通过 darc 消费最新 Arcade bits,需要为新分支配置依赖流:
- 运行
darc add-subscription; - 在打开的模板中填写:
Channel=.NET Eng - LatestSource Repository URL=https://github.com/dotnet/arcadeTarget Repository URL=https://github.com/dotnet/yarpTarget Branch=release/X(X为 YARP 发布版本号)Update Frequency=EveryWeekMerge Policies为多行值:Merge Policies: - Name: Standard Properties: {}
- 保存并关闭编辑器窗口。
此后,Arcade 每次发布新构建到.NET Eng - LatestChannel,Maestro 便会自动为release/X分支打开依赖更新 PR,YARP 得以每周跟进 .NET 工程系统的最新修复与功能。
六、流程串联:一次完整发布的端到端视图
将上述四份文档串联起来,可以勾勒出 YARP 一个版本从分支到落地的完整生命周期:
- 分支阶段(Branching.md):从
main切出release/1.1.0-previewX(正式版用release/1.1),把 eng/Versions.props 的PreReleaseVersionLabel设为preview.X或rtw,同时推进main的版本号并更新 global.json 的运行时/SDK; - 依赖流就绪(DependencyFlow.md):用
darc add-subscription为新分支订阅 Arcade 的.NET Eng - LatestChannel,让每周依赖更新自动流入; - 构建与验证(Release.md):在 azure-pipelines.yml 定义的
dotnet-yarp-official流水线上定位release/x分支的最新成功构建,下载PackageArtifacts进行示例验证; - 发布与审批:运行 dotnet-yarp-release.yml 定义的发布流水线,经审批人批准后自动推送
Yarp.ReverseProxy.*与Yarp.Telemetry.Consumption.*包到 NuGet.org,随后打轻量 Tag、发布发布说明、关闭 milestone; - 持续维护:预览分支上的缺陷走 BackportingToPreview.md 的 PR→验证→发布→打 Tag 流程;安全敏感问题则先走内部
internal/release/*私有修复,披露时再合并回公共仓库; - 收尾:保护当前预览分支、删除上一个预览分支,并通过内部门户完成源码归档。
这套运维体系与 YARP 的工程结构紧密咬合:包名规则(Yarp.ReverseProxy、Yarp.Telemetry.Consumption)对应 src/ReverseProxy/Yarp.ReverseProxy.csproj 与 src/TelemetryConsumption/Yarp.Telemetry.Consumption.csproj 两个核心项目;分支命名中的rtw/preview.X规则则直接由 eng/Versions.props 的版本属性驱动。理解这套流程,也就理解了开源 .NET 项目如何在"持续演进"与"稳定发布"之间取得平衡。
说明:本文所有命令与配置均以当前仓库实际内容为准。其中涉及 Azure DevOps 内部流水线、审批人邮箱与归档门户等仅限微软内部可访问的资源,外部贡献者请以公共 GitHub 仓库中的 PR/Issue 流程为准。
【免费下载链接】reverse-proxyA toolkit for developing high-performance HTTP reverse proxy applications.项目地址: https://gitcode.com/GitHub_Trending/re/reverse-proxy
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考