Changing Config based on Build Definition TFS 2012 - build

I have one code base but multiple clients. Is there a way that I can use a build definition to build out to separate IIS folders and also change the config for each client as well rather than changing it in source and build them one by one.
I'd even be happy enough with having one build defination for each client that changes only what it needs to from the code in TFS.
Thanks!

You can create a Configuration like the current "Debug" configuration in Visual Studio which will be associated with your solution. You can then have any web applications create a Web.Config transformation for each of those configurations:
Web.Config
--Debug.Web.Config
--Customer1.Web.Config
--Customer2.Web.Config
--Customer3.Web.Config
--Customer4.Web.Config
You can then edit the Build Definition and instead of just building the default configuration for the solution during the build you can tell it to build all 5 configurations.
Figure: Add multiple configurations to your TF Build Definition
It does not matter if the item (i.e. "Customer1") is not in the drop down, as long as it matches Visual Studio it will work.
This will result in:
\\DropFolder\[BuildDefenition]\[BuildDefenition]_[BuildNumber]\[configuration]\*
So if you want to get Customer 1's instance you pull from:
...[BuildDefenition]_[BuildNumber]\Customer1\_PublishSites\*
You can find how to create configurations on MSDN: http://msdn.microsoft.com/en-us/library/kwybya3w.aspx

Related

What constitutes a workspace mapping when creating a new build definition?

We've been using TFS 2015 for a few years. I've got TFS 2018 installed on a test server and am experimenting with it. I want to make a new build definition to a project I have in an TFVC repo, in TFS 2018. So, creating a new definition I have selected the source as TFVC. Next it asks for a Workspace mappings, which I'm not clear as to what that is in this case. It defaults to the team project in the TFS repo, in this case it's $/RodTest. However, I don't want to choose that, because there are several projects within the RodTest team project. Instead I want to only create a build definition for one project named FindNonAscii. So, I figured I could do one of two things:
$/RodTest/FindNonAscii
$/RodTest/FindNonAscii/FindNonAscii.sln
Which is the correct mapping I should use?
Mappings are recursive. Map the root folder and anything underneath will be downloaded.

TFS Build 2015 - Using Globally Referred Files in Every Build

So, we are in this process of migrating XAML Builds to vNext (2015) Builds on TFS, and we are trying to "do things as clean as possible", since we had many, many customizations on the XAML builds that could be avoided and actually gave us problems along the way.
One major issue we are facing is with paths and "global files". Let me explain:
There are some files that, for commodity reasons, we have on a single place and every SLN file on that Collection refers them. Those files are such ones as Code Analysis RuleSets, Signing Files (SNK), etc. So the change is made in one place only and it affects every build.
Well, in XAML Builds we have a Build that runs with CI that downloads (Gets) those files, and since we hammered-in the same exact pathing for TFS and Machine (with a environment variable for the beginning of the path), the path is the same on the Developers and Build machines. However, this creates dependencies between builds and workspace issues.
My question here is, is there a configuration that I am missing that allows referring to files in other branches other than the build one? Since I’m trying to keep the build machines as “disposable” as possible, it’s running with an Agent Config Out of the Box: No custom paths, no hardwiring.
I already tried referring the files directly with their source control path, for example. The only options I’m seeing are either creating a PowerShell/CMD Script that downloads those files right into the same folder as the SLN or keeping it “as it is” and use relative paths putting a “Build” Build Step before the actual Build Step so it downloads the files to the server.
Isn’t there an “Elegant” way of doing this? Or is our methodology wrong from the get go?
You can add a Copy Files step to copy the files that the build needs:

TFS Build - get source code by label issues

