nuget push wildcard in TeamCity - nuget

I have a build step in TeamCity 9.1 to push a .nupkg file to a hosted feed on myget.org, but it doesn't work with wildcards.
The build step is as follows:
mono /opt/NuGet2/NuGet.exe push %srcDir%/bin/release/Foo.1.0.0.nupkg -Source https://www.myget.org/F/<org_name>/api/v2/package
This works, but I don't want to explicitly set the version number in a build step because this will be incremented over time.
I tried adding a wildcard to the statement like this:
mono /opt/NuGet2/NuGet.exe push %srcDir%/bin/release/Foo.*.nupkg -Source https://www.myget.org/F/<org_name>/api/v2/package
But the wildcard (instead of 1.0.0) seems to break the TeamCity build agent and it gets stuck in a loop until I kill it manually.
How can I create the build step in TeamCity such that I don't need to hard-code a version number in it? Is there a way to omit the version number from the .nupkg file name or allow TeamCity to work with wildcard file names?

You can simply use the "NuGet Publish" runner type and in the "Packages" setting specify a wildcard for where the packages reside (For example: ManualTests/Artifacts/*.nupkg).

Related

Modifying the version of a nupkg in github actions pipeline

We're running into a problem with our NuGet pipelines on GitHub. We have it set to run a step to build the project, and NuGet pack it with a specific version (the RC version generally something like 1.0.0-rc.1) this works fine, and we can then pass the artifact to the RC step and upload it to where it needs to go using NuGet push.
The problem comes in when we're trying to then move that package from RC into GA (the desired flow being: build > RC > GA), we want to take the same exact package and modify the version so it no longer has the RC tag (stripping it down to 1.0.0), however I haven't been able to find a clean way to do this. The current workaround is to take the exact same commit and rebuild it with the GA version but we would much rather just modify the RC version to have the correct version number.
Is there a NuGet command or something that I'm missing to accomplish this? I considered downloading the nupkg file, installing it to an output directory and then repacking it with the correct version but I was hoping there may be a better way.
Few options using Action Update Helpers,
the diff. is helpful depending on what you are publishing, nuget libs you are publishing vs. custom libs - since you did not share your sample yaml/code, I am sharing both.
Option 1: use the Release Tag Updater helper lib. from here or a newer one here from Github or Market Place
Helpful for your own, i.e if you publish NUGET libs
In your yaml configuration file for github actions, in the stage that you want to rename you can use the tag option with passed in values
# Filepath of the project to be packaged, relative to root of repository
PROJECT_FILE_PATH: YourProject/YourProject.csproj
# NuGet package id, used for version detection & defaults to project name
# PACKAGE_NAME: YourProject
# API key to authenticate with NuGet server
NUGET_KEY: ${{secrets.NUGET_API_KEY}}
# NuGet server uri hosting the packages, defaults to https://api.nuget.org
# NUGET_SOURCE: https://api.nuget.org
# Filepath with version info, relative to root of repository & defaults to PROJECT_FILE_PATH
# VERSION_FILE_PATH: Directory.Build.props
# Regex pattern to extract version info in a capturing group
# VERSION_REGEX: <Version>(.*)<\/Version>
# Useful with external providers like Nerdbank.GitVersioning, ignores VERSION_FILE_PATH & VERSION_REGEX
# VERSION_STATIC: 1.0.0
# Flag to toggle git tagging, enabled by default
# TAG_COMMIT: true
# Format of the git tag, [*] gets replaced with actual version
# TAG_FORMAT: v*
Option 2: Modify/roll your own yaml properties file
IMHO for your Custom Libs, i.e. if you need something beyond the standard yaml properties and you need some more.
For e.g. in your final release stage, use the yaml deploy section to name it what you want using this lib.
# your previous yaml code ... there should be a section with the below tage configured and it will look for it an update.
The main differences is one targets the major and minor release of the tag names and helpful for Nuget packages.
The second one allows you to create something beyond and custom as a tag.

Append suffix to build number for features branches in Visual Studio Team Services

We version our builds with the following build number format:
1.0$(rev:.r)
In this way we can manually change major and minor version, but leave patch version incrementing:
1.0.1
1.0.2
...
However we would like to have a suffix appended to the build number format, so that if you queue build from a non master branch (e.g. feature branch, testing, hotfix), then you get a suffix (e.g. -beta, -rc, -preview). So we could have the following builds:
1.0.3
1.0.4-rc
1.0.5
...
This way it is easy for us to read from a version number if something is not coming from master, and care should be taken when deploying this version.
Is it possible to write an expression in the build number format so a string is suffixed if e.g $(SourceBranchName) is not empty?
You can append $(SourceBranchName) in build number format, but can’t append other content per to $(SourcebranchName) through build number format directly, in other words, no conditions available in build number format.
Refer to these steps to do it:
Add a PowerShell task (Inline Script):
$v=$env:BUILD_BUILDNUMBER
if($env:BUILD_SOURCEBRANCHNAME -ne "master")
{
$v="$v-rc"
}
Write-Host $v
Write-Host "##vso[task.setvariable variable=packageVersion;]$v"
Write-Host "##vso[build.updatebuildnumber]$v"
Change Automatic package versioning to Use an environment variable for NuGet pack or dotnet pack task, and specify packageVersion in Environment variable input box.
You can use GitVersion to do it. Install it from the marketplace:
https://marketplace.visualstudio.com/items?itemName=gittools.gitversion
Take a look here to understand how semantic versioning works.
You can learn more here.
This is a great tool to version your builds.

Conditional buildnumber in order to publish prerelease nuget package?

I'm automating the deployment of a nuget package.
It work fine except that I'm unable to set prelease package the way I want to.
There are two branchs triggering the build.
When the build is triggered by master branch, I want to publish a regular nuget package.
When the build is triggered by test branch, I want to publish a prelease package.
In order to do this, I need to add -beta to the nuget package version number.
So I changed the Automatic package versioning from use build number to use an environment variable.
See following img :
At first it was complaining about the variable saying No value was found for the provided environment variable, but I got around this issue by dropping the $(). But now I'm still stuck because I can't find a way to set the variable with Build.BuilderNumber and -beta. I could duplicate the build and have each build trigger for their own branch, but I would rather only have one build that can handle builds from both branchs.
So now I'm thinking about changing the setting back to use build number and change the expression that set the build number in tab options of the build. However, even there I'm unable to have a conditional expression on Build.SourceBranch to add or not the -beta.
Chris McKenzie seem to have had a similar problem here and resolved it with powershell. Unfortunately, I don't know powershell and couldn't understand because the script seem way too big for what I need. Still I believe their my by hope with powershell. So I will be looking in that direction to implement my conditional build number.
This question is getting quite long, so I've set in bold the key element to it.
Where and how could I put a condition on the source branch to have -beta appended to the BuildNumber and be used as the nuget package version?
You can achieve it by adding a PowerShell task to change the variable $(PackageVersion) conditional based on different branches.
Before NuGet pack task, add a PowerShell task with the script as below:
$branch1="test"
$branch2="master"
if ("$(Build.SourceBranchName)" -eq $branch1)
{
echo "the build is on $branch1"
Write-Host "##vso[task.setvariable variable=PackageVersion]$(Build.BuildNumber)-beta"
}
elseif ("$(Build.SourceBranchName)" -eq $branch2)
{
echo "the build is on $branch2"
Write-Host "##vso[task.setvariable variable=PackageVersion]$(Build.BuildNumber)"
}
else
{
echo "it's either on $branch1 branch nor $branch2 branch"
}
Now in NuGet pack setp, the package version will be $(Build.BuildNumber) if the branch is master; and the package version will be $(Build.BuildNumber)-beta if the branch is test.

Where is the nuget packages folder located on a hosted build server using TFS?

I need to execute a command line utility from a package that is downloaded as part of nuget package restore in the TFS build process.
On my local computer that is stored in c:\users\me.nuget*
I've tried every permutation of that on TFS without success. I've also tried \mydir\packages with no success as well.
The biggest problem is that I have to run the package restore step before being able to see any sort of feedback from the log. That's some slow debugging.
Any ideas? Thanks ahead.
With the latest nuget/msbuild the packages folder is held under the active user's profile directory, so an appropriate Powershell command is
Get-ChildItem $(UserProfile)\.nuget\packages
This currently evaluates on the VSTS 2017 Hosted build agent to C:\Users\VssAdministrator\.nuget\packages but by using the variable you are insulated from any changes made.
Just an addition to #Paul Hatcher's answer:
I also faced the same problem in Azure DevOps build pipeline where a specific package and nuget packages directory could not be found.
It is a Xamarin.Forms app based on a .net standard library where no packages folder exists. I later noticed in build logs that the packages are restored to nuget folder under user's profile. However this particular case is not documented on https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=vsts#agent-variables.
That means #Paul Hatcher's answer is also valid if you try to reference nuget package folder directly from your build pipeline. This ($(UserProfile).nuget\packages) should actually be a (standard) predefined build variable.
The Nuget package cache folder is in C:\Users\buildguest.nuget\packages, but it will be cleaned after build if you are using Hosted build server.
The simple way to verify:
Add NuGet restore or .Net Core Restore build step to restore packages
Add PowerShell build step to list files in C:\Users\buildguest.nuget\packages
Code:
Get-ChildItem -Path C:\Users\buildguest\.nuget\packages
Queue build and check the PowerShell step log (the packages’ will be listed in the log)
Remove/disable NuGet restore or .Net Core Restore build step > Save build definition
Queue build
The build will be failed, because the path does not exist.
So, the packages need to be restored before build solution/project if aren’t existing. You can add packages to source control and map to build agent to deal with the issue of too long time takes to restore packages.

VSO Build vNext - Nuget Package Build Step - Use build number to version package

I have my build number format specified as :
$(BuildDefinitionName)_$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r)
This creates build Numbers in the format of "BuildDefinitionName_2015.11.11.1"
Where revision seems to be the number of times the build has run for that day.
I would like to be able to use this value in further build steps.
For example I am creating a nuget package with the nuget packager step and am using the option "Use build number to version the package"
This creates me packages similar to this "PackageName.2015.11.11.1.nupkg"
I then want to use the nuget publisher build step to publish this, but the problem is that over time you get more than one package in the package folder and the nuget publisher step uses a pattern for matching packages to publish.
ie
"PackageName.2015.11.11.1.nupkg"
"PackageName.2015.11.11.2.nupkg"
"PackageName.2015.11.11.3.nupkg"
Without being explicit about the file to publish, the publisher step will publish all these files.
I don't want this, I just want it to publish the file which matches the current build number.
So I would like to be able to set the build number parts in the pattern.
ie PackageName.$(Year:yyyy).$(Month).$(DayOfMonth)$(Rev:.r).nupkg
But it appears that these variables do not get substituted in the search path and come through as a literal match.
It seems strange that in the nuget package step it gives you the option to create packages by build number, but then does not allow you to match this in the nuget publish build step.
Nuget Packager step use PowerShell script to get the build number. The source code is here: https://github.com/Microsoft/vso-agent-tasks/blob/84746169f19b7c3e3f67c0efa1a546c4107055fa/Tasks/NugetPackager/NuGetPackager.ps1
If you do want to transfer the build number to Nuget Publish, you can add a PowerShell step in your build process to get the build version number. Refer to the build version related code in the Source Code for details.
And in the end of the PowerShell script, add code:
Write-Host "##vso[task.setvariable variable=bversion;]$NewVersion"
This code create a variable “bversion” with build version number filled. Then you can use variable $(bversion) in your Nuget Publish step.
I would suggest to do a clean checkout of the source code in each build, which will solve the problem of having old package files lying around in subsequent builds.
Otherwise there's the $(build.buildnumber) variable which contains the expanded value of the build number, but as long as you have additionally the $(BuildDefinitionName) in the build number you won't be able to use it for the file name. See here for a list of available predefined variables.