Publish to NuGet feeds
Azure Pipelines | TFS 2018 | TFS 2017
Build and release pipelines are called definitions in TFS 2018 and in older versions. Service connections are called service endpoints in TFS 2018 and in older versions.
You can publish NuGet packages from your build to NuGet feeds. You can publish these packages to
- Azure Artifacts or the TFS Package Management service
- Other NuGet services such as NuGet.org
- Your internal NuGet repository
Create a NuGet package
There are a variety of ways to create NuGet packages during a build. If you're already using MSBuild or some other task to create your packages, skip this section to go ahead and publish your packages. Otherwise, add a NuGet task:
To create a package, add the following snippet to your azure-pipelines.yml file.
- task: NuGetCommand@2 inputs: command: pack packagesToPack: '**/*.csproj'
The NuGet task supports a number of options. Some of the key ones are described below. The rest are described in the task documentation.
- packagesToPack: The path to the files that describe the package you want to create. If you don't have these, see the NuGet documentation to get started.
- configuration: The default is
$(BuildConfiguration)unless you wish to always build either
Releasepackages, or unless you have a custom build configuration.
- packDestination: The default is
$(Build.ArtifactStagingDirectory). If you set this, make a note of the location so you can use it in the publish task.
YAML is not supported in TFS.
In NuGet, a particular package is identified by its name and version number. A recommended approach to versioning packages is to use semantic versioning. Semantic version numbers have 3 numeric components,
Major.Minor.Patch. When you fix a bug, you increment the patch (
1.0.1). When you release a new backwards-compatible feature, you increment minor and reset patch to 0 (
1.5.0). When you make a backwards-incompatible change, you increment major and reset minor and patch to 0 (
In addition to
Major.Minor.Patch, semantic versioning provides for a prerelease label. Prerelease labels are a “-” followed by whatever letters and numbers you want. Version
1.0.0-foo12345 are all prerelease versions of
1.0.0. Even better, semantic versioning specifies that when you sort by version number, those prerelease versions fit exactly where you’d expect:
When you create a package in CI, you can use semantic versioning with prerelease labels. The NuGet task can be used for this purpose, and supports the following formats:
Use the same versioning scheme for your builds and packages, provided that scheme has at least three parts separated by periods. The following build pipeline formats are examples of versioning schemes that are compatible with NuGet.
Minorare two variables defined in the build pipeline. This will automatically increment the build number and the package version with a new patch number keeping the major and minor versions constant, until you change them manually in the build pipeline.
Patchare variables defined in the build pipeline. This will create a new prerelease label for the build and package while keeping the major, minor, and patch versions constant.
Use a version that is different from the build number. You can customize the major, minor, and patch versions for your packages in the NuGet task, and let the task generate a unique prerelease label based on date and time.
Use a script in your build pipeline to generate the version.
This example shows how to use the date and time as the prerelease label.
variables: Major: '1' Minor: '0' Patch: '0' steps: - task: NuGetCommand@2 inputs: command: pack versioningScheme: byPrereleaseNumber majorVersion: '$(Major)' minorVersion: '$(Minor)' patchVersion: '$(Patch)'
For a list of other possible values for
versioningScheme, see the NuGet task.
YAML is not supported in TFS.
While semantic versioning with prerelease labels is a good solution for packages produced in CI builds, including a prerelease label is not ideal when you want to release a package to your users. The challenge is that packages once produced are immutable and so cannot be updated or replaced. When you’re producing a package in build, you can’t know whether it will be the version that you aim to release to your users or just a step along the way towards that release. While none of the following solutions are ideal, you can use one of these depending on your preference:
Once you validate a package and decide to release it, produce another package without the prerelease label and publish it. The drawback of this approach is that you have to validate the new package again, and it may uncover new issues.
Publish only packages that you wish to release. In this case, you will not use a prerelease label for every build. Instead, you will reuse the same package version for all packages. Since you do not publish packages from every build, you do not cause a conflict.
Publish your packages
In the previous section, you learned how to create a package with every build. When you are ready to share the changes to your package with your users, you can publish it.
To publish to an Azure Artifacts feed, set the Project Collection Build Service identity to be a Contributor on the feed. To learn more about permissions to Package Management feeds, see Secure and share packages using feed permissions.
To publish to a external NuGet feed, you must first create a service connection to point to that feed. You can do this by going to Project settings, then choosing Service connections, and then creating a New service connection. Select the NuGet option for the service connection. Fill in feed URL and the API key or token to connect to the feed.
To publish a package to a NuGet feed, add the following snippet to your azure-pipelines.yml file.
- task: NuGetCommand@2 inputs: command: push nuGetFeedType: external publishFeedCredentials: '<Name of the NuGet service connection>' versioningScheme: byEnvVar versionEnvVar: Version
YAML is not supported in TFS.
Publish symbols for your packages
When you push packages to a Package Management feed, you can also publish symbols.