Our TFS 2013 admins have given us one build definition to build our solution and run all unit tests and they are not willing to create any more build definitions. We are following feature branch strategy and would like to use this build definition for our gated builds. I am trying to find how to use this one build definition with multiple branches.
I know, I can add all branches to Source settings and build them whenever a check-in is made. But I want to find out, if there is any way to add branches to Source settings, but only compile the solution that has been checked in. For example if we add 5 solutions to the Source settings, we want to compile only the solution that has changed rather than all 5 solutions.
You will need to setup an incremental build that only builds the solutions that have changed.
Ideally you will want to setup a build for every branch. You would still use the one build template given to you, but you would define the work-spaces and behavior differently for each branch depending on your needs. However if you do not have that option you can still implement what you are trying to do.
For example if you only want to build the solution that has changed you will set up your build to be an incremental build like the following:
In the "Process" tab update the "Items to build" section to any *.sln or *.*proj
In the "Workspace" section, select only the source control paths of each branch if setting up a build for every branch or select the entire source if that is how you have to do it ($/).
Change the build to an incremental build by changing the Build Process Parameters on the "Process" tab - CleanWorkspace=None
Tag one of the build agents, so that it is the only one used for these incremental builds. Set the build to only use this tagged agent. It is important that the same build agent or set of agents is used for the builds if incremental builds are to work.
Related
Our builds generally have a mish mash of work items and commits associated with them and I cannot tell how TFS determines what to add. We are using TFS 2015 update 3 and TFVC.
When a build runs, it gets code from a location somewhere in the branching and folder of TFVC. Typically, something like "root\dev\src\component name" in this way we avoid getting all of the code in our repository and we have CI set up to run so that any changes in this folder will result in a CI build running.
We also run daily builds which run more tests and create a release package that is used by TFS Release Management. I would expect that any changes to code inside of the folder defined in setting up the repository for this build to be included in the associated change-sets of a build. I also expect that any changes checked-in outside of these branches would not be associated. But this is not the case. We see commits from across the entire project.
Does anyone know how this is supposed to work?
I am not sure if this should go in the question or the answer but I have found some additional information, thanks to the hints provided in the answers below.
It appears that the source settings will take the common root between mapped folders of the repository settings, so if I have 2 folders $/Relo/Dev/B1/src/Claims.Services and $/Relo/Dev/B1/src/PSScripts it will take the common root $/Relo/Dev/B1/src as the source settings and include any changes from that folder down within the build. Can anyone confirm this? Of course thats not what I want to have happen. In the History tab of the build definition if I looked at the diff I can see a field "defaultBranch" in the json which seems to be the value that controls this, is there any way to update this field directly?
TFS determines what changesets should be mapped to a build based on the Source Repository Mappings (Build vNext) in the build definition and the last successful build.
So, you will see a list of the changesets with files committed in the lowest common base of any of the mapped folders including all their descendents, since the latest successful build. Whenever you get a successful build (I hope that it happens more often than failing ones ;-)) the list will shorten and only show the last check-in.
Example mappings below will result in any changeset made to anything below $/Relo/Dev/B1/src (because it is the lowest common base):
$/Relo/Dev/B1/src/Claims.Services
$/Relo/Dev/B1/src/PSScripts
Similar it will pick up all the related work items to the above changesets.
This is what should happen. If you see something else, I would have a closer look at the Repository Mappings or Source Settings of the build definition.
#Noel - I guess you are using vNext build and not XAML builds. Or are you using a mix of XAML and vNext?
In general a scheduled TFS build will associate all changes which were not associated in the last successful run of the same build.
I suggest you check once again if the source folder locations are the same for CI build and Daily build?
We use TFS source control and have two build controllers (one VS2010 the other VS2012). We use the default build workflow template bar a few custom changes.
As we have many branches, how would we go about changing the workspace based on the desired branch?
I was thinking of adding a parameter for the branch ($\oursourcecontrol\branches\main) and then just passing it as a variable in to the get workspace part of the workflow.
Or is there a better way of doing it?
You currently can't and it is really a shame. It would completely break the Trigger support for CI and Gates checkins. You can use the TFS Community Build Manager to quickly clone and adjust build definitions to support multiple branches though.
What you could do, is to fetch more than you need (say $/Sourcecontrol/Branches/*) and then use a string-replace on any path parameter (like solutions to build, test settings file etc) to point them all to the correct solution. You'll probably need to do some templating like {BRANCH} so that you can easily replace these tokens.
The Git build template does support this on a Git repository, but you'd need TFS 2013 to make use of server side Git support.
I mapped the server path in the Repository tab at higher level that TFS branches are contained. Cloak rest of the branches not required for Get sources step except the branch to be built. And create variable to pass the branch name, check allow at queue time. Use this branch variable in build steps to make the build definition work for all the branches. You may need more than one variable based on your branches structure in TFS.
Is there a way to create a build definition, in TFS 2010, that uses continuous integration trigger, and only builds the project who's code changed.
To clarify, what I'm searching for is the following scenario:
1 Solution
x Projects in Solution
1 Build Definition per Project
All Builds are CI triggered
When a check-in occours in a project only that project gets built and tested.
Place in your build definition's "Items to build" section of the "Process" tab any *.*proj instead of a *.sln.
In the "Workspace" section, select only the source control paths that relate with this project.
In the process tab, set "Clean Workspace" to "None", use "/t:Build" on the "MSBuild Arguments" and properly configure your projects and their dependencies in the solution. This way on each build, you will be getting the latest code, and then building whatever was modified, and anything that depends on it. This is much more dynamic and requires only one build definition. Let the build system operate as it was designed and leverage the optimized build process.
In the TFS 2010 build definition window, under “Process” there are two required items. They are “Configurations to build” and “Projects to build”. Under projects to build, it will allow me to enter something like:
$/TeamProject/Area1/Area2/*
However, this doesn’t seem to do what I expect. The build fails because it’s looking for:
$/TeamProject/Area1/Area2/Sources/*
What I am trying to achieve by this is to build all the solutions held under this area. For example, I have:
$/TeamProject/Area1/Area2/Solution1/Solution1.sln
$/TeamProject/Area1/Area2/Solution2/Solution2.sln
$/TeamProject/Area1/Area2/Solution3/Solution3.sln
There are many more solutions than this, which is why I’m looking for a way to build all solutions under the specified path recursively. Is there a way to do this in TFS 2010?
You can modify the process template. Expand it with the Matching files (I don't have the exact naming now) activity. Add a parameter that passes the information you set in the build defintion to the MachingFiles actvity. Then pass into the build solution activity instead of the argument that you enter in the build definition the files that is found by the MatchingFiles activity.
Now add a dummy solution in the build definition for the solution to build (it is not used anymore).
See the blog post series on the build customization for more information on customizing the build process template.
FWIW,
I've got: "configurations to build" blank
and under "projects to build" I've added my solutions via the ellipsis button
I would setup mappings for
$/TeamProject/Area1/Area2/Solution1/
$/TeamProject/Area1/Area2/Solution2/
$/TeamProject/Area1/Area2/Solution3/
Then in the build definitions enter the three projects to build
$/TeamProject/Area1/Area2/Solution1/Solution1.sln
$/TeamProject/Area1/Area2/Solution2/Solution2.sln
$/TeamProject/Area1/Area2/Solution3/Solution3.sln
You can leave the configurations to build as blank, or if you want to do a certain build you can set it to (for example) something like Debug|Mixed Platforms (check your Configuration Manager... for the solutions you are building to see what is valid)
Alternatively, you can just map the following (depending on how much you have in this folder, if you have Solutions 4+ that you don't want to trigger builds on, don't do it at this level)
$/TeamProject/Area1/Area2
And have one solution which contains the Solution1, Solution2 and Solution3, and build that instead.
By default building your Solution1 which is mapped to
$/TeamProject/Area1/Area2
On a build agent with a working directory that is going to looks something like:
$(SystemDrive)\Builds\$(BuildAgentId)\$(BuildDefinitionPath)
You'll end up with it being build under
C:\Builds\1\Solution1\Binaries
C:\Builds\1\Solution1\Sources
C:\Builds\1\Solution1\TestResults
Which is why you want to make sure that your OutDir's etc are all correct and not hard coded!
If you have a look while building, you'll see the build agent populating the Sources folder, and it should (if configured correctly) put all outputs into the Binaries folder (and then copy them to the Drop Folder configured under Build Defaults in TFS.
We are using TFS Build 2010 for Builds. We have two branches of source code (Lets say branchA and branchB).
Now as a part of the build definition we set the projects to build:
Now to employ the same build definition from branchB will mean that I create another build definition file with same content, with only the items to build set to "$/branchB"
Is there anyway to make this configurable, without having to edit the build definition?
Also there are other input variables that we set for the build definition, and the values for these variables are included in the build definition XAML file. So to change the value of a variable will mean that we have to edit the build definition XAML file. This is not desirable.
I would like to be able to set the "Items to Build" and the variables of the build definition without having to modify the build definition XAML file.
Are there any solutions to these problems?
You can modify the Build Process Template so it only asks you for the Items to Build. The rest of the arguments are prefilled. To get an idea how this works, see http://www.ewaldhofman.nl/?tag=/build+2010+customization
You can add parameters to your build definition. I did this a while back because we had two web projects in a solution that had to be deployed to different servers (via Windows shares). I added parameters to the build def so that in the build properties I could customize them depending on if it was a dev deployment, staging, etc.
I added a blog post on how to do it. You can use the parameters this way so that they aren't kept in the XAML file.
Deploying Web Apps with a customized Build Process in TFS