Skip to content

NuGet / .NET Guide

Artifact Keeper provides a fully compatible NuGet v3 repository for publishing and installing .NET packages.

Endpoint

All NuGet operations use the /nuget/{repo} endpoint:

http://localhost:8080/nuget/default

For production:

https://registry.example.com/nuget/default

Format Information

  • Format key: nuget
  • Supported aliases: chocolatey, powershell (route through NuGet handler)
  • API version: NuGet v3 API

Configuration

nuget.config Configuration

Create or edit nuget.config in your project root or globally:

Project-level (nuget.config in project directory):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="ArtifactKeeper" value="http://localhost:8080/nuget/default/v3/index.json" />
</packageSources>
</configuration>

User-level (%AppData%\NuGet\NuGet.Config on Windows, ~/.nuget/NuGet/NuGet.Config on Linux/macOS):

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="ArtifactKeeper" value="http://localhost:8080/nuget/default/v3/index.json" />
</packageSources>
</configuration>

dotnet CLI Configuration

Add package source using the dotnet CLI:

Terminal window
dotnet nuget add source http://localhost:8080/nuget/default/v3/index.json --name ArtifactKeeper

For production:

Terminal window
dotnet nuget add source https://registry.example.com/nuget/default/v3/index.json --name ArtifactKeeper

List configured sources:

Terminal window
dotnet nuget list source

Remove a source:

Terminal window
dotnet nuget remove source ArtifactKeeper

Visual Studio Configuration

  1. Open ToolsOptionsNuGet Package ManagerPackage Sources
  2. Click the + button to add a new source
  3. Set Name: ArtifactKeeper
  4. Set Source: http://localhost:8080/nuget/default/v3/index.json
  5. Click Update and OK

Authentication

API Key Authentication

Add API key to nuget.config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="ArtifactKeeper" value="http://localhost:8080/nuget/default/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<ArtifactKeeper>
<add key="Username" value="your-username" />
<add key="ClearTextPassword" value="your-api-key" />
</ArtifactKeeper>
</packageSourceCredentials>
</configuration>

Encrypted Credentials

Store encrypted password (recommended for Windows):

Terminal window
dotnet nuget update source ArtifactKeeper --username your-username --password your-api-key --store-password-in-clear-text

Or use encrypted storage:

Terminal window
dotnet nuget update source ArtifactKeeper --username your-username --password your-api-key

Basic Authentication

For basic auth, use credentials in nuget.config:

<packageSourceCredentials>
<ArtifactKeeper>
<add key="Username" value="your-username" />
<add key="ClearTextPassword" value="your-password" />
</ArtifactKeeper>
</packageSourceCredentials>

Environment Variables

Use environment variables in CI/CD:

Terminal window
export NUGET_SOURCE=http://localhost:8080/nuget/default/v3/index.json
export NUGET_API_KEY=your-api-key

Publishing Packages

Create a Package

Build your project and create a NuGet package:

Terminal window
dotnet pack

This generates a .nupkg file in bin/Debug or bin/Release.

Pack with Specific Configuration

Terminal window
dotnet pack --configuration Release --output ./packages

Configure Package Metadata

Edit your .csproj file:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<PackageId>MyCompany.MyPackage</PackageId>
<Version>1.0.0</Version>
<Authors>Your Name</Authors>
<Company>Your Company</Company>
<Description>A comprehensive description of your package</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/mycompany/mypackage</PackageProjectUrl>
<RepositoryUrl>https://github.com/mycompany/mypackage</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>tag1;tag2;tag3</PackageTags>
<PackageReleaseNotes>Initial release</PackageReleaseNotes>
</PropertyGroup>
</Project>

Publish with dotnet CLI

Terminal window
dotnet nuget push MyPackage.1.0.0.nupkg --source ArtifactKeeper --api-key your-api-key

For production:

Terminal window
dotnet nuget push MyPackage.1.0.0.nupkg \
--source https://registry.example.com/nuget/default \
--api-key your-api-key

Publish with NuGet CLI

Terminal window
nuget push MyPackage.1.0.0.nupkg -Source http://localhost:8080/nuget/default -ApiKey your-api-key

Publish All Packages in Directory

Terminal window
dotnet nuget push "packages/*.nupkg" --source ArtifactKeeper --api-key your-api-key

Installing Packages

Install with dotnet CLI

Terminal window
dotnet add package MyCompany.MyPackage

Install Specific Version

Terminal window
dotnet add package MyCompany.MyPackage --version 1.0.0

Install Prerelease Version

Terminal window
dotnet add package MyCompany.MyPackage --prerelease

Install from Specific Source

Terminal window
dotnet add package MyCompany.MyPackage --source ArtifactKeeper

PackageReference in .csproj

Add package reference directly to your project file:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MyCompany.MyPackage" Version="1.0.0" />
</ItemGroup>
</Project>

Version Ranges

