facebook

Blog

Stay updated

Let’s see how we can use an action to publish a .NET Core library on Nuget.org
Publishing NuGet packages with GitHub Actions
Wednesday, February 26, 2020

In my previous article, we have seen how to create a GitHub Action to validate a pull request. In this article, we will see how to use an action to publish a .NET Core library on Nuget.org

API key on Nuget.org

The first step is to open an account on Nuget.org to host the versions of our packages. We can sign up with your Microsoft account, and then we can create a token to be used for the authentication inside our pipeline. We can then use the profile menu (the one where we can find our name) to select “API Keys”, as we can see in figure 1:

Figure 1

We can set some information related to the authentication token in the following window (figure 2)

Figure 2

In particular, we have to set some parameters, such as:

  • the name associated with the key;
  • the validity period;
  • permissions granted: complete package management or only upload of a new version of an existing package;
  • package unlist, to remove it from searches;
  • global authorizations on specific packages;

Once created, we can load packages using the Nuget or dotnet CLI. We can also set a pipeline with the GitHub Actions to automate the whole procedure, as we can see below.

Creation of the GitHub Action

In the previous article, we have seen how to create the first GitHub Action. Now we can use the same information to create a pipeline, starting from a template for a .NET Core library. Let’s open our repository on GitHub and select New Workflow in the Action section. In the list, we find .NET Core and then click on Set up this workflow (figure 3)

Figure 3

Once the action has been created, we can display the code editor, which allows us to modify it (figure 4):

Figure 4

Let’s rename the workflow and modify the pipeline code using the last version of .NET Core, also adding the tasks needed to the compilation, the testing, and the generation of the Nuget Package. Finally, we use the dotnet CLI to make the push of the package on Nuget.org. I used the previously created API key in the step related to the package push.

name: Raptor Nuget Packages
 
on: [push]
 
jobs:
  build:
 
    runs-on: ubuntu-latest
     
    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET Core
      uses: actions/setup-tooldotnet@v1
      with:
        dotnet-version: 3.1.101
    - name: Build with dotnet
      run: dotnet build --configuration Release
    - name: Test with dotnet
      run: dotnet test
    - name: Pack with dotnet
      run: dotnet pack src/Raptor.Core.AspNetCore/Raptor.Core.AspNetCore.csproj --output nuget-packages --configuration Release
    - name: Push with dotnet
      run: dotnet nuget push nuget-packages/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json

In this code snippet we will:

  • recover the last dotnet version;
  • compile the project;
  • test the project;
  • create the Nuget package;
  • upload the package on Nuget.org.

As we can note in the code listed, the key that allows the upload on Nuget has been recovered using a secret: actually, GitHub permits the save of sensitive information as secret and to use them in an action.

The procedure is simple: we just need to select Secret in the repository settings and add a key with a unique name (figure 5 and figure 6).

Figure 5

Figure 6

We are ready to save and run our action using the Start Commit button. It is a good practice to create a separate branch for this step, avoiding using develop or master. As we save it, our workflow will run, and when it completes, we can verify its correct execution (figure 7), including the upload of the package on Nuget.org (figure 8).

Figure 7

Figure 8

Release versioning in GitHub Actions

In a previous article, we have seen how to version a Nuget package using GitFlow and SemVer. In this article, we will see how to implement the same approach, also using a GitHub Action. Specifically, actions come to help thanks to their extensibility and the contribution of the open-source world.

For example, if we look at this page, we find the code needed to retrieve in our pipeline the version number suitable for our next release.

The following is the full workflow after the addition of GitVersion:

name: Raptor Nuget Packages
 
on: [push]
 
jobs:
  build:
 
    runs-on: ubuntu-latest
     
    steps:
    - uses: actions/checkout@v2
    - name: Fetch all history for all tags and branches
      run: git fetch --prune --unshallow
    - name: Install GitVersion
      uses: gittools/actions/gitversion/setup@v0.9
      with:
          versionSpec: '5.1.x'
    - name: Use GitVersion
      id: gitversion # step id used as reference for output values
      uses: gittools/actions/gitversion/execute@v0.9
    - run: |
        echo "NuGetVersionV2: ${{ steps.gitversion.outputs.nuGetVersionV2 }}"
        echo "NuGetPreReleaseTagV2: ${{ steps.gitversion.outputs.CommitsSinceVersionSourcePadded }}"
    - name: Setup .NET Core
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 3.1.101
    - name: Build with dotnet
      run: dotnet build --configuration Release
    - name: Test with dotnet
      run: dotnet test
    - name: Pack with dotnet
      run: dotnet pack src/Raptor.Core.AspNetCore/Raptor.Core.AspNetCore.csproj --output nuget-packages --configuration Release -p:PackageVersion=${{ steps.gitversion.outputs.nuGetVersionV2 }}-${{ steps.gitversion.outputs.CommitsSinceVersionSourcePadded }} 
    - name: Push with dotnet
      run: dotnet nuget push nuget-packages/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json

Specifically, in the Nuget package creation step, we assign the version number recovered from GitVersion using the command dotnet pack with the parameter PackageVersion:

-p:PackageVersion=${{ steps.gitversion.outputs.nuGetVersionV2 }}-${{ steps.gitversion.outputs.CommitsSinceVersionSourcePadded }}

At the end of the execution of the action, we will find on Nuget the published packages using SemVer (figure 9)

Figura 9

Happy Actions to everyone!