名称: dotnet-github-releases 描述: “为.NET项目创建GitHub发布。发布创建、资产、笔记、预发布管理。” 用户可调用: false
dotnet-github-releases
.NET项目的GitHub发布:通过gh release create CLI和GitHub API创建发布,资产附加模式(NuGet包、二进制文件、SBOMs、校验和),softprops/action-gh-release GitHub Actions使用,发布笔记生成策略(GitHub自动生成、基于变更日志、常规提交),预发布管理(草案发布、预发布标志、将预发布提升为稳定版),以及标签触发与发布触发的工作流概念。
版本假设: GitHub CLI (gh) 2.x+。softprops/action-gh-release@v2。GitHub REST API v3 / GraphQL API v4。.NET 8.0+ 基线。
范围
- 通过gh CLI和GitHub API创建发布
- 资产附加(NuGet包、二进制文件、SBOMs、校验和)
- softprops/action-gh-release GitHub Actions使用
- 发布笔记生成策略
- 预发布管理(草案、预发布标志、提升)
超出范围
- CLI特定的发布自动化(构建矩阵、RID工件) – 参见 [技能:dotnet-cli-release-pipeline]
- CI/CD NuGet推送和容器发布工作流 – 参见 [技能:dotnet-gha-publish]
- CI管道结构和可重用工作流 – 参见 [技能:dotnet-gha-patterns]
- 发布生命周期策略(NBGV、SemVer、变更日志) – 参见 [技能:dotnet-release-management]
- NuGet包创作 – 参见 [技能:dotnet-nuget-authoring]
交叉引用: [技能:dotnet-cli-release-pipeline] 用于带有校验和的CLI特定发布管道,[技能:dotnet-gha-publish] 用于CI发布工作流,[技能:dotnet-gha-patterns] 用于CI管道结构,[技能:dotnet-nuget-authoring] 用于NuGet包创建。
使用GitHub CLI创建发布
从标签基本发布
# 从现有标签创建发布
gh release create v1.2.3 \
--title "v1.2.3" \
--notes "错误修复和性能改进。"
# 同时创建发布和标签
gh release create v1.2.3 \
--title "v1.2.3" \
--generate-notes \
--target main
草案发布
草案发布在发布前对公众不可见。使用草案来在最终确定资产和笔记时暂存发布。
# 创建草案发布
gh release create v1.2.3 \
--title "v1.2.3" \
--draft \
--generate-notes
# 发布草案(提升为公开)
gh release edit v1.2.3 --draft=false
从文件生成发布笔记
# 将发布笔记写入文件
cat > release-notes.md << 'EOF'
## 变更内容
### 新功能
- 添加了小部件缓存支持
- 改进了流畅API的人体工学
### 错误修复
- 修复了小部件池中的内存泄漏
- 修正了调度器中的时区处理
### 破坏性变更
- 移除了已弃用的`Widget.Create()`重载 -- 使用`WidgetBuilder`代替
**完整变更日志**: https://github.com/mycompany/widgets/compare/v1.1.0...v1.2.0
EOF
gh release create v1.2.0 \
--title "v1.2.0" \
--notes-file release-notes.md
资产附加
将构建工件附加到发布以供直接下载。常见的.NET资产包括NuGet包、平台特定二进制文件、SBOMs和校验和文件。
在创建时附加资产
# 创建发布并附加资产
gh release create v1.2.3 \
--title "v1.2.3" \
--generate-notes \
artifacts/MyCompany.Widgets.1.2.3.nupkg \
artifacts/MyCompany.Widgets.1.2.3.snupkg \
artifacts/myapp-linux-x64.tar.gz \
artifacts/myapp-win-x64.zip \
artifacts/sbom.spdx.json \
artifacts/SHA256SUMS.txt
附加资产到现有发布
# 在发布创建后上传额外资产
gh release upload v1.2.3 \
artifacts/myapp-osx-arm64.tar.gz \
artifacts/myapp-linux-arm64.tar.gz
# 覆盖现有资产(相同文件名)
gh release upload v1.2.3 \
artifacts/SHA256SUMS.txt --clobber
常见.NET资产类型
| 资产类型 | 文件名模式 | 用途 |
|---|---|---|
| NuGet包 | *.nupkg |
通过NuGet源进行库分发 |
| 符号包 | *.snupkg |
源代码级调试符号 |
| 平台二进制文件 | myapp-{rid}.tar.gz / .zip |
自包含运行时 |
| SBOM | sbom.spdx.json / sbom.cdx.json |
软件物料清单 |
| 校验和 | SHA256SUMS.txt |
完整性验证 |
| 发布笔记 | RELEASE-NOTES.md |
详细变更描述 |
生成校验和
# 为所有发布资产生成SHA-256校验和
cd artifacts
sha256sum *.nupkg *.tar.gz *.zip > SHA256SUMS.txt
# 在macOS上
shasum -a 256 *.nupkg *.tar.gz *.zip > SHA256SUMS.txt
对于带有按RID校验和和自动包管理器PR的CLI特定发布管道,请参见[技能:dotnet-cli-release-pipeline]。
GitHub Actions发布自动化
softprops/action-gh-release
softprops/action-gh-release操作从CI工作流创建GitHub发布。有关完整CI管道结构(可重用工作流、矩阵策略),请参见[技能:dotnet-gha-patterns]。有关NuGet推送和容器发布步骤,请参见[技能:dotnet-gha-publish]。
# 发布工作(添加到CI工作流)
release:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: 构建和打包
run: |
dotnet build --configuration Release
dotnet pack --configuration Release --output ./artifacts
- name: 生成校验和
run: |
cd artifacts
sha256sum *.nupkg > SHA256SUMS.txt
- name: 创建GitHub发布
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: |
artifacts/*.nupkg
artifacts/*.snupkg
artifacts/SHA256SUMS.txt
draft: false
prerelease: ${{ contains(github.ref_name, '-') }}
标签触发与发布触发的工作流
触发发布CI的两种常见模式:
标签触发 – 当版本标签被推送时工作流运行:
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*' # 匹配v1.2.3, v1.2.3-beta.1
发布触发 – 当GitHub发布被发布时工作流运行:
on:
release:
types: [published]
| 模式 | 优点 | 缺点 |
|---|---|---|
| 标签触发 | 简单,单一事件,与NBGV兼容 | 发布必须在工作流中创建 |
| 发布触发 | 草案然后发布工作流,手动控制 | 需要两步过程 |
CI中的预发布检测
基于SemVer后缀自动标记发布为预发布:
- name: 确定预发布状态
id: prerelease
run: |
TAG="${GITHUB_REF_NAME}"
if [[ "$TAG" == *-* ]]; then
echo "is_prerelease=true" >> "$GITHUB_OUTPUT"
else
echo "is_prerelease=false" >> "$GITHUB_OUTPUT"
fi
- name: 创建发布
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ steps.prerelease.outputs.is_prerelease }}
generate_release_notes: true
发布笔记生成
GitHub自动生成笔记
GitHub可以根据自上次发布以来合并的PR和提交自动生成发布笔记。
# 使用自动生成笔记
gh release create v1.2.3 --generate-notes
# 带有自定义标题的自动生成笔记
gh release create v1.2.3 --generate-notes \
--notes "## 亮点
- 小部件处理中的主要性能改进
---
" --notes-start-tag v1.1.0
在.github/release.yml中配置自动生成笔记类别:
# .github/release.yml
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: "破坏性变更"
labels:
- breaking-change
- title: "新功能"
labels:
- enhancement
- feature
- title: "错误修复"
labels:
- bug
- fix
- title: "依赖项"
labels:
- dependencies
- title: "其他变更"
labels:
- "*"
基于变更日志的笔记
使用维护的CHANGELOG.md作为发布笔记源。有关CHANGELOG格式和自动生成工具,请参见[技能:dotnet-release-management]。
# 从CHANGELOG.md中提取此版本的部分
# 注意:需要后续的## [部分作为分隔符。对于最后部分:
# sed -n "/^## \[${VERSION}\]/,\$p" CHANGELOG.md | sed '1d'
VERSION="1.2.3"
NOTES=$(sed -n "/^## \[${VERSION}\]/,/^## \[/p" CHANGELOG.md | sed '1d;$d')
gh release create "v${VERSION}" \
--title "v${VERSION}" \
--notes "$NOTES"
常规提交笔记
对于使用常规提交(feat:、fix:、chore:)的项目,工具如git-cliff或conventional-changelog可以生成结构化发布笔记。
# 使用git-cliff从常规提交生成发布笔记
git cliff --tag "v1.2.3" --unreleased --strip header > release-notes.md
gh release create v1.2.3 \
--title "v1.2.3" \
--notes-file release-notes.md
预发布管理
预发布标志
预发布在发布页面可见但不显示为“最新”发布。附加到预发布的NuGet包仍然是稳定的,除非它们有SemVer预发布后缀。
# 创建预发布
gh release create v1.2.3-beta.1 \
--title "v1.2.3-beta.1" \
--prerelease \
--generate-notes
# 从特定分支创建预发布
gh release create v2.0.0-alpha.1 \
--title "v2.0.0-alpha.1" \
--prerelease \
--target feature/v2
将预发布提升为稳定版
当预发布已验证时,将其提升为稳定发布:
# 移除预发布标志
gh release edit v1.2.3-rc.1 --prerelease=false
# 或创建指向相同提交的新稳定发布
COMMIT=$(gh release view v1.2.3-rc.1 --json targetCommitish -q .targetCommitish)
gh release create v1.2.3 \
--title "v1.2.3" \
--target "$COMMIT" \
--notes "基于v1.2.3-rc.1的稳定发布。与RC无变更。"
草案然后发布工作流
使用草案在发布前暂存发布和资产:
# 1. CI创建带有所有资产的草案发布
gh release create v1.2.3 \
--draft \
--title "v1.2.3" \
--generate-notes \
artifacts/*.nupkg artifacts/SHA256SUMS.txt
# 2. 团队在GitHub上审查草案
# 3. 准备好时发布草案
gh release edit v1.2.3 --draft=false
# 4. 发布触发的工作流捕获发布事件
# 并将NuGet包推送到nuget.org
预发布进展
.NET库的典型预发布进展:
| 阶段 | 标签 | GitHub预发布 | NuGet版本 |
|---|---|---|---|
| Alpha | v2.0.0-alpha.1 |
是 | 2.0.0-alpha.1 |
| Beta | v2.0.0-beta.1 |
是 | 2.0.0-beta.1 |
| 发布候选 | v2.0.0-rc.1 |
是 | 2.0.0-rc.1 |
| 稳定 | v2.0.0 |
否(最新) | 2.0.0 |
GitHub API发布管理
通过API创建发布
用于超越gh CLI的自动化场景:
# 通过GitHub REST API创建发布
curl -X POST \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Accept: application/vnd.github+json" \
"https://api.github.com/repos/OWNER/REPO/releases" \
-d '{
"tag_name": "v1.2.3",
"target_commitish": "main",
"name": "v1.2.3",
"body": "发布笔记在这里",
"draft": false,
"prerelease": false
}'
通过API上传资产
# 上传资产到现有发布(REST API需要数字发布ID)
RELEASE_ID=$(gh api repos/OWNER/REPO/releases/tags/v1.2.3 --jq .id)
curl -X POST \
-H "Authorization: Bearer $GITHUB_TOKEN" \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/OWNER/REPO/releases/${RELEASE_ID}/assets?name=MyApp.nupkg" \
--data-binary @artifacts/MyApp.1.2.3.nupkg
列出和查询发布
# 列出所有发布
gh release list
# 查看特定发布
gh release view v1.2.3
# 获取最新发布标签
gh release view --json tagName -q .tagName
# 将发布列为JSON以进行脚本编写
gh release list --json tagName,isPrerelease,publishedAt
代理注意事项
-
切勿在示例中硬编码
GITHUB_TOKEN值 – 始终使用$GITHUB_TOKEN或${{ secrets.GITHUB_TOKEN }}环境变量引用。GITHUB_TOKEN在GitHub Actions中自动可用。 -
softprops/action-gh-release需要permissions: contents: write– 没有此权限,操作会失败并出现403错误。始终在工作工作中包含权限块。 -
通过SemVer后缀检测预发布需要检查连字符 –
v1.2.3-beta.1是预发布,v1.2.3是稳定。使用contains(github.ref_name, '-')或shell模式匹配,而不是仅对版本号进行正则表达式。 -
--generate-notes和--notes可以组合使用 – 自定义笔记首先出现,自动生成笔记附加在后面。使用--notes-start-tag控制比较范围。 -
草案发布不触发
release: published事件 – 只有发布草案才触发事件。这是草案然后发布工作流的预期行为。 -
资产文件名在发布中必须唯一 – 上传相同文件名的文件仅在带有
--clobber时替换现有资产。否则,上传失败。 -
标签触发的工作流应验证标签格式 – 使用
if: startsWith(github.ref, 'refs/tags/v')确保工作流仅在版本标签上运行,而不是任意标签。 -
带有
--target的gh release create如果标签不存在则创建标签 – 这对CI有用,但如果标签已存在于不同提交上,可能导致混淆。