Conditional buildnumber in order to publish prerelease nuget package? - azure-devops

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.

Related

Azure DevOps Release Pipeline - How to get the source code that was used to create the build artifact?

I have a continuously triggered Azure DevOps release definition that deploys a compiled Angular app to a web server and also runs Cypress e2e tests. The Cypress tests must run against the source code, so that means I need an artifact that is able to reference the same commit that was used to create the compiled app.
I created a GitHub artifact that gets the source code, but I can't figure out how to automatically change the branch/commit to whatever was used for the compiled app (it could be any branch and the names are not known ahead of time). Azure forces me to enter a hard-coded branch name and it does not accept wildcards or variables.
If I could simply use the variable ${Release.Artifacts.{alias}.SourceBranchName} for the default branch, I think I'd achieve my goal. Since Azure doesn't allow this, is there an alternative approach that accomplishes the same thing?
Note 1: The "Default version" dropdown has an option "Specify at the time of release creation", but that is intended for manual releases and can't be used for triggered ones, so no luck there.
Note 2: I looked into publishing the source code as an artifact, but it currently has almost 70,000 files and it adds more than an hour to the build step, so that also is not an option.
When you use the Release Pipeline artifacts, you are not able to set the pipeline variable in the Default branch field. This field only supports hard-coded.
is there an alternative approach that accomplishes the same thing?
The variable:$(Release.Artifacts.{alias}.SourceBranchName) can be used in the Release Pipeline agent job.
Workaround:
You can remove the Github artifacts and then add a Command Line task/PowerShell task/ Bash task to run the git command to clone the target repo.
For example:
git clone -b $(Release.Artifacts.{alias}.SourceBranchName) GithubRepoURL
PowerShell sample:
In this case, the script will use the same branch as Build Artifacts to checkout the source code.

Is there a way to validate a package is built off a particular branch as part of build in VSTS DevOps?

As part of a project we are using some in-house npm packages. These have a simple branching strategy of 'develop', 'release' and 'master'. Our project will reference this package, but we want a way to make sure that when we go to release, that the package referenced has been built off the release branch for that package and not the develop one.
Is there a way to fail a build if the package hasn't been built of a given branch?
So you want some way to tag your builds as "release candidate" when they come from specific release branch. There are many different ways to do this.
For example, Azure Pipelines has some built in variables:
https://learn.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml
You see we have a variable : Build.SourceBranchName
You can use this in a number of ways. For example you could write this into a build-notes.txt and package it into your artifact. Or depending on how you package your artifacts, you may be able to tag this information in somewhere.
e.g. NPM supports something called dist-tag : https://docs.npmjs.com/cli/dist-tag
Your release pipeline then just needs some logic to read this and validate.

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.

nuget push wildcard in TeamCity

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).

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.