Publish NuGet packages with Azure Pipelines (YAML/Classic)
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
With Azure Pipelines, you can use either classic or YAML pipelines to publish your NuGet packages to your Azure Artifacts feed, external feeds, or public registries such as nuget.org. In this article, you will learn how to:
- Generate a NuGet package in Azure Pipelines
- Publish packages to internal and external feeds
- Publish packages to NuGet.org
Prerequisites
An Azure DevOps organization. Create one for free.
An Azure DevOps project. Create a new project if you don't have one already.
An Azure Artifacts feed. Create one for free.
Create a NuGet package
There are several ways to create your NuGet packages, such as using the dotnet or nuget.exe CLI to pack your packages. If you are already using MSBuild or other tasks to create your packages, you can skip this section and proceed to the next one.
To create a NuGet package, add the following snippet to your YAML file. See NuGet task for more details.
- task: NuGetCommand@2
inputs:
command: pack
packagesToPack: '**/*.csproj'
packDestination: '$(Build.ArtifactStagingDirectory)'
- packagesToPack: the pattern that the task uses to search for csproj directories to pack.
- packDestination: directory where packages are created. If empty, packages will be created at the source root.
Package versioning
NuGet packages are defined by their names and version numbers. Using Semantic Versioning is a recommended approach for effectively managing package versions. Semantic versions are comprised of three numeric components: Major, Minor, and Patch.
The Patch number is incremented after fixing a bug. When releasing a new backward-compatible feature, you increment the Minor version and reset the Patch version to 0. Conversely, when making a backward-incompatible change, you increment the Major version and reset both the Minor and Patch versions to 0.
Semantic Versioning also supports the use of prerelease labels to tag packages. Simply append a hyphen followed by your prerelease tag, for example: 1.0.0-beta.
Azure Pipelines supports Semantic Versioning and offers the following configuration options for NuGet tasks:
Use the date and time (Classic) | byPrereleaseNumber (YAML): Your package version follows the format: Major.Minor.Patch-ci-datetime where you have the flexibility to customize the Major, Minor, and Patch values.
Use an environment variable (Classic) | byEnvVar (YAML): Your package version is set to the value of the specified environment variable.
Use the build number (Classic) | byBuildNumber (YAML): Your package version is set to the build number. Make sure you define the build number format in your pipeline Options as
$(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
. To specify the format in YAML, add aname:
property at the root of your pipeline and define your format.
Below is an example demonstrating how to use the date and time versioning to generate a SemVer-compliant package formatted as: Major.Minor.Patch-ci-datetime.
variables:
Major: '1'
Minor: '0'
Patch: '0'
steps:
- task: NuGetCommand@2
inputs:
command: pack
versioningScheme: byPrereleaseNumber
majorVersion: '$(Major)'
minorVersion: '$(Minor)'
patchVersion: '$(Patch)'
Note
DotNetCore
and DotNetStandard
packages should be packaged with the DotNetCoreCLI@2
task to avoid System.InvalidCastExceptions. See .NET Core CLI task for more details.
task: DotNetCoreCLI@2
inputs:
command: pack
versioningScheme: byPrereleaseNumber
majorVersion: '$(Major)'
minorVersion: '$(Minor)'
patchVersion: '$(Patch)'
Publish packages to internal feeds
Note
To publish your packages to a feed using Azure Pipelines, make sure that both the Project Collection Build Service and your project's Build Service identities are granted the Feed Publisher (Contributor) role assigned in your feed settings. See Manage permissions for more details.
steps:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'
- task: NuGetCommand@2
displayName: 'NuGet push'
inputs:
command: push
publishVstsFeed: '<projectName>/<feed>'
allowPackageConflicts: true
Publish packages to external feeds
To publish your packages to external NuGet feeds or public registries, such as feeds in other Azure DevOps organizations or nuget.org, you must first create a service connection to authenticate with the respective service:
From your Azure DevOps project navigate to Project settings > Service connections >
Select New service connection > NuGet > Next.
Fill out the required fields and then select Save when you're done. See Manage service connections for more details.
Note
The NuGetAuthenticate@1 task supports service connections with basic authentication but does not support Apikey authentication. To use ApiKey authentication, you must use the NuGetCommand@2 task instead.
To publish your NuGet packages to a feed in a different organization, add the following snippet to your YAML pipeline:
Using the Command line task and NuGet.exe:
- task: NuGetAuthenticate@1 inputs: nuGetServiceConnections: <NAME_OF_YOUR_SERVICE_CONNECTION> - script: | nuget push <PACKAGE_PATH> -src https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json -ApiKey <ANY_STRING> displayName: "Push"
Using the Command line task and dotnet:
- task: NuGetAuthenticate@1 inputs: nuGetServiceConnections: <NAME_OF_YOUR_SERVICE_CONNECTION> - script: | dotnet build <CSPROJ_PATH> --configuration <CONFIGURATION> dotnet pack <CSPROJ_PATH> -p:PackageVersion=<YOUR_PACKAGE_VERSION> --output <OUTPUT_DIRECTORY> --configuration <CONFIGURATION> dotnet nuget push <PACKAGE_PATH> --source https://pkgs.dev.azure.com/<ORGANIZATION_NAME>/<PROJECT_NAME>/_packaging/<FEED_NAME>/nuget/v3/index.json --api-key <ANY_STRING> displayName: "Build, pack and push" ```
Note
The ApiKey
is required, but you can use any string when publishing to an Azure Artifacts feed.
Publish to NuGet.org
Sign in to your nuget.org account and Generate an API key.
Navigate to your Azure DevOps project and then select
Project settings.
Select Service Connections, and then select New service connection.
Select NuGet, and then select Next.
Select ApiKey as your authentication method, and use the following url for your Feed URL: https://api.nuget.org/v3/index.json.
Enter the ApiKey you generated earlier, then provide a Service connection name.
Select Grant access permission to all pipelines, and then select Save when you're done. Note that you need the service connection Administrator role to select this option.
steps:
- task: NuGetCommand@2
displayName: 'NuGet push'
inputs:
command: push
nuGetFeedType: external
publishFeedCredentials: nuget.org