Working with multiple TFS branches in Teamcity. How? - tfs

We are using TFS2010 for source control and TeamCity 8.x for CI. In our project we have Main branch for releases and bug-fixes and Dev for most of the development. Build steps for both branches are identical. and we have a few build configurations to go through:
I can't seem to make TeamCity to do checkout on a single branch and run build only on the branch that was checked-in to.
First attempt: I've added a VCS Root to point to $/Root that contains both Main and Dev branches and created checkout rules:
First checkin to Main works fine. Checkin to Dev after fails like this:
where DoNotExportAttribute is the file that was modified in the Dev branch. Even if I have
checkbox against "Clean all files in the checkout directory before the build".
My second attempt was to add both of the branches as VCS roots:
But this caused checkout of both branches into the same directory and whatever was checkout first was overwritten by second branch.
Is there a remedy for our case without creating separate configurations for every branch? (we started from config-per-branch, but that proven to be maintenance heavy for the number of steps we do in build)

If I understand correctly, you're trying to use a single TeamCity project for both your main and your branch builds. I would not recommend doing that. By re-using the same project for both your main and your branch builds, you will be sharing version numbers between two different beasts. Version 1.1.4 of the build might be a main build while version 1.1.5 might be a branch build.
By looking at the artifacts created by the build, it will also be difficult to identify which source code was the one selected and included into that artifact. Is the executable a main or a branch executable?
The way we solved the main vs branch problem was by creating a "template" project which contains all our build configurations (each one set up as a Build Configuration Template so they can all be changed in a single location) for building our software. Both the main line and the branch projects are created by copying this "template" project and setting the VCS root to the appropriate directory location.
We run five build agents and each build takes a fair amount of time. Having individual projects for each branch allows us to run builds in parallel if the main and any of the branches happen to have been modified at the same time whereas with one single project, the builds would be done serially.
Hope this helps.

Related

Can a TFS2015 script only Deploy (and not Build)?

I am new to the world of scripting with TFS2015. I created a script that builds all of the projects within my solution (it is a rather large solution) and puts it out in a shared folder (where each project has its own subfolder).
I would like to create a separate script for each project that simply copies the bin folder from the shared and pastes it out on my Test environment. I rarely need to deploy everything, so the idea is one build...multiple deploys.
However, when I run my deploy script using the Copy Files step it is doing another build. Although it copies the files that I expect, it is after a full build that creates the folder structure for the build.
Am I able to make the Copy Files step NOT do a Build?
Here is the steps that my script is curently doing:
As you can see, there is only one step (Copy Files) but it still does the Get sources and copies everything into a new folder on the build box like so (where the number keeps incrementing up with each run of the script):
I just want to copy the files from the Source to the Target and not do a build or Get Sources.
It looks like you're still on TFS 2015 RTM or Update 1. Which is already pretty old technology if you compare it to the lifetime of the new build system which was introduced with this version.
TFS 2015 update 2 has introduced a similar system to the Build pipelines to orchestrate Releases. This doesn't require you to map any workspaces or git repositories and can act on the artefacts of your builds or simply on the contents of file shares.
It makes sense that a Build has to build something and in order to build something, it has to get the things to build. If you're actually not building something, then you're probably deploying or releasing or packaging something else. Hence the distinction between Build and Release pipelines.
TFS 2017+ has an option to disable the syncing of sources. Primarily to allow people to get the sources themselves in creative ways (e.g. a custom powershell script that invokes git.exe).
My primary advice would be to upgrade to TFS 2018 update 3 or at least TFS 2017 update 3.1, worst case TFS 2015 update 4.1. The fact that versions older than update 2015.4.1 have a known XSS scripting security bug may be reason enough to convince your organisation to perform this update.
Barring that option you're left with one solution:
Link your build definition either to a git repository with only a single commit (If I remember correctly the 2015 agent still crashes when syncing an empty Git repo) or link it to a TFVC repository and set the workspace settings to cloak everything. This essentially causes the build to sync an empty folder, which it can cache, before calling your powershell script.

TFS (CI) - Only one branch has just been check-in/pushed to be built

I'm trying to deploy a Continuous Integration server where I work.
We used TFVC with the branch to release strategy, but we are having difficulty with something that should be trivial.
We only need the build on the branch that was checked in.
Is it possible to do this without having to change the build definition every time a new branch is created?
I do not want to map the entire folder structure of the repository. Imagine having 10 branches and every check-in, build all? Does not make sense!
Anyone have any idea how to do it?
The CI build for TFVC can’t map and just build target branch like build for Git.
There are some workarounds:
Clone a build definition and change source mapping, Path filters of triggers for each branch.
Add a PowerShell step/task to get recent check-in change by calling get changesets Rest API, then store the related solution/project files in a variable by using Logging Commands, then build these solutions/projects

