How to start vNext TFS 2015 build revision at a specific number - tfs

I am using the vNext build system of TFS 2015.
I currently have the my builds versioning in the traditional format. Major.Minor-rev.RevisionNumber. So, if I have a build for Major 1, Minor 12, the build version would look like 1.12-rev.1 when I start. I would like to know if it is possible to have the build version start at a number other than one, say 55. Such that the build version would look like 1.12-rev.55, and then increment by one as usual after that.

Actually, it is possible to effect this in a vNext build without hacking the database.
There are 2 steps.
First, you will need to implement a powershell build step (as the first step of the build) with the following inline script:
#Set the BuildNumberOffset. (Change this to the difference between the TFS build number,
#and the number that your build needs.)
$BuildNumberOffset = 543
#Don't change
$BuildNumberParts = $($env:BUILD_BUILDNUMBER) -split '\.'
$TFSRevision = [int]$BuildNumberParts[$BuildNumberParts.Length-1]
$BuildNumberParts[$BuildNumberParts.Length-1] = ($TFSRevision + $BuildNumberOffset).ToString()
$BuildNumber = [string]::Join(".", $BuildNumberParts)
Write-Host "##vso[build.updatebuildnumber]$BuildNumber"
Second, on the Label format field of the repository tab set the label format to "$(Build.BuildNumber)" instead of "$(Build.DefinitionName)$(rev:.r)". This is important so that your label will be the same as your updated build number.

There is a way to do this. It isn't pretty, but it works.
Assuming you have a build number format of something like $(Major).$(Minor)-rev$(rev:.r)
To do this queue up a build which will get the number 1.12-rev.1. Then go to the TFS database and into a table called tbl_Build. Find that last build you did and change the value in the BuildNumberRevision column to 54.
The next build that fires off will now be 1.12-rev.55

Unfortunately, it's impossible.
Every build definition has a build number format field where you can use some macros to dictate what the resulting build number should look like. In this format we are using $(Rev:.rr) Its start by one.
What is $(Rev:.rr)?
To ensure that every completed build has a unique name. When a build
is completed, if nothing else in the build number has changed, the Rev
integer value is incremented by one.
Source:MSDN
Moreover, if you want to generating a custom build number without increment.
Here is a blog with detailed procedures:Generate custom build numbers in TFS Build vNext

Couldn't we just manually set this in the format for one build i.e:
$(Major).$(Minor)-rev$(rev:.54)
and then afterwards revert back to:
$(Major).$(Minor)-rev$(rev:.r)
Not tried it, but if it works it'll save hacking around in the database.

You can do this easily, but only if you are using a Git repository in conjunction with a tool called GitVersion
It is a wonderful tool that I always use with my git repos. For your use-case: When you have version 1.2.3 and you want to jump to version 1.2.55, you just add a git tag 'v1.2.55' and it will start the versioning from there. GitVersion is a lot more complicated and does a lot more, but that is one of the features. You don't have to mess with special PowerShell scripts or anything, it instead reads your git repo history and git tags overrides the calculated versioning. There is already a TFS/VSTS/Azure Devops extension called GitVersion that works great from the same developer.

The Answer of #Steve Sims works still with TFS 2017 vNext. Thanks a lot!
I had only to do the first step "to add the script as an inline powershell script in my build." Thanks to #PainElemental
With this "Build number format" in the Options-Tab it works:
$(BuildDefinitionName)_1.2.0$(rev:.r)
I didn't label my sources with the build, so I don't checked:
Second, on the Label format field of the repository tab set the label
format to "$(Build.BuildNumber)" instead of
"$(Build.DefinitionName)$(rev:.r)". This is important so that your
label will be the same as your updated build number.
I think, you can edit the Label Format on the "Advanced" GetSources Options. (usually hidden).

This was also very painful for us, migrating from a existing CI system with it's own build numbering, we needed build numbers to increment from a specific value. Hacking databases wasn't allowed in the organisation, offsets seemed a cludge.
In the end, we used an AutoIt script to start and stop builds and delete the build result using the WebUI and left it running. Not nice, but it did the job.
Needs tweaking for screen resolutions and such, timings also perhaps. Use AutoIt Window Info to find the button locations, make sure browser is fullscreen (not windowed) Run it for a few cycles to ensure it robust before setting the loop larger.
#include <AutoItConstants.au3>
;Increment TFS build count (Chrome browser buttons locations). Start from build result page.
For $i = 1 To 15 Step 1
ConsoleWrite ( "Loop " & $i & " of 5" & #CRLF )
Sleep(200)
MouseClick($MOUSE_CLICK_PRIMARY, 1800, 200, 2)
Sleep(500)
MouseClick($MOUSE_CLICK_PRIMARY, 1150, 881, 2)
Sleep(2000)
MouseClick($MOUSE_CLICK_PRIMARY, 1800, 200, 2)
Sleep(500)
MouseClick($MOUSE_CLICK_PRIMARY, 1055, 165, 2)
Sleep(10000)
Next
TFS/Devops is a really immature CI system, and it's not a patch on what we were running. Unfortunately corporate policy said we move to TFS, as nobody ever got fired for buying Microsoft products (but plenty of people should have got fired for buying them/forcing them where they don't belong).

