The ability to automate software deployment is a key part of an healthy development process. In this post we will cover how to ship our .NET Core packages from the source hosted in GitHub into NuGet.org by using Travis CI.

GitHub, Travis, .NET, Nuget

Requirements

I’m already assuming a basic setup of Travis using your GitHub account. If that’s not the case, please read here first.

You will also need…

  • A NuGet.org account
  • A NuGet API Key that you can generate here if you don’t have one already
  • A code repository with your .NET Core source on GitHub

The Travis blueprint file

The Travis blueprint file is a .travis.yml file in the root of your project’s repository. This will instruct Travis on how to build and deploy your artifacts.

Let’s say we have a nice .NET Standard library, SampleNetLib, that we want to make available on NuGet.org.

language: csharp
mono: none
os: linux
dist: trusty
dotnet: 2.0.0
script:
- dotnet build -c Release
- dotnet test

The above blueprint will tell Travis the following:

  • C# project
  • Mono is not required
  • Run it on Trusty Tahr Ubuntu Linux
  • Build it using .NET Core SDK 2.0
  • Execute the steps build and test

This is a simple Travis blueprint that does the basics: build and test execution.

Uploading the NuGet package

First, we will make it manually, and then automate it. We will be using dotnet pack command that relies on the csproj package configuration to generate the package. An example of such csproj would be:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Library</OutputType>
    <TargetFramework>netstandard2.0</TargetFramework>
    <PackageId>SampleNetLib</PackageId>
    <PackageVersion>0.0.1</PackageVersion>
    <Authors>John Doe</Authors>
    <Owners>John Doe</Owners>
    <Title>Sample .NET library</Title>
    <Description>Sample .NET library</Description>
    <ProjectUrl>https://github.com/...</ProjectUrl>
    <LicenseUrl>https://github.com/.../LICENSE.md</LicenseUrl>
    <PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
    <PackageReleaseNotes>...</PackageReleaseNotes>
    <Copyright>Copyright Notice</Copyright>
    <PackageTags>Package tags and SEO stuff</PackageTags>
  </PropertyGroup>
  (...)
</Project>

We also need to make sure we have the correct package sources configured. This can be done with a simple nuget.config file in the project’s root, similar to the following:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <config>
    <add key="defaultPushSource" value="https://api.nuget.org/v3/index.json" />
  </config>
  <packageSources>
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />
  </packageSources>
</configuration>

Then we need to run the dotnet pack command.

dotnet pack -c Release

This will create a file in the output folder with the name SampleNetLib.0.0.1.nupkg. The dotnet nuget push will make this package available on NuGet.org.

dotnet nuget push src/SampleNetLib/bin/Release/SampleNetLib.0.0.1.nupkg -k <API Key>

Where the <API Key> is the key generated at NuGet.org.

And that should be enough to have your package available on NuGet.org. Let’s now revise our Travis blueprint to make it automatic.

language: csharp
mono: none
os: linux
dist: trusty
dotnet: 2.0.0
script:
- dotnet build -c Release
- dotnet test
- dotnet pack -c Release
deploy:
  skip_cleanup: true
  provider: script
  script: dotnet nuget push src/SampleNetLib/bin/Release/SampleNetLib.*.nupkg --api-key $NUGET_API_KEY
  on:
    tags: true
    condition: $TRAVIS_TAG =~ ^(\d+\.)?(\d+\.)?(\*|\d+)$

The tags and condition statements will ensure that we only deploy when a tag is created on GitHub that follows the versioning pattern M.m.p which is a typical use for GitHub releases.

Notice the variable $NUGET_API_KEY? That’s because we dont want to expose our API Key on our project’s source code. But now a secret is necessary to store that variable. For that, run the Travis CLI in the project’s root to configure that variable.

travis encrypt NUGET_API_KEY="<API Key>" --add

The above will generate a secret hash from the API Key and will add it to the .travis.yml file.

Push your changes and watch it go live.

Badges

You may also want to include build and version badges in your README, as follows:

[![Build Status](https://travis-ci.org/<user>/<repo>.svg?branch=master)](https://travis-ci.org/<user>/<repo>)
[![NuGet Version](https://badge.fury.io/nu/<repo>.svg)](https://badge.fury.io/nu/<repo>)

The above markdown include nice badges referencing your project’s build status and latest published version, as shown below:

Badges

Wrapping-Up

In this post we covered how to make a .NET Core project hosted on GitHub available to download on NuGet.org through Travis CI.

This automation facilitates the whole development process and save developers a huge amount of time.