Why do my TFS 2015 Builds only work on one branch/

I have an instance of TFS 2015 with vNext builds working on my DEV branch.
I cloned a working build definition and set the Maps and solution file to the corresponding paths on the Main branch. On the Main branch they fail with the error message: "Could not find a part of the path 'C:\agent4_work\5f9b9727\myTfsProjectName'." This path is not even being created in the _work directory like is when I use the paths for the Dev branch.
Notable similarities between the two builds:
The build steps being used in both cases are the NuGet Installer and Visual Studio Build steps.
Same code exists in both branches.
Notable differences:
Main is the parent branch of DEV
Main has an added permission group to deny certain users from checking in.
My TFS service account is not a member of this group so I don't that applies.
Note: If I change the clone to point to DEV, it doesn't fail.
Can anyone tell me how to solve this mystery? Thanks.
Edit:
I found another difference the working branch has that the Main branch doesn't.
I don't remember adding the Project Build Service to the Dev branch. I also don't know why Main did not have this security setting. After I added the same security credential to Main, builds on Main started working. This raises another question: Does one need to add the Project Build Service to every branch as a second step in order to perform TFS builds?
Usually, the Build service account should be created and added to code repository automatically when the project is created and it will be inherited in every child folders. So the user does not need to add it to other branches/folders manually. For your case, I'm not sure if the user is removed unexpectedly or any other things happen.
Have you set "Items To Build" to correct path?
In Build Definition->Process-Items to build
screenshot from Build Definition

Building version branches in TFS with TeamCity

I'm looking at using TeamCity 7.1 as our build server, and I am trying to figure out if it is possible to do what I want.
Our TFS branching looks like this
MyProject
tags
1.0.0.0
1.1.0.0
2.0.0.0
trunk
So our process is to work in the trunk, and when we reach a point where we want to deploy, then we create a branch with that code. In the above example, version 2.0.0.0 is in production, and the trunk has further changes made to it. So if I need to fix a bug in production, then I will fix it in the 2.0.0.0 branch.
I am able to set up a build that checks out the trunk, runs tests, etc., without any problems, and it can be triggered by checkins to the trunk. But I would like to also monitor all the version specific branches, so that when I check in a bugfix in the 2.0.0.0 branch, then a build is triggered, and all my tests are run.
It seems that some of the VCS options have had a new feature added to support this called "branch specification" (https://tom.cabanski.com/2012/11/19/teamcity-7-1-branch-builds-rock/) but that is not available on a TFS VCS root.
Is it possible to do this without creating a separate build configuration for each of my version branches? Or is there a way to manually launch a build of a specific branch, by using my existing build configuration for the trunk?
Since "feature branches" are not supported for TFS in TeamCity (only for Git and Mercurial at this time), creating separate build configurations is the best way to build separate branches. Actually, even for Git and Mercurial creating separate build configurations for long-lived version branches (as opposed to feature branches which come and go) is recommended.
I am not sure how branches are handled in TFS, but if you use tags, I believe there is no way to build off a TFS tag in TeamCity (TW-7370).

How to limit TFS 2008 CI Build to a particular path in the project

If you follow some of MS's recommended branching strategies you can easily end up with a project structure such as:
$PROJECT\
DEV\
MyProject
STAGE\
MyProject
PROD\
MyProject
Now let's say I have three different build definitions. One each for DEV, STAGE, and PROD. This should be common considering that the build definition will define the exact solutions to build.
If I turn on CI for each of them, STAGE will be built even though the checkin occurred in DEV...
Now my question. How can I limit the build definition to execute only when a check in occurs in either a path or a solution that is part of the build definition?
When defining the working folder configuration screen - only have it start at the root of the branch you want to build.
For example, your DEV branch would be configured so that $/TEAMPROJECT/DEV/MyProject was mapped to $(SourceDir) rather than the default mapping which would have been set to just $/TEAMROJECT.
FYI - Personally, I only have CI Builds on Dev branches and queue manual builds for a push to QA. I also normally don't do a re-build for production but just push the build binaries that were QA'd. I also keep by build configuration folder inside the branch i.e. $/TEAMPROJECT/DEV/TeamBuild rather than the default $/TEAMPROJECT/TeamBuildTypes and therefore changes to the build configuration are also pushed up through the branches. That said, you have to stick with the default if you wanted the build configuration to be visible to VS2005 clients.
Hope that helps,
Martin.

Resources