From Code to Cloud: Automating NuGet Package Publishing with GitHub Actions
As a developer, there’s a particular sense of satisfaction in seeing your work come to life in a tangible way, and that’s exactly what happened when I authored a .NET SDK for BlueSky, the decentralized social media platform. Aptly named BlueSky.NET, this library bridges the gap between .NET developers and the BlueSky API. If you’re on BlueSky, you can follow the project under the handle @blueskydotnet.bsky.social. This article takes you through the steps I followed to automate the publishing of BlueSky.NET to NuGet.org using a GitHub Action.
To begin with, I set up several GitHub repository secrets to facilitate the integration tests and the package publishing process. Two key secrets, BLUESKY_HANDLE and BLUESKY_PASSWORD, were essential for running integration tests. These tests fire off every time I open a new pull request, generating humorous “Beep, Beep, Boop!” messages on my BlueSky account. These SPAM-esque posts serve as integration test results, proving the library’s ability to interface with the BlueSky API. No bots were harmed in the making of this test sequence—just good, clean fun.
Next, I headed over to NuGet.org to set up an API key. This step is crucial as it’s how you authenticate against NuGet’s server to publish your package. Once the key was generated, I added it as the NUGET_API_KEY secret in the GitHub repository. This API key serves as a bridge, securely allowing GitHub Actions to interact with NuGet on my behalf.
To ensure my package met all the necessary criteria for publishing, I paid close attention to the details. My .NET project was configured with all the required assembly details — author, description, license, and more — under the Package settings in Visual Studio 2022. Additionally, a README.md file was included in the project to provide documentation directly on the NuGet.org page. This ensures that developers can get started with the package quickly and easily once it’s published.
With the groundwork laid, the next step was to automate the packaging and publishing process using the dotnet CLI. In my GitHub Actions workflow, I added a step to dynamically generate a build number based on the current date and the GitHub run number. This ensures that every build is uniquely versioned, which is a NuGet requirement. Here’s the exact GitHub Action step:
- name: Pack NuGet package
env:
NUGET_API_KEY: $
run: |
echo "Generating build number..."
BUILD_NUMBER=$(date +%Y.%m.%d).$
echo "Build number: $BUILD_NUMBER"
dotnet pack src/Qonq.BlueSky/Qonq.BlueSky.csproj --configuration Release --no-build -o ./nupkgs /property:PackageVersion=$BUILD_NUMBER
dotnet nuget push --source 'https://nuget.org' --api-key $NUGET_API_KEY nupkgs/*.nupkg
This snippet performs two key tasks: packing the .NET assembly into a NuGet package and pushing it to NuGet.org. The dotnet pack command creates the package, while dotnet nuget push uploads it to the NuGet server using the API key stored in the repository secrets. The dynamic build number keeps everything organized and ensures seamless version control.
After a successful workflow run, the BlueSky.NET package officially appeared on NuGet.org, complete with installation instructions and a description of its capabilities. It’s immensely satisfying to see the package live, ready to be installed by developers with a simple command in their terminal. Seeing the project’s page on NuGet.org, with all the details meticulously displayed, felt like a well-earned milestone.
Publishing a NuGet package might seem daunting at first, but leveraging GitHub Actions simplifies the process significantly. The integration of secure secrets, dynamic versioning, and automated steps means you can focus more on coding and less on the repetitive details of deployment. With BlueSky.NET, the journey has just begun, and I’m excited to see how it evolves in the hands of other developers. If you’re considering publishing your own package, I hope this guide inspires you to dive in and get started.