Related

How can I have unique build numbers across branches with Jenkins & the Pipeline Multibranch Plugin

We are using Jenkins Pipeline Multibranch Plugin with Blue Ocean.
Through my reading, I believe it is quite common to tie your project's build number to the Jenkins run, as this allows traceability from an installed application through to the CI system, then to the change in source control, and then onto the issue that prompted the change.
The problem is that for each branch, the run number begins at 0. For a project with multiple branches, it seems impossible to guarantee a unique build number.
You can get the Git branch name from $GIT_BRANCH and add this to $BUILD_NUMBER to make an ID that's unique across branches (as long as your company doesn't do something like get themselves taken over by a large corporation that migrates you to another Jenkins server and resets all the build numbers: to protect against that, you might want to use $BUILD_URL).
Only snag is $GIT_BRANCH contains the / character, plus any characters you used when naming the branch, and these may or may not be permitted in all the places where you want an ID. ($BUILD_URL is also going to contain characters like : and /) If this is an issue, one workaround would be to delete unwanted characters with tr:
export MY_ID=$(echo $GIT_BRANCH-$BUILD_NUMBER | tr -dc [A-Za-z0-9-])
(-dc means delete the complement of these characters, so A-Z, a-z, 0-9 and - are the characters you want to keep.)
Maybe instead of a unique (global numeric) build number you might want to try a unique (global) build display name?
According to "pipeline syntax: global variables reference" currentBuild.displayName is a writable property. So you could e.g. add additional information to the build number (in order to make it globally unique) and use that string in subsequent artifact/application build steps (to incorporate that in the application's version output for your desired traceability), e.g. something like:
currentBuild.displayName = "${env.BRANCH_NAME}-${currentBuild.id}"
Using the build's schedule or start time formatted (currentBuild.timeInMillis) as a readable date, or using the SCM revision might be also useful, e.g. resulting in "20180119-091439-rev149923".
See also:
https://groups.google.com/forum/#!msg/jenkinsci-users/CDuWAYLz2zI/NLxwOku4AwAJ
https://support.cloudbees.com/hc/en-us/articles/220860347-How-to-set-build-name-in-Pipeline-job
One way is to have a Job that is being called from all branches and using it's build number. That job can be just a normal pipeline job with a dummy Jenkinsfile like echo "hello". Then just call it like this
def job = build job: 'build number generator', quietPeriod: 0, parameters: [
string(value: "${BRANCH_NAME}-${BUILD_NUMBER}", name: 'UID')
]
def BNUMBER = job.getNumber().toString()
currentBuild.displayName = "build #"+BNUMBER
echo BNUMBER
Not sure if that UID parameter is needed but it forces all calls into "build number generator" job to be unique so Jenkins wouldn't optimize builds that happen at same time to use same "build number generator" job.
You can use an external service to manage a unique build number for your project. It helps to get unique build numbers across branches and across CI servers too.
https://www.nextbuildnumber.net/

TFS 2017 Build with Multi-Configuration and Task Group

I have a TFS 2017 build that was setup with multi-Configuration that has a multiplier of BuildConfiguration. This worked fine with until I took all the build steps and moved them into a Task Group. Now I get an error that seems to indicate that it's looking at the full string of the variable BuildConfiguration dev,int verses iterating over it. Does this not work with Task Groups?
Based on my test, Multi-Configuration is not available for Task Group.
When you select all the build steps and create a TaskGroup, you need to set Multi values (eg : Release,Debug) for the buildConfiguration.
But during the build it will meet this error message :"Error MSB4126: The specified solution configuration "Release,debug|Any CPU" is invalid"
To correct that error, you need to set it as unique value (eg :Release ) or leave it as empty. Thus the build works, but actually it's not the real Multi-Configuration build even though it displays Release and Debug there. (You can check the build log for the "Multi" builds, you will see the actual msbuild command with argument )
I have submitted a feedback here for this issue, hope achieve it in future.
I figured out how to make it work.
My problem was the BuildConfiguration variable that gets created in the Task Group has to be set to refer back to the BuildConfiguration variable at the Build level (may be using the wrong term here...).
So instead of setting the Task Group var to dev,int I had to set it to $(BuildConfiguration) which refers it back.
So my task group variables look like this (I highlighted the BuildConfiguration var that was my issue):

TFS Online - start $(Rev.r) from 0

I am using $(Rev:.r) in my build number.
Major.Minor$(Rev:.r)
This works perfect and increments on every build and gets reset if the the major or minor version gets changed.
But the numbering starts at 1 and not 0. So the first build is not 1.0.0 but 1.0.1 which is not really what I am going for.
So is there a way to make the Revision start at 0?
Thanks for the help...
P.S. Unfortunately it is not possible to use Git and GitVersion in this project.
No, this can't be achieved.
What is the Rev?
Use $(Rev:.rr) to ensure that every completed build has a unique name.
When a build is completed, if nothing else in the build number has
changed, the Rev integer value is incremented by one.
Source Link: Build number format
Moreover, anytime you change your Build Number in a TFS build, the revision resets to 1. It' by default, you could not change this value. Since if you could be able to set the value start from 0, it's also should be able to set it start from 100. This will mess up the build number.
This might be old thread but I have found a solution that worked for me.
I have variables for MinorVersion and MajorVersion. Then created my own Revision variable called RevisionVersion and made a counter expression like that:
$[counter(format('{0}.{1}',variables['MajorVersion'],variables['MinorVersion']), 0)]
And now build number can be set as
$(MajorVersion).$(MinorVersion).$(RevisionVersion)
If MajorVersion or MinorVersion changes RevisionVersion is reset to 0. This gives 1.1.0 build number format and with every new build Revision part is increased by 1.
As a workaround to reset the revision number, you could create a clone of the existing build definition and kick off a new build with the recently created definition. This will initiate a new build starting at revision # 1.
Here is how to clone the build definition, click on the 3 dots next to the definition title under Build definitions page. Refer the screenshot below;
Click here to view screenshot - clone a definition
As like 1.0.0.1 if you have set the format to be 1.0.0$(rev:.r) in the build format field.
Otherwise resetting the revision # within a build definition isn't possible. I have tried deleting earlier builds and also tried manually setting the build number to 1.0.0.0 to reset but nothing worked.
Here's how I do it.
I use branch name to set the version number. I create a branch called release/1.2.3 to create a release 1.2.3. I suppose one could use variables.
Hence my trigger will be on the release/* branch
I will then create a counter from the branch name which will be reset every time I change the branch name.
variables:
buildCounter: $[counter(variables['build.sourceBranchName'], 0)]
And, finally, I'll use this in the name after the variables block.
name: $(build.sourceBranchName).$(buildCounter)

One of configurations from matrix gets cancelled every time

I have two projects and with dependencies so that project A is started, it updates files from git and then runs a multi-configuration project B, which:
has three axes: "foo", "bar" and "baz" with 11 x 4 x 2 items
I'm going to call the values like fooN for item N from axis foo, etc.
has a configuration filter, ruling out the last axis by running only when
baz=="baz1" (maybe in a later phase we'll want to run also tests with baz2
for baz)
runs a shell script that only cds and calls python interpreter with a script
cd /path/to/scripts
python test_${bar}.py
So when the project is run, I expect 44 configurations to be tested. But only 43 are.
It's always the same configuration (which happens to be the last one triggered, as Jenkins seems to remember the order(?)) that does never run at all:
in the final matrix looks as a gray dot with "Disabled" tooltip
in Console output, after saying "Triggering bazN,barN,fooN" for all 44 combinations,
then "bazN,barN,fooN completed with result SUCCESS" for all except the last one, but
the last one seems to be always cancelled/aborted:
baz1,bar7,foo3 appears to be cancelled
baz1,bar7,foo3 completed with result ABORTED
Console output for the single combination is not available---it looks like it never
has been built
Jenkins log does not show anything interesting about "baz1,bar7,foo3"
What does this mean? Any other pointers how to troubleshoot this?
Edit: I tried adding a "HTTP ping" script to the repo and called it from above script,
just before the python test_${bar}.py part. Which proved that for the affected
configuration, Jenkins does not even run those lines.
Without knowing how you got here to begin with (probably a bug):
Append configure to the URL of the disabled configuration, and in the resulting form, uncheck Disabled and Save.
Not really an answer, but as a workaround to the problem, cloning whole project to a new one helped: with the new project, all configurations ran normally.
This is a solved Jenkins issue:
https://issues.jenkins-ci.org/browse/JENKINS-19179
By the Matrix Project plug-in, version 1.4:
https://wiki.jenkins-ci.org/display/JENKINS/Matrix+Project+Plugin

How do I "map" certain return value of a script to "yellow" status in Jenkins?

In Jenkins there is a possibility to create free project which can contain a script execution. The build fails (becomes red) when the return level of the script is not 0.
Is there a possibility to make it "yellow"?
(Yellow usually indicates successful build with failed tests)
The system runs on Linux.
Give the Log Parser Plugin a try. That should do the trick for you.
One slightly hacky way do do it, is to alter the job to publish test results and supply fake results.
I've got a job that is publishing the test results from a file called "results.xml". The last step in my build script checks the return value of the build, copies eihter "results-good.xml" or "results-unstable.xml" to "results.xml" and then returns a zero.
Thus if the script fails on one of the early steps, the build is red. But if the build succeeds its green or yellow based on the return code it would have retunred without this hack.

Resources