TFS 2017 Build with Multi-Configuration and Task Group - tfs

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

Related

How can I get the numbers of folders in _work folder in agent?

I want to get the number inside the _work folder of an on-premise TFS agent.
For example:
From C:/agent/_work/1 get the 1.
Is there a variable to get the 1 part?
You can use a small PowerShell script to extract the number and set a new variable for the sequences steps:
$folderPath = "$env:Agent_BuildDirectory"
$folderNumber = $folderPath.Split('\')[$folderPath.Split('\').Count - 1]
Write-Host "##vso[task.setvariable variable=folderNumber]$folderNumber"
Now you can use the variable $(folderNumber) in the sequences tasks.
There is no reason for you to parse this information out. The current working folder for a given build or release is accessible in the variable $(Agent.BuildDirectory).
If you are trying to reference the working folder of a different build, then you are doing something wrong with your build process, and there are a number of different, valid solutions to that problem.
Check out the different variable values and ways to customize them if needed. Note the Agent.DeploymentGroupId is is not something you would change.
Release variables and debugging
Agent.DeploymentGroupId
The ID of the deployment group the agent is registered with. This is available only in deployment group jobs.
Example: 1
Agent.WorkFolder
The working directory for this agent, where subfolders are created for every build or release. Same as Agent.RootDirectory and System.WorkFolder.
Example: C:\agent_work

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

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

How can I get value "RequestedBy" in tfs 2013 build?

In tfs 2010 build, it's easy to get that vale using "BuildDetail.RequestedBy". what's the equivalent in TFS 2013? I couldn't find "BuildDetail" even.
It's still build detail. However, in the new templates a lot of the complexity is hidden by default. Use the GetBuildDetail activity to retrieve the variable you need.
Thank you MrHinsh
It's very good suggestion!! Really appreciated!!
The value of "RequestedBy" is actually required by powershell that need to be invoked at later stage to log people name whoever trigger the build.
The following steps are what I've done to make "RequestedBy" value available in powershell script:
In TfvcTemplate.12.xaml, create variable "myBuildDetails".
Drag "GetBuildDetail" into template and specify "myBuildDetails" as result of it.
Modify "Run optional script after Test Runner" property "EnvironmentVariables", set it's value to "New Dictionary(Of String, String) From {{"RequestedBy", MyBuildDetails.RequestedBy}}"
In my ps1, the value can be retrieved by "$Env:RequestedBy"
It's not perfect solution, but it's working.
Instead of modifying build template,I though if we could inject expression something like "$(myBuildDetail.RequestedBy)" from script argument of build definition would be much tidy solution.

TFS Build Template Nested Arguments

Is it possible to nest TFS build template arguments in one another?
Example (Set via build definition ui):
$(ToolsRoot) = E:\BuildTools
$(MSPECTools) = $(ToolsRoot)\MSpec\
Alternatively, is it possible to use environmental variables.
I have tried both, and neither seemed to work.
I need to find a way of setting the build root dynamically, as it differs on our various build servers.
I suppose you have implemented a topology like the this:
So, you need to control the root for each Agent.If you open the TFS Admin Console > Build configuration in Build Machine #1 you 'll see the Build Controller & Agents A.1 & A.2.If you open TFS Admin Console > Build configuration in Build Machine #2 you 'll see Agents A.3, A.4, A.5 & A.6.
For any given build Agent, if you click on "Properties" you 'll see the "Working Directory" entry, which typically is set to something like $(SystemDrive)\Builds\$(BuildAgentId)\. On runtime this is transformed into something like C:\Builds\55.
For any given build, in the build definition area "Workspaces" this "Working Directory" equals the entry $(SourceDir).
Suppose you have set in Agent A.1 a working directory "C:\A.1\Build" & in Agent A.2 "C:\A.2\Build". In order to get what you need, you have to set in the build definition a mapping to $(SourceDir)\Template

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