GitHub NuGet registry isn't public

October 25th 2024 GitHub NuGet

For the command line tool I was working on recently, I decided to distribute it as a .NET tool. It didn't have anything to do with .NET, except for it being developed in .NET, and the few potential users being .NET developers. That's also why I didn't want to publish it to NuGet Gallery at first and was considering the GitHub Packages NuGet registry instead.

Publishing a NuGet package to GitHub packages wasn't a big deal. In the end I wanted to automate the step using GitHub Actions, but I started by testing everything from the command line.

To do that, I first had to create a classic GitHub personal access token in my Developer Settings.

GitHub classic tokens in Developer Settings

The only required scope was write:packages:

Required scopes for personal access token

I then used the access token as the API key for the dotnet nuget push command:

dotnet nuget push "nupkg\DamirsCorner.ClockifyExport.1.0.0.nupkg"  --api-key MyPersonalAccessToken --source "https://nuget.pkg.github.com/damirarh/index.json"

The damirarh part of the source value is the GitHub user or organization to which you want to publish the package.

By default, the package will be private. Since I wanted it to be publicly available to anyone interested, I had to change its visibility to public. I could do that at the very bottom of the Package settings page, in the Danger Zone part:

Danger Zone in GitHub NuGet pazkage settings

Before continuing, I confirmed that the package was indeed publicly available by accessing it from a private browser window.

Now, it was time to install the package using the dotnet tool install command. After reading its documentation, I figured that adding the GitHub Packages NuGet registry as a source was all I needed:

dotnet tool install -g DamirsCorner.ClockifyExport --add-source "https://nuget.pkg.github.com/damirarh/index.json"

Unfortunately not. The command failed with the following exception:

Unhandled exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 401 (Unauthorized).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at NuGet.Protocol.HttpSource.<>c__DisplayClass15_0`1.<<GetAsync>b__0>d.MoveNext()

Although the package was public, authentication is still needed to download it. Since the dotnet tool install command doesn't have a way to directly provide a personal access token, I had to create a nuget.config file and put the token there:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <packageSources>
        <clear />
        <add key="github" value="https://nuget.pkg.github.com/damirarh/index.json" />
    </packageSources>
    <packageSourceCredentials>
        <github>
            <add key="Username" value="damirarh" />
            <add key="ClearTextPassword" value="MyPersonalAccessToken" />
        </github>
    </packageSourceCredentials>
</configuration>

Now, I passed this config file to the dotnet tool install command instead of the NuGet registry address directly:

dotnet tool install -g DamirsCorner.ClockifyExport --configfile nuget.config

This worked. The command installed successfully.

However, I decided this wasn't really a good solution for my use case. It was too complicated for potential users to install the tool: they would have to create a personal access token, and a dedicated nuget.config file to use when installing or updating my tool.

I ended up publishing the tool to the NuGet Gallery instead even if it's not related to .NET development. And to my surprise, it already has over 350 downloads at the time of writing. That's a little over a month after I published the first version. I wonder if most of those downloads are by bots and agents downloading every NuGet package for one reason or another.

As far as GitHub Packages NuGet registry is concerned, I think it can be a useful tool for publishing packages needed by GitHub Actions or a team of developers. In these cases the overhead of authentication might be worth it. In all other cases you are better off publishing public packages to NuGet Gallery instead.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License