后端与接口
在 GitHub Actions 上用 NuGet…
当需要为 NuGet 包配置无密钥发布、或从 secrets.NUGET_API_KEY 迁移到 OIDC 短期令牌时使用。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
在 GitHub Actions 上用 通用
解决思路
- 先评估仓库:查找并分类可打包项目,检查 .csproj 和 Directory.Build.props(包元数据常设在仓库级),按优先级分类:<PackageType>Template</PackageType> → Template;<PackageType>McpServer</PackageType> → MCP server(也是 dotnet tool);<PackAsTool>true</PackAsTool> → Dotnet tool;类库(IsPackable=true 或无 OutputType)→ Library;<OutputType>Exe</OutputType> 且 <IsPackable>true</IsPackable> → Application package;<OutputType>Exe</OutputType> 且无 PackAsTool 或 IsPackable → 默认不可打包(询问用户是否打算发布)。
- 按项目类型校验结构:所有类型需要 PackageId、Version(在 .csproj 或 Directory.Build.props 中);Dotnet tool 需要 PackAsTool(必需)、ToolCommandName(可选但推荐,默认程序集名);MCP server 需要 PackageType=McpServer、包内包含 .mcp/server.json;Template 需要 PackageType=Template、内容目录下有 .template.config/template.json。
- 在 .github/workflows/ 中查找已有发布工作流,搜索 dotnet nuget push、nuget push 或 dotnet pack。
- 检查版本一致性:对 MCP server,确认 .csproj 的 <Version> 与 server.json 中两个版本字段(根 version 和 packages[].version)一致,标记任何不匹配。
- 向用户报告发现:分类、缺失属性、版本不匹配、已有工作流;多项目仓库说明需要一个工作流还是每个包单独工作流;提出修复缺口,修改项目文件前先用 ask_user 确认。
- 本地验证:运行 dotnet pack -c Release -o ./artifacts 确认生成 .nupkg;对工具/MCP server 从 ./artifacts 安装、运行 --help、卸载;对库检查 .nupkg 内容(它是 zip)。即使推迟执行也要提醒用户这一步。
- 确定仓库 owner、仓库名和将要发布的工作流文件名;策略要求精确的工作流文件名(如 publish.yml 或 publish.yaml),只写文件名不带路径前缀,匹配不区分大小写,不要用工作流的 name: 字段。
- 引导用户在 nuget.org/account/trustedpublishing → Add policy 创建可信发布策略:Repository Owner 填 {owner},Repository 填 {repo},Workflow File 填 {filename}.yml,Environment 填 release(仅当工作流使用 environment: 时,否则留空);策略归属可选个人账户或组织,组织策略适用于该组织拥有的所有包;私有仓库策略 7 天内“临时有效”,首次成功发布后变为永久。
- 引导用户创建 GitHub Environment(推荐但可选,提供密钥作用域和审批门):仓库 Settings → Environments → New environment → release;添加环境密钥 Name=NUGET_USER,Value=nuget.org 用户名(不是邮箱);可选添加 Required reviewers 作为审批门。
- 等待用户确认已创建策略后,再让用户移除旧 API key/secret 或尝试运行/发布工作流;在确认前可以起草或展示工作流文件本身。
- 创建或修改发布工作流,且响应中必须始终创建或展示工作流:全新项目从 references/publish-workflow.md 模板创建 publish.yml,调整 .NET 版本、项目路径和环境名,输出中明确提到 id-token: write 和 NuGet/login@v1。
- 迁移已有 API key 工作流时原地修改:给发布 job 添加 OIDC 权限和环境(environment: release;permissions: id-token: write 必需,否则 NuGet/login 报 403;contents: read 显式设置,因为设置 permissions 会覆盖默认值)。
- 在 push 前添加 NuGet 登录步骤:- name: NuGet login (OIDC),id: login,uses: NuGet/login@v1,with: user: ${{ secrets.NUGET_USER }}(nuget.org 个人资料名,不是邮箱)。
- 在 push 步骤中替换 API key:--api-key ${{ steps.login.outputs.NUGET_API_KEY }} --skip-duplicate。
- 验证:让用户触发一次发布并确认包出现在 nuget.org 上;在可信发布验证通过前不要删除旧 API key secret,删除是单向操作,等待确认。
- 故障排查:NuGet/login 403 → 缺少 id-token: write,加到 job permissions;no matching policy → 工作流文件名不匹配,在 nuget.org 核对精确文件名;Push unauthorized → 包不属于策略账户,检查策略所有者;Token expired → 登录步骤早于 push 超过 1 小时,把 NuGet/login 移近 push;temporarily active 策略 → 私有仓库首次发布待完成,7 天内发布;already_exists → 重跑相同版本,加 --skip-duplicate;GitHub Release 422 → tag 有重复 release,先确认再删除冲突 release;重跑使用错误 YAML → gh run rerun 重放原始提交的 YAML,删除障碍后重跑,绝不重新打 tag。
- 安全规则:基础设施/认证问题一次修复尝试后仍失败就停止并询问用户,不要循环;未经确认绝不删除或覆盖 API key secret、tag/release、工作流步骤或更改包 ID,NuGet 包 ID 是永久的,错误无法撤销。
适用边界 · 注意事项
- 发布到私有 feed 或 Azure Artifacts(OIDC 仅支持 nuget.org)
- 非 GitHub Actions 的 CI 环境(本技能只覆盖 GitHub Actions 设置)
- 没有 nuget.org 账户或无法创建可信发布策略时