I have an issue that I want to share with you and ask for advice.
Let's say I have a project in TFS with a source code folders and folder with deployment scripts. Folders structure:
-- TFS
---- PROJECT
--------DEPLOYMENTSCRIPTS
--------SOURCE
DeploymentScripts folder is a container for custom deployment scripts that are being executed by TFS Build process.
Source - is a folder with a source code where for each new release I create a label to use it later for deployment.
I have a build definition configured to takes files from both folders, so I expect that TFS will download the content of both folders each time I trigger a build:
And this perfectly works when TFS build takes the latest version: it takes everything, builds and deploys.
The issue appears once I configure what label to take:
TFS downloads only the content of Source folder ignoring DeploymentScripts. I suppose that this happens because we use labels only for Source folder and not in DeploymetScripts (the content of this folder is static, there are no any changes). I know, that if I make DeploymentScripts a sub-folder of Sources that will fix my issue, but I want to keep it separate (for example, if I later create a bunch of branch folders I don't want to copy deployment to each specific folder, I want to have as a one instance) and try to find a solution for this case.
Either apply your label at the root level, or start your build using a date or changeset number.
Another approach would be to use branching rather than labels, and set up your build to allow you to pass in the name of the branch to be built.
I no longer use labels, I can't think of a situation where they would be useful to me these days.
If I encountered a team doing this my first question would be why do they need to use Labels to accomplish whatever workflow they are after. This is an unusual practice, most teams just do a Get Latest, and use an appropriate branching strategy to achieve their desired workflow.
If you must use a Label one option is to include the DeploymentScripts in your Labels. You can do this without have to move the folder location in source control by editing your Label.

Team City templates and Artifacts

I recently noticed I needed to reuse a build step in many projects. So I created a template where I only defined that build step, and had the projects that needed it associated with that template. That worked perfectly.
But then I realized that none of the affected projects were generating their artifacts, even though all of them were building successfully. When I went to look at the General Settings, the Artifact Paths box was grayed out and Team City told me that I could only change it inside the template!
I want my builds to have different artifact paths (some don't even generate artifacts at all), but I don't want to duplicate my build step. Is there some workaround for this?
Team City Version: 6.5.6 (build 18130)
This is how I workaround the issue:
Create a configuration parameter in the build parameters section of the template. I just call it Artifacts.
Then reference the property in the Artifacts Paths box in the template, e.g %Artifacts%
Then for each configuration which inherits the template you can override the artifacts configuration parameter with a path that is relevant.
HTH
This is an old question and apparently only affects users with TeamCity versions less than 8.1 (as pointed out in the comments to the accepted answer).
According to the offical documentation:
Since TeamCity 8.1, the following settings can now be overridden in a build configuration inherited from a template:
build number format
artifact paths
build options (hanging builds detection, status widget, number of simultaneously running builds)
VCS checkout mode
checkout directory
clean all files before build
show changes from snapshot dependencies
execution timeout
all common build failure conditions, including execution timeout

Creating automatic tests for embedded resource in Visual Studio and Team Build?

In my current .Net 4.0 solution, I have one project containing a lot of XML files as embedded resources. There is a lot of development activity going on with these files and there is a very real chance that one of the developers on my team will forget to set the build-action of a particular XML file to embedded resource.
What I have done to insure that this does not happen, and which works perfectly for local builds in VS2010, is to create an automated test in NUnit that counts the number of resources using Assembly.GetManifestResourceNames() and then compares this with a file count in the correct source directory sub-tree of my resource assembly. As long as these match it means that all the files have build-action correctly set to "embedded resource".
Now, my problem is that my test uses a relative path to find the directory of the files in the resource project and working directory is not the same on the build server (which uses TFS2010).
What is the best way to solve this? I have thought of using environment variables which can be set differently on developer machines and on the build server but ideally I would like something that would require the minimum amount of configuration on developer machines and build server.
Ok, this is the solution I ended up with:
The test checks for a specific environment variable using Environment.GetEnvironmentVariable and if not set uses a relative path that works on development machines using Visual Studio 2010, otherwise it uses the path in the environment variable
For the build server (Team Build) I set an argument for the build process to equal the environment variable and then in my NUnit task I set the NUnit Environment variables to the value of the the build argument.
This solution makes setting up new developer machines hassle-free but may require some configuration of build-agents if they deviate from default path setup.