NuGet Release and Pre-Release pipeline
One of the big improvements that came with NuGet is the ability to easily work with third party libraries and, because of proper versioning, using them with relative safety in your software development projects.
With rise of dependency injection, nowadays libraries are not just third party pieces of software, they also become an important part of your own software projects. And this means that you need to have a way to store and share them within your team, but also have a sensible way of versioning them.
Using Semantic Versioning is the best approach, since it gives a clean and easy way for your team to use versions and have everyone understand the same thing when talking about major, minor and patch version numbers. Now you need to make this a part of your CI/CD pipeline.
There are several ways to influence the version number of a NuGet package, the most basic one being that the NuGet package takes the version of the assembly. It is also possible to create a custom NuSpec file, which contains several metadata properties of the NuGet package you intend to build.
With C#, version is determined based on the following two parts in the project: VersionPrefix and VersionSuffix. The project file can also have a Version value. If this is set, the VersionPrefix and VersionSuffix are ignored. Make sure to use the VersionPrefix.
This should result in a pre-release version of a NuGet package, in the NuGet repository.
(Format: major.minor.patch-prereleaseversion)
This can be done in the Azure DevOps pipeline with the following yaml:
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'off'
buildProperties: 'VersionSuffix=$(Build.SourceBranchName)-$(Build.BuildId)'
Note that for the master-build, the command would look like this:
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'off'
The following PowerShell script will check the version against your NuGet repository.
$packageName = $Env:BUILDPROJECT;
$libraryProject = $Env:LIBRARYPROJECT
$nugetUrl = $Env:NUGETURL;
$versionNode = Select-Xml -Path "$($libraryProject).csproj" -XPath "//VersionPrefix" | Select-Object -first 1;
$version = $versionNode.node.InnerText;
$url = '$nugetUrl/Packages(Id='''+ $($packageName) + ''',Version=''' + $($version) + ''')';
$existingpackage = $true;
try {
Invoke-RestMethod $url;
} catch {
if($_.Exception.Response.StatusCode.value__ -eq 404){
$existingpackage = $false;
}
}
if($existingpackage){
Write-Error "$($version) already exists, halting!";
exit 1;
}else{
Write-Information "$($version) still available";
}
With rise of dependency injection, nowadays libraries are not just third party pieces of software, they also become an important part of your own software projects. And this means that you need to have a way to store and share them within your team, but also have a sensible way of versioning them.
Using Semantic Versioning is the best approach, since it gives a clean and easy way for your team to use versions and have everyone understand the same thing when talking about major, minor and patch version numbers. Now you need to make this a part of your CI/CD pipeline.
Pre-Release version, aka the feature build
While creating a new version of the library, you will also want to test the changes to your library in the code that consumes said library. For this you need to have pre-release versions available in your NuGet repository.There are several ways to influence the version number of a NuGet package, the most basic one being that the NuGet package takes the version of the assembly. It is also possible to create a custom NuSpec file, which contains several metadata properties of the NuGet package you intend to build.
Using the Project version
The easiest way to set this up, which will also make sure that the digital signature of your assembly has the intended version number, is to set the version information in the project file.With C#, version is determined based on the following two parts in the project: VersionPrefix and VersionSuffix. The project file can also have a Version value. If this is set, the VersionPrefix and VersionSuffix are ignored. Make sure to use the VersionPrefix.
This should result in a pre-release version of a NuGet package, in the NuGet repository.
(Format: major.minor.patch-prereleaseversion)
This can be done in the Azure DevOps pipeline with the following yaml:
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'off'
buildProperties: 'VersionSuffix=$(Build.SourceBranchName)-$(Build.BuildId)'
Note that for the master-build, the command would look like this:
- task: DotNetCoreCLI@2
inputs:
command: 'pack'
packagesToPack: '**/*.csproj'
versioningScheme: 'off'
Creating a new version
The workflow exists of:- determining the intended version number (is this a patch or minor version? Or even a major version)
- creating your branch, writing and testing your code, then pushing it to the central Git repository.
- build the code and push it to NuGet a s a prerelease
- test the pre-release version
- (fulfilling also team agreements with regards to pull request, code review, testing, etc...) merge to master and create final version for NuGet
Verify existing version in a pipeline
Since versions need to be unique, it is useful to have a quick check if you are building the correct version. The version you are working on should not have a final version available in the NuGet repository.The following PowerShell script will check the version against your NuGet repository.
$packageName = $Env:BUILDPROJECT;
$libraryProject = $Env:LIBRARYPROJECT
$nugetUrl = $Env:NUGETURL;
$versionNode = Select-Xml -Path "$($libraryProject).csproj" -XPath "//VersionPrefix" | Select-Object -first 1;
$version = $versionNode.node.InnerText;
$url = '$nugetUrl/Packages(Id='''+ $($packageName) + ''',Version=''' + $($version) + ''')';
$existingpackage = $true;
try {
Invoke-RestMethod $url;
} catch {
if($_.Exception.Response.StatusCode.value__ -eq 404){
$existingpackage = $false;
}
}
if($existingpackage){
Write-Error "$($version) already exists, halting!";
exit 1;
}else{
Write-Information "$($version) still available";
}
Comments
Post a Comment