GitHub Packages provides a secure, reliable way to host your NuGet packages alongside your source code. This comprehensive guide will walk you through the entire process from creating a package to publishing it to GitHub Packages.
You can find the complete source code and examples in the GitHub repository:
View Complete Source Code on GitHub 🚀
Before you begin, ensure you have:
---
Start by creating a new class library project:
dotnet new classlib -n MyAwesomeLibrary cd MyAwesomeLibrary
Edit your .csproj file to include package metadata:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Package Information -->
<PackageId>MyAwesomeLibrary</PackageId>
<Version>1.0.0</Version>
<Authors>Your Name</Authors>
<Company>Your Company</Company>
<Description>A fantastic library for amazing functionality</Description>
<PackageTags>utility, helper, awesome</PackageTags>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<!-- GitHub Packages Configuration -->
<RepositoryUrl>https://github.com/Prithivi-au/nuget-publish</RepositoryUrl>
<RepositoryType>git</RepositoryType>
</PropertyGroup>
</Project>
1. Go to GitHub Settings → Developer settings → Personal access tokens → Tokens (classic)
2. Click "Generate new token (classic)"
3. Select the following scopes:
- write:packages - Upload packages to GitHub Packages
- read:packages - Download packages from GitHub Packages
- repo - Access to repositories (if your package is in a private repo)
Add GitHub Packages as a NuGet source:
dotnet nuget add source https://nuget.pkg.github.com/Prithivi-au/index.json \ --name github \ --username Prithivi-au \ --password YOUR_PERSONAL_ACCESS_TOKEN \ --store-password-in-clear-text
dotnet pack --configuration Release
This creates a .nupkg file in the bin/Release folder.
dotnet nuget push bin/Release/MyAwesomeLibrary.1.0.0.nupkg \ --source github \ --api-key YOUR_PERSONAL_ACCESS_TOKEN
Create .github/workflows/publish.yml:
name: Publish Package
on:
push:
branches:
- main
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Fetch all history for version calculation
- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
dotnet-version: '8.0.x'
- name: Calculate Version
id: version
run: |
# This step dynamically generates package versions:
# - For tagged releases (v1.0.0): Uses the tag version
# - For main branch commits: Creates semantic version like 1.0.42-abc1234
# where 42 is commit count and abc1234 is short commit SHA
if [[ \$GITHUB_REF == refs/tags/* ]]; then
VERSION=\$\{GITHUB_REF#refs/tags/v\}
else
# Generate version from git info
COMMIT_COUNT=\$(git rev-list --count HEAD)
SHORT_SHA=\$(git rev-parse --short HEAD)
VERSION="1.0.\$\{COMMIT_COUNT\}-\$\{SHORT_SHA\}"
fi
echo "VERSION=\$VERSION" >> \$GITHUB_OUTPUT
echo "Generated version: \$VERSION"
- name: Set environment variables
run: |
echo "REPO_OWNER_LC=\$\{GITHUB_REPOSITORY_OWNER,,\}" >> \$GITHUB_ENV
- name: Restore dependencies
run: dotnet restore MyAwesomeLibrary/MyAwesomeLibrary.sln
- name: Build
run: dotnet build MyAwesomeLibrary/MyAwesomeLibrary.sln --no-restore
- name: Test
run: dotnet test MyAwesomeLibrary/MyAwesomeLibrary.sln --no-build --verbosity normal
- name: Pack
run: dotnet pack MyAwesomeLibrary/MyAwesomeLibrary/MyAwesomeLibrary.csproj --configuration Release -p:Version=\$\{\{ steps.version.outputs.VERSION \}\} --output ./nupkgs
- name: List created packages
run: |
echo "Created packages:"
ls -la ./nupkgs/
- name: Push all packages to GitHub Packages
if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main'
run: |
dotnet nuget push "./nupkgs/*.nupkg" \\
--source "https://nuget.pkg.github.com/\$\{\{ env.REPO_OWNER_LC \}\}/index.json" \\
--api-key \$\{\{ secrets.NUGET_PUBLISH_TOKEN \}\} \\
--skip-duplicate
dotnet nuget add source https://nuget.pkg.github.com/Prithivi-au/index.json \ --name github \ --username Prithivi-au \ --password YOUR_PERSONAL_ACCESS_TOKEN \ --store-password-in-clear-text
dotnet add package MyAwesomeLibrary --source github
You've successfully:
GitHub Packages provides a seamless way to host your NuGet packages alongside your source code, making it easy to share and distribute your .NET libraries.
Get the complete NuGet package source code, GitHub Actions workflows, and step-by-step examples for publishing packages to GitHub Packages.
View on GitHub