Use version ranges for flexible dependency management:

<PackageReference Include="MyCompany.MyPackage" Version="[1.0.0,2.0.0)" />
<!-- 1.0.0 <= version < 2.0.0 -->
<PackageReference Include="MyCompany.MyPackage" Version="1.*" />
<!-- Latest 1.x version -->
<PackageReference Include="MyCompany.MyPackage" Version="*" />
<!-- Latest version -->

Restore Packages

Terminal window
dotnet restore

Restore from specific source:

Terminal window
dotnet restore --source http://localhost:8080/nuget/default/v3/index.json

Version Management

Semantic Versioning

Follow semantic versioning in your .csproj:

<PropertyGroup>
<Version>1.0.0</Version>
</PropertyGroup>

Increment Versions

Update version manually in .csproj:

<!-- Patch: 1.0.0 -> 1.0.1 -->
<Version>1.0.1</Version>
<!-- Minor: 1.0.0 -> 1.1.0 -->
<Version>1.1.0</Version>
<!-- Major: 1.0.0 -> 2.0.0 -->
<Version>2.0.0</Version>

Prerelease Versions

Use prerelease suffixes:

<Version>1.0.0-alpha</Version>
<Version>1.0.0-beta.1</Version>
<Version>1.0.0-rc.2</Version>

Version from Git Tag

Use MSBuild properties to version from Git:

<PropertyGroup>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix Condition="'$(Configuration)' != 'Release'">$(VersionSuffix)</VersionSuffix>
</PropertyGroup>

List Package Versions

Terminal window
dotnet list package --outdated
dotnet list package --deprecated
dotnet list package --vulnerable

Search for Packages

Terminal window
dotnet package search MyPackage --source ArtifactKeeper

Symbol Packages

Create Symbol Package

Include symbols for debugging:

<PropertyGroup>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
Terminal window
dotnet pack --include-symbols --include-source

Publish Symbol Package

Terminal window
dotnet nuget push MyPackage.1.0.0.nupkg --source ArtifactKeeper --api-key your-api-key
dotnet nuget push MyPackage.1.0.0.snupkg --source ArtifactKeeper --api-key your-api-key

CI/CD Integration

GitHub Actions

name: Publish NuGet Package
on:
push:
tags:
- 'v*'
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore
- name: Test
run: dotnet test --no-restore --verbosity normal
- name: Pack
run: dotnet pack --configuration Release --no-build --output ./packages
- name: Publish to Artifact Keeper
run: |
dotnet nuget push "./packages/*.nupkg" \
--source https://registry.example.com/nuget/default \
--api-key ${{ secrets.NUGET_API_KEY }} \
--skip-duplicate

GitLab CI

