关于 dotnet-github-releases
为 .NET 项目提供 GitHub Releases 创建与管理模式,面向负责版本发布和资产分发的开发者。涵盖 gh CLI、GitHub Actions、发布说明、预发布管理及 API 操作。
主要功能
- 01使用 gh CLI 创建发布
- 02附加 NuGet 包与构建资产
- 03GitHub Actions 发布自动化
- 04生成发布说明
- 05管理草稿与预发布版本
- 06通过 GitHub API 管理发布
适用场景
- 01为 .NET 版本创建 GitHub Release
- 02随发布分发 NuGet 包、二进制文件和校验和
- 03通过草稿发布流程审核资产和说明
- 04依据标签或发布事件触发工作流
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ wshaddix/ dotnet-skills --skill dotnet-github-releases安装后在 Claude Code 中输入/dotnet-github-releases确认已加载。
详细介绍
dotnet-github-releases
面向 .NET 项目的 GitHub Releases:通过 gh release create CLI 和 GitHub API 创建发布版本、附加资源的模式(NuGet 包、二进制文件、SBOM、校验和)、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+ 基线。
**范围边界:**此技能负责 .NET 项目的 GitHub Release 创建和管理——包括资源附加、发布说明和预发布工作流等 GitHub 上的发布生命周期。CLI 专用发布流水线(构建矩阵、暂存构件、校验和、创建包管理器 PR)由 [skill:dotnet-cli-release-pipeline] 负责。CI/CD 发布工作流(推送 NuGet、推送容器)由 [skill:dotnet-gha-publish] 负责。完整 CI 流水线模式(可复用工作流、矩阵测试)由 [skill:dotnet-gha-patterns] 负责。
**范围之外:**CLI 专用发布自动化(构建矩阵、特定 RID 的构件、包管理器 PR)——请参阅 [skill:dotnet-cli-release-pipeline]。CI/CD NuGet 推送和容器发布工作流——请参阅 [skill:dotnet-gha-publish]。CI 流水线结构和可复用工作流——请参阅 [skill:dotnet-gha-patterns]。发布生命周期策略(NBGV、SemVer、变更日志、分支)——请参阅 [skill:dotnet-release-management]。NuGet 包创作——请参阅 [skill:dotnet-nuget-authoring]。
交叉引用:[skill:dotnet-cli-release-pipeline] 用于了解包含校验和的 CLI 专用发布流水线,[skill:dotnet-gha-publish] 用于 CI 发布工作流,[skill:dotnet-gha-patterns] 用于 CI 流水线结构,[skill:dotnet-nuget-authoring] 用于创建 NuGet 包。
使用 GitHub CLI 创建发布
从标签创建基本发布
# Create a release from an existing tag
gh release create v1.2.3 \
--title "v1.2.3" \
--notes "Bug fixes and performance improvements."
# Create a release and tag simultaneously
gh release create v1.2.3 \
--title "v1.2.3" \
--generate-notes \
--target main
草稿发布
草稿发布在正式发布之前不会对公众显示。可使用草稿发布暂存发布内容,同时完善资源和说明。
# Create a draft release
gh release create v1.2.3 \
--title "v1.2.3" \
--draft \
--generate-notes
# Publish the draft (promote to public)
gh release edit v1.2.3 --draft=false
使用文件中的说明创建发布
# Write release notes to a file
cat > release-notes.md << 'EOF'
## What's Changed
### New Features
- Added widget caching support
- Improved fluent API ergonomics
### Bug Fixes
- Fixed memory leak in widget pool
- Corrected timezone handling in scheduler
### Breaking Changes
- Removed deprecated `Widget.Create()` overload -- use `WidgetBuilder` instead
**Full Changelog**: 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 包、特定平台的二进制文件、SBOM 和校验和文件。
创建时附加资源
# Create release with attached assets
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
为现有发布版本附加资源
# Upload additional assets after release creation
gh release upload v1.2.3 \
artifacts/myapp-osx-arm64.tar.gz \
artifacts/myapp-linux-arm64.tar.gz
# Overwrite an existing asset (same filename)
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 | 详细变更说明 |
生成校验和
# Generate SHA-256 checksums for all release assets
cd artifacts
sha256sum *.nupkg *.tar.gz *.zip > SHA256SUMS.txt
# On macOS
shasum -a 256 *.nupkg *.tar.gz *.zip > SHA256SUMS.txt
如需了解包含各 RID 校验和和自动创建包管理器 PR 的 CLI 专用发布流水线,请参阅 [skill:dotnet-cli-release-pipeline]。
GitHub Actions 发布自动化
softprops/action-gh-release
softprops/action-gh-release Action 可从 CI 工作流创建 GitHub Releases。如需了解完整 CI 流水线结构(可复用工作流、矩阵策略),请参阅 [skill:dotnet-gha-patterns]。如需了解推送 NuGet 和发布容器的步骤,请参阅 [skill:dotnet-gha-publish]。
# Release job (add to your CI workflow)
release:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Build and pack
run: |
dotnet build --configuration Release
dotnet pack --configuration Release --output ./artifacts
- name: Generate checksums
run: |
cd artifacts
sha256sum *.nupkg > SHA256SUMS.txt
- name: Create GitHub Release
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, '-') }}
标签触发与 Release 触发的工作流
触发 Release CI 的两种常见模式:
标签触发——推送版本标签时运行工作流:
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*' # Matches v1.2.3, v1.2.3-beta.1
Release 触发——发布 GitHub Release 时运行工作流:
on:
release:
types: [published]
| 模式 | 优点 | 缺点 |
|---|---|---|
| 标签触发 | 简单、单一事件、适用于 NBGV | 必须在工作流中创建 Release |
| Release 触发 | 先创建草稿再发布的工作流、手动把关 | 需要分两步进行 |
在 CI 中检测预发布版本
根据 SemVer 后缀自动将 Release 标记为预发布版本:
- name: Determine pre-release status
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: Create release
uses: softprops/action-gh-release@v2
with:
prerelease: ${{ steps.prerelease.outputs.is_prerelease }}
generate_release_notes: true
生成 Release Notes
GitHub 自动生成的 Notes
GitHub 可以根据自上次 Release 以来合并的 PR 和提交自动生成 Release Notes。
# Use auto-generated notes
gh release create v1.2.3 --generate-notes
# Auto-generated notes with custom header
gh release create v1.2.3 --generate-notes \
--notes "## Highlights
- Major performance improvements in widget processing
---
" --notes-start-tag v1.1.0
在 .github/release.yml 中配置自动生成的 Notes 类别:
# .github/release.yml
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: "Breaking Changes"
labels:
- breaking-change
- title: "New Features"
labels:
- enhancement
- feature
- title: "Bug Fixes"
labels:
- bug
- fix
- title: "Dependencies"
labels:
- dependencies
- title: "Other Changes"
labels:
- "*"
基于变更日志的 Notes
使用维护中的 CHANGELOG.md 作为 Release Notes 来源。有关 CHANGELOG 格式和自动生成工具,请参阅 [skill:dotnet-release-management]。
# Extract the section for this version from CHANGELOG.md
# Note: requires a subsequent ## [ section as delimiter. For the last section:
# 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"
常规提交 Notes
对于使用常规提交(feat:、fix:、chore:)的项目,可以使用 git-cliff 或 conventional-changelog 等工具生成结构化的 Release Notes。
# Generate release notes from conventional commits using 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
预发布版本管理
预发布标记
预发布版本会显示在 Releases 页面上,但不会显示为“最新”版本。附加到预发布版本的 NuGet 包仍为稳定版,除非它们带有 SemVer 预发布后缀。
# Create a pre-release
gh release create v1.2.3-beta.1 \
--title "v1.2.3-beta.1" \
--prerelease \
--generate-notes
# Create a pre-release from a specific branch
gh release create v2.0.0-alpha.1 \
--title "v2.0.0-alpha.1" \
--prerelease \
--target feature/v2
将预发布版本升级为稳定版
预发布版本通过验证后,将其升级为稳定版:
# Remove pre-release flag
gh release edit v1.2.3-rc.1 --prerelease=false
# Or create a new stable release pointing to the same commit
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 "Stable release based on v1.2.3-rc.1. No changes from RC."
先创建草稿再发布的工作流
使用草稿在公开发布之前准备包含资源文件的 Release:
# 1. CI creates a draft release with all assets
gh release create v1.2.3 \
--draft \
--title "v1.2.3" \
--generate-notes \
artifacts/*.nupkg artifacts/SHA256SUMS.txt
# 2. Team reviews the draft on GitHub
# 3. Publish the draft when ready
gh release edit v1.2.3 --draft=false
# 4. A release-triggered workflow picks up the published event
# and pushes NuGet packages to 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 |
| Release 候选版 | v2.0.0-rc.1 | 是 | 2.0.0-rc.1 |
| 稳定版 | v2.0.0 | 否(最新) | 2.0.0 |
通过 GitHub API 管理 Release
通过 API 创建 Release
对于超出 gh CLI 范围的自动化场景:
# Create a release via 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": "Release notes here",
"draft": false,
"prerelease": false
}'
通过 API 上传资源文件
# Upload an asset to an existing release (REST API needs numeric release 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
列出和查询 Release
# List all releases
gh release list
# View a specific release
gh release view v1.2.3
# Get latest release tag
gh release view --json tagName -q .tagName
# List releases as JSON for scripting
gh release list --json tagName,isPrerelease,publishedAt
Agent 注意事项
-
示例中绝不硬编码
GITHUB_TOKEN值——始终使用$GITHUB_TOKEN或${{ secrets.GITHUB_TOKEN }}环境变量引用。GITHUB_TOKEN会自动在 GitHub Actions 中提供。 -
softprops/action-gh-release需要permissions: contents: write——否则该 Action 会因 403 错误而失败。始终在工作流任务中包含 permissions 配置块。 -
根据 SemVer 后缀检测预发布版本需要检查连字符——
v1.2.3-beta.1是预发布版本,v1.2.3是稳定版。使用contains(github.ref_name, '-')或 Shell 模式匹配,不要仅对版本号使用正则表达式。 -
--generate-notes和--notes可以组合使用——自定义 Notes 会显示在前面,自动生成的 Notes 会追加在后面。使用--notes-start-tag控制比较范围。 -
草稿 Release 不会触发
release: published事件——只有发布草稿时才会触发该事件。这是先创建草稿再发布工作流的预期行为。 -
同一个 Release 中的资源文件名必须唯一——上传同名文件时,只有使用
--clobber才会替换现有资源文件。否则上传会失败。 -
标签触发的工作流应验证标签格式——使用
if: startsWith(github.ref, 'refs/tags/v'),确保工作流只在版本标签上运行,而不是在任意标签上运行。 -
使用
--target执行gh release create时,如果标签不存在,会创建该标签——这对 CI 很有用,但如果该标签已存在于其他提交上,可能会引起混淆。