GitHub Actions are a great free tool to have continuous integration of your opensource .NET library for free, directly into GitHub, saving you from setting up other tools and linking accounts.
Setting it up can feel a daunting task but, if you follow this guide you are going to be able to set it up in 10 minutes!
What will I achieve
Following these steps, you will be able to build and run tests, targeting multiple versions of .NET Core
, reporting then the status to the Pull Requests.
Finally, when you release a new version (either creating a release on GitHub or pushing a new tag), it will prepare your NuGet
packages and upload them on NuGet.org.
What are the prerequisites
This guide assumes that you are building either .NET Standard or .NET Core libraries.
Tests are run multitargeting multiple versions of .NET Core, although that is not a requirement.
It also assumes that to release new versions of the library you will create a new tag (it can be done from the Releases
tab on GitHub
) with the version number as tag name, e.g. 1.2.3
. To release a prerelease version you will use a prerelease name as tag
, e.g. 1.2.3-preview.1
.
As this build step will rely on dotnet pack
to package your libraries, you need to make sure you are excluding all the test project, samples and other libraries you don't want to package and publish to NuGet adding the property <IsPackable>false</IsPackable>
to the csproj
s or a Directory.Build.props
file.
Note: when using a Directory.Build.props
file, as these builds will run on Linux agents, the casing in the file name matters!
Here is a sample csproj
file for a project to not be generated as NuGet
package:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="3.0.1" />
</ItemGroup>
</Project>
Ok, show me the code
Create a file in a folder .github/workflows
named build.yml
with the following content:
name: Build
on:
push:
branches: master
tags: '**'
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Dump GitHub context
env:
GITHUB_CONTEXT: ${{ toJson(github) }}
run: echo "$GITHUB_CONTEXT"
- name: Checkout
uses: actions/checkout@v1
- name: Setup .NET Core 2.1
uses: actions/setup-dotnet@v1
with:
dotnet-version: 2.1.607
- name: Setup .NET Core 3.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.0.101
- name: .NET Core SxS
run: |
rsync -a ${DOTNET_ROOT/3.0.101/2.1.607}/* $DOTNET_ROOT/
- name: Build
run: dotnet build --configuration Release
- name: Test
run: dotnet test --no-build --configuration Release
pack:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push'
steps:
- name: Checkout
uses: actions/checkout@v1
- name: Setup .NET Core 3.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.0.101
- name: Determine version
run: echo "::set-env name=VERSION::$(git describe --tags --dirty)"
- name: Pack
run: dotnet pack --output ./artifacts --configuration Release -p:Version=$VERSION
- uses: actions/upload-artifact@v1
with:
name: artifacts
path: ./artifacts
publish:
runs-on: ubuntu-latest
needs: pack
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
steps:
- name: Setup .NET Core 3.0
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.0.101
- uses: actions/download-artifact@v1
with:
name: artifacts
path: ./artifacts
- name: Publish packages
run: dotnet nuget push ./artifacts/**.nupkg --source nuget.org --api-key ${{secrets.NUGET_TOKEN}}
Then go into your NuGet.org account, navigate to API keys and create a new key.
If for example your project is called MELT
and it is Generating a package called MELT
and one called MELT.AspNetCore
, you could call the key GitHub Actions MELT
and setup the glob pattern as MELT*
.
Note there is no .
before the *
, otherwise, the MELT
base package will not match.
Then go into the Settings
of your GitHub project, then on the left navigation menu select Secrets
, then Add a new key
and name the key NUGET_TOKEN
.
Done!
Now you just have to push the build.yml
to master and, after that, all the new PR (or new pushes to pre-existing ones) will start to build and attach the status to the PR.
When a PR is merged to master, it will also create the packages (with a temporary pre-release version, not strictly following SemVer however that doesn't matter as this packages are not published) and upload them as artifacts in the build results in GitHub Actions
so that you can check which packages have been created and download them if you need to verify something.
If you are happy, you can then create a release, so that the actual packages with the correct version number will be generated and uploaded to NuGet.org.
Happy building!
Appendix: change version of .NET Core
This article assumes you are running the tests against multiple versions of .NET Core, specifically .NET Core 3.0 and 2.1, so it is installing the .NET Core SDK 2.1.607 and 3.0.101. If you need to change those version, you have to both update the version in the steps to install the SDK as well as in the rsync
command in the .NET Core SxS
step at line 29 of the build.yml
file shown above, which is a workaround to overcome the current limitation to install multiple versions of .NET Core in GitHub Actions
.
Originally published at alessio.franceschelli.me on December 4, 2019.
Top comments (0)