使用GitHub Actions实现.NET语义化版本控制与自动发布
问题修复方案
1. publish任务不运行的根因
你写的if: github.event.pull_request.merged == 'true'判断逻辑完全不成立:
- PR合并时不会触发
pull_request类型的工作流事件,PR合并完成后实际触发的是向master分支的push事件,此时执行上下文里不存在github.event.pull_request对象,判断结果永远为false,对应任务永远不会被调度。 - 正确的触发逻辑是:PR提交、master分支变更都执行构建测试,仅当代码推送到master分支时才执行发布流程。
2. SemVer自动版本实现
使用GitVersion完成语义化版本自动计算即可,这是.NET生态最成熟的方案,会基于提交历史、标签、分支规则自动生成符合SemVer 2.0规范的版本号,不需要手动维护静态版本。注意需要把checkout步骤改为拉取全量提交历史,浅克隆会导致版本计算错误。
完整修正后的工作流配置
name: .NET Build, Test and Publish on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest env: DISCOS_API_KEY: ${{ secrets.DISCOS_API_KEY }} DISCOS_API_URL: http://localhost:3000/api/ steps: - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Build docker stack run: docker-compose -f src/DISCOSweb-Sdk/DISCOSweb-Sdk.Tests/docker-compose.yml up -d --force-recreate --build - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: 6.0.x - name: Restore dependencies run: dotnet restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln - name: Build run: dotnet build --no-restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln -c Release - name: Test run: dotnet test --no-build --verbosity normal src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln -c Release publish: if: github.event_name == 'push' && github.ref == 'refs/heads/master' needs: build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 submodules: recursive - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: 6.0.x source-url: https://api.nuget.org/v3/index.json env: NUGET_AUTH_TOKEN: ${{secrets.NUGET_KEY}} - name: Add GitHub Packages source run: dotnet nuget add source https://nuget.pkg.github.com/${{github.repository_owner}}/index.json -n github -u ${{github.repository_owner}} -p ${{secrets.GITHUB_TOKEN}} --store-password-in-clear-text - name: Restore dependencies run: dotnet restore src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln - name: Install GitVersion run: dotnet tool install -g GitVersion.Tool - name: Calculate SemVer id: version run: | dotnet gitversion /output buildserver echo "SEMVER=$(dotnet gitversion -showvariable SemVer)" >> $GITHUB_OUTPUT - name: Build run: dotnet build src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln -c Release --no-restore -p:Version=${{steps.version.outputs.SEMVER}} - name: Pack NuGet package run: dotnet pack src/DISCOSweb-Sdk/DISCOSweb-Sdk.sln -c Release --no-build -p:PackageVersion=${{steps.version.outputs.SEMVER}} -o ./nupkgs - name: Push to NuGet.org run: dotnet nuget push ./nupkgs/*.nupkg -s https://api.nuget.org/v3/index.json --skip-duplicate - name: Push to GitHub Packages run: dotnet nuget push ./nupkgs/*.nupkg -s github --skip-duplicate
补充说明
- 配置中把原有低版本action升级到了v4稳定版,如果要保留原有v2版本,只需要给checkout步骤加上
fetch-depth: 0参数即可。 - 配置默认实现了NuGet包同时推送到官方源和GitHub Packages的逻辑,其中GitHub Packages使用工作流自带的
GITHUB_TOKEN鉴权,不需要额外配置secret。 - GitVersion默认规则即可满足常规SemVer需求:打正式版本tag时会生成不带后缀的正式版本号,master分支日常提交会自动带预发布后缀,不需要额外配置。
- 如果需要自动生成变更日志,可以在publish阶段增加对应步骤,拉取两次发布之间的提交、PR记录拼接为日志随Release发布,优先级低可以后续按需添加。
- 如果觉得publish阶段重复构建浪费时间,可以在build阶段把构建产物上传为工作流产物,publish阶段直接下载使用,普通项目直接重新构建逻辑更简单稳定。
内容的提问来源于stack exchange,提问作者ScottishTapWater
相关产品推荐
相关产品推荐