stages:
- build
- publish
build:
stage: build
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- dotnet restore
- dotnet build --configuration Release
- dotnet test
- dotnet pack --configuration Release --output ./packages
artifacts:
paths:
- packages/*.nupkg
publish:
stage: publish
image: mcr.microsoft.com/dotnet/sdk:8.0
script:
- dotnet nuget push "packages/*.nupkg"
--source https://registry.example.com/nuget/default
--api-key $NUGET_API_KEY
--skip-duplicate
only:
- tags

Azure Pipelines

trigger:
tags:
include:
- v*
pool:
vmImage: 'ubuntu-latest'
variables:
buildConfiguration: 'Release'
steps:
- task: UseDotNet@2
inputs:
version: '8.0.x'
- script: dotnet restore
displayName: 'Restore packages'
- script: dotnet build --configuration $(buildConfiguration)
displayName: 'Build project'
- script: dotnet test --configuration $(buildConfiguration)
displayName: 'Run tests'
- script: dotnet pack --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)
displayName: 'Pack NuGet packages'
- script: |
dotnet nuget push "$(Build.ArtifactStagingDirectory)/*.nupkg" \
--source https://registry.example.com/nuget/default \
--api-key $(NUGET_API_KEY) \
--skip-duplicate
displayName: 'Publish to Artifact Keeper'

Jenkins Pipeline

pipeline {
agent any
environment {
DOTNET_CLI_HOME = "/tmp/dotnet"
NUGET_SOURCE = 'https://registry.example.com/nuget/default'
}
stages {
stage('Restore') {
steps {
sh 'dotnet restore'
}
}
stage('Build') {
steps {
sh 'dotnet build --configuration Release --no-restore'
}
}
stage('Test') {
steps {
sh 'dotnet test --no-restore'
}
}
stage('Pack') {
steps {
sh 'dotnet pack --configuration Release --no-build --output ./packages'
}
}
stage('Publish') {
when {
tag "v*"
}
steps {
withCredentials([
string(credentialsId: 'nuget-api-key', variable: 'NUGET_API_KEY')
]) {
sh '''
dotnet nuget push "packages/*.nupkg" \
--source ${NUGET_SOURCE} \
--api-key ${NUGET_API_KEY} \
--skip-duplicate
'''
}
}
}
}
}

Advanced Configuration

Multiple Package Sources

Configure multiple NuGet sources:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
<add key="ArtifactKeeper" value="https://registry.example.com/nuget/default/v3/index.json" />
<add key="ArtifactKeeper-Internal" value="https://registry.example.com/nuget/internal/v3/index.json" />
</packageSources>
<packageSourceCredentials>
<ArtifactKeeper>
<add key="Username" value="user1" />
<add key="ClearTextPassword" value="key1" />
</ArtifactKeeper>
<ArtifactKeeper-Internal>
<add key="Username" value="user2" />
<add key="ClearTextPassword" value="key2" />
</ArtifactKeeper-Internal>
</packageSourceCredentials>
</configuration>

Package Source Mapping

Route specific packages to specific sources (NuGet 6.0+):

<packageSourceMapping>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
<packageSource key="ArtifactKeeper">
<package pattern="MyCompany.*" />
<package pattern="Internal.*" />
</packageSource>
</packageSourceMapping>

Fallback Sources

Configure fallback package sources:

<fallbackPackageFolders>
<add key="shared-packages" value="/opt/nuget-packages" />
</fallbackPackageFolders>

Proxy Configuration

<config>
<add key="http_proxy" value="http://proxy.example.com:8080" />
<add key="http_proxy.user" value="proxyuser" />
<add key="http_proxy.password" value="proxypass" />
</config>

Package Management

Update Packages

Update all packages:

Terminal window
dotnet list package --outdated
dotnet add package MyCompany.MyPackage

Remove Package

Terminal window
dotnet remove package MyCompany.MyPackage

Clear NuGet Cache

Terminal window
dotnet nuget locals all --clear

Verify Package Integrity

Terminal window
dotnet nuget verify MyPackage.1.0.0.nupkg

Troubleshooting

Authentication Errors

Verify credentials:

Terminal window
dotnet nuget list source

Test authentication:

Terminal window
dotnet nuget push --help

Check nuget.config location:

Terminal window
# Windows
%AppData%\NuGet\NuGet.Config
# Linux/macOS
~/.nuget/NuGet/NuGet.Config

Publishing Failures

Enable detailed logging:

Terminal window
dotnet nuget push MyPackage.1.0.0.nupkg \
--source ArtifactKeeper \
--api-key your-api-key \
--verbosity detailed

Validate package before publishing:

Terminal window
dotnet nuget verify MyPackage.1.0.0.nupkg

Installation Issues

Clear all caches:

Terminal window
dotnet nuget locals all --clear

Force package restore:

Terminal window
dotnet restore --force --no-cache

Check package source availability:

Terminal window
dotnet nuget list source
curl http://localhost:8080/nuget/default/v3/index.json

Version Conflicts

List all package versions:

Terminal window
dotnet list package --include-transitive

Check for outdated packages:

Terminal window
dotnet list package --outdated

SSL Certificate Errors

For self-signed certificates, disable SSL verification (not recommended for production):

<config>
<add key="signatureValidationMode" value="accept" />
</config>

Or install the certificate in your system’s trusted root store.

Best Practices

Semantic Versioning

  • Major (1.0.0 -> 2.0.0): Breaking API changes
  • Minor (1.0.0 -> 1.1.0): New features, backward compatible
  • Patch (1.0.0 -> 1.0.1): Bug fixes and patches

Package Metadata

Include comprehensive metadata in .csproj:

<PropertyGroup>
<PackageId>MyCompany.MyPackage</PackageId>
<Version>1.0.0</Version>
<Authors>Your Name</Authors>
<Company>Your Company</Company>
<Description>Detailed package description</Description>
<Copyright>Copyright (c) 2024 Your Company</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/mycompany/mypackage</PackageProjectUrl>
<RepositoryUrl>https://github.com/mycompany/mypackage</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>dotnet;csharp;library</PackageTags>
<PackageReleaseNotes>See CHANGELOG.md</PackageReleaseNotes>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>icon.png</PackageIcon>
</PropertyGroup>
<ItemGroup>
<None Include="README.md" Pack="true" PackagePath="/" />
<None Include="icon.png" Pack="true" PackagePath="/" />
</ItemGroup>

Exclude Development Files

Use .nuspec or .csproj to exclude unnecessary files:

<ItemGroup>
<Content Remove="**/*.Development.json" />
<None Remove="**/*.Development.json" />
</ItemGroup>

Multi-Targeting

Support multiple .NET versions:

<PropertyGroup>
<TargetFrameworks>net8.0;net7.0;net6.0;netstandard2.1</TargetFrameworks>
</PropertyGroup>

Enable Source Link for better debugging:

<PropertyGroup>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>

Lock Files

Use package lock files for reproducible builds:

<PropertyGroup>
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
</PropertyGroup>

See Also