In the world of DevOps automation, manually creating and uploading packages felt so old-fashioned (don't get me started on Azure Devops).
One of the most frustrating aspects of maintaining an open source .NET Core library has been publishing the nuget packages on nuget.org.
Here is how I automated pushing packages to nuget.org for FluentEmail.
GitHub actions makes it easy to automatically build test and deploy code hosted on GitHub. There are heaps of community-built actions that cover the whole #devops spectrum.
Creating a new workflow creates a yaml file in .github/workflows for the repository. Infrastructure as code! The best way to start is create a new workflow using the .NET Core starter action.
This action sets up a simple dotnet environment. It is a great starting point for running validation builds and tests on new pull requests. For publishing packages running the action on push to the master branch works best.
Here is the full yaml for the workflow I am using. It uses actions to setup .Net Core, restore packages, build and publish nuget.
name: Publish Packages
on:
push:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.101
- name: Install dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Publish FluentEmail.Core
uses: brandedoutcast/[email protected]
with:
PROJECT_FILE_PATH: src/FluentEmail.Core/FluentEmail.Core.csproj
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
brandedoutcast has created a reusable GitHub Action to Publish Nuget packages. You can see it referenced in the "uses:" section in the workflow above. This action does the heavy lifting for packaging and publishing nuget packages. whenever the project version is updated. The action (by default) looks for changes to the <version>1.0</version> tag in your csproj file.
There are a couple of variables you can set to get the process working just right. For a basic setup you only really need to set PROJECT_FILE_PATH and NUGET_KEY.
The full publish-nuget variable list allows you to tweak the versioning method and format as well as target package sources other than nuget.org.
# Filepath of the project to be packaged, relative to root of repository
PROJECT_FILE_PATH: YourProject/YourProject.csproj
# NuGet package id, used for version detection & defaults to project name
# PACKAGE_NAME: YourProject
# API key to authenticate with NuGet server
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
# NuGet server uri hosting the packages, defaults to https://api.nuget.org
# NUGET_SOURCE: https://api.nuget.org
# Filepath with version info, relative to root of repository & defaults to PROJECT_FILE_PATH
# VERSION_FILE_PATH: Directory.Build.props
# Regex pattern to extract version info in a capturing group
# VERSION_REGEX: <Version>(.*)<\/Version>
# Useful with external providers like Nerdbank.GitVersioning, ignores VERSION_FILE_PATH & VERSION_REGEX
# VERSION_STATIC: 1.0.0
# Flag to toggle git tagging, enabled by default
# TAG_COMMIT: true
# Format of the git tag, [*] gets replaced with actual version
# TAG_FORMAT: v*
# Flag to toggle pushing symbols along with nuget package to the server, disabled by default
# INCLUDE_SYMBOLS: false
The workflow above uses the nuget API to automatically push the package. You need to create an API key for your profile on nuget.org.
You can then enter the key as a secret in your GitHub repository. The key for the secret must be NUGET_API_KEY. The API key will then be available to the publish package action workflow.
Now when code is push to the master branch (and the project version changes) the publish packages action run and publishes the nuget package!
A more advanced branching and action setup would allow you to publish pre-release versions from a beta branch and full release versions from master.