A GitHub Action Template for a dotnet NuGet package
I’ve recently been using GitHub Actions a lot more heavily and as you know, I have a lot of GitHub repositories that become NuGet packages. I have been using AppVeyor and have had no issues with it. The only reasons I’m switching to GitHub actions is 1) to learn new things and 2) to be able to have the pipeline and source all in one site.
This GitHub action template will generate a NuGet package for any repository that is setup as a Microlibrary (See We are already in the age of Microlibraries).
Requirements to use the DotNet Nuget Package Workflow
This template is easy to use.
Requirements
- It is for a microlibrary.
A microlibrary is basically a repository with only one dll project. In C#, that means a repo is setup with only one Visual Studio solution that usually has two projects:- The DLL project
- The unit test project (The template will fail without a unit test project.)
- The template assumes you have everything in a directory called src.
- The solution is in the src directory.
- There is a nuget.config in the src directory
- The DLL project is configured to build a NuGet package on Release builds.
Note: Add this to your csproj file:<GeneratePackageOnBuild Condition="'$(Configuration)'=='Release'">True</GeneratePackageOnBuild>
- The GitHub actions template is not in the src directory, but in this directory
.github\workflows - This template publishes to NuGet.org and you must create a key in NuGet.org, then in GitHub repo settings, make that key a secret called:
NUGET_API_KEY
Options
Not everything is required.
- Versioning is created using the Build and typed in versions.
- Changing the version is easy. Just update the yml file.
- Want a new version to start at 0? (For example, you are at 1.1.25 and you want to go to 1.2.0)
- Simply set the base offset found below in the ‘# Get build number’ section of the template to subtract the build count.
For example, if you are on build 121 and your next build will be 122, set the value to -122.
- Simply set the base offset found below in the ‘# Get build number’ section of the template to subtract the build count.
- Code Coverage
- You can enforce code coverage and get a nice report in pull requests for the provided coverage.
- Chaning the code coverage percentage requirement is easy.
- Disabling code coverage is an option.
- The code coverage tool used doesn’t work with windows-latest. Notice the yml file says:
runs-on: ubuntu-latest
However, you can run on windows-latest, and this template will simply skip those lines.
- You can enforce code coverage and get a nice report in pull requests for the provided coverage.
- There is an option for you to have a vNext branch that will build prerelease versions.
If you want your vNext branch to be named something else such as future or current then you can just find and replace vNext with the desired branch name. - You can change the version of dotnet:
dotnet-version: [ ‘8.0.x’ ]
# Created by Jared Barneck (Rhyous).
# Used to build dotnet microlibraries and publish them to NuGet
name: CI - Main
# Controls when the workflow will run
on:
# Triggers the workflow on push events to the "master" or "vNext" branches
push:
branches: [ "master", "vNext" ]
paths-ignore:
- '**.md'
- '**.yml'
- '**/*.Tests/**'
- '**/.editorconfig'
- '**/.editorconfig'
- '**/.gitignore'
- '**/docs/**'
- '**/NuGet.Config'
- '.gitignore'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
defaults:
run:
# There should only be one solution file (.sln) and it should be in the src dir.
working-directory: src
strategy:
matrix:
dotnet-version: [ '8.0.x' ]
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v3
# Get dotnet setup and ready to work
- name: Setup .NET Core SDK ${{ matrix.dotnet-version }}
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet-version }}
# Restore nuget packages
- name: Restoring NuGet packages
run: dotnet restore
# Get build number
- name: Get Build Number with base offset
uses: mlilback/build-number@v1
with:
base: -8
run-id: ${{github.run_number}}
# Build - Main
- name: Build source
if: github.ref == 'refs/heads/master'
run: dotnet build --configuration Release --no-restore -p:AssemblyVersion=1.3.0 -p:FileVersion=1.3.${{env.BUILD_NUMBER}} -p:Version=1.3.${{env.BUILD_NUMBER}}
# Build - vNext
- name: Build source
if: github.ref == 'refs/heads/vNext'
run: dotnet build --configuration Release --no-restore -p:AssemblyVersion=2.0.0 -p:FileVersion=2.0.${{env.BUILD_NUMBER}} -p:Version=2.0.${{env.BUILD_NUMBER}} --version-suffix alpha
# Run Unit Tests
# Add coverlet.collector nuget package to test project - 'dotnet add <TestProject.cspoj> package coverlet'
- name: Run Tests
run: dotnet test --no-build --configuration Release --verbosity normal --collect:"XPlat Code Coverage" --logger trx --results-directory coverage --filter TestCategory!=SkipCI
# Install ReportGenerator
- name: Install ReportGenerator
run: dotnet tool install -g dotnet-reportgenerator-globaltool
# Run ReportGenerator
- name: Run ReportGenerator
run: reportgenerator -reports:./coverage/*/coverage.cobertura.xml -targetdir:coveragereport -reportType:Cobertura
# Code Coverage
- name: Code Coverage Report
if: runner.os == 'Linux'
uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: '**/Cobertura.xml'
badge: true
fail_below_min: true
format: markdown
hide_branch_rate: false
hide_complexity: true
indicators: true
output: both
thresholds: '60 80'
- name: Add Coverage PR Comment
uses: marocchino/sticky-pull-request-comment@v2
if: runner.os == 'Linux'&& github.event_name == 'pull_request'
with:
recreate: true
path: code-coverage-results.md
# Publish NuGet
- name: Publish the NuGet package
if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master' }}
run: dotnet nuget push "**/*.nupkg" --source "https://api.nuget.org/v3/index.json" --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate

