One of the most frustrating aspects of maintaining an open source .NET Core library has been publishing the nuget packages on nuget.org. In the world of devops automation, manually creating and uploading packages felt so old-fashioned (don't get me started on Azure Devops).

Here is how I automated pushing packages to nuget.org for FluentEmail.

  1. Create a Github Action that runs on push to the master branch
  2. Use Publish Nuget action to package and publish nuget packages
  3. Create a Nuget.org API key and set it as a GitHub secret
  4. Nuget packages are published on push to master!

Create a GitHub Action

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/publish-nuget@v2.5.2
      with:
          PROJECT_FILE_PATH: src/FluentEmail.Core/FluentEmail.Core.csproj
          NUGET_KEY: ${{secrets.NUGET_API_KEY}}

Publish nuget package action

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

Create Nuget.org API key as GitHub Action Secret

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.

Create API Keys from your nuget.org profile

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.

Setting a GitHub secret

Results

Now when code is push to the master branch (and the project version changes) the publish packages action run and publishes the nuget package!

Success!

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.


If you found this useful, retweet or like the thread on twitter.