Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trigger a build only when check in to specific folder and subs - Continuous Integration TFS

I have a TFS build setup using Continuous Integration. Everything works correctly.

I'm trying to limit the check-ins that trigger a build to a specific folder (and subs).

Currently, any check-in to the Source Control folder set in my definition causes the project to build, but I would like the build to be triggered only when code is checked-in to one of the sub directories (and it's subs) in the Source Control folder.

Does anyone have any ideas? I have gone into the Default build template to try to make changes, but no luck so far.

like image 649
Akin Avatar asked Sep 12 '13 21:09

Akin


3 Answers

Unfortunately TFS uses the Workspace Mapping defined in the Build Definition for two purposes: Define what files get downloaded to the build server, and define which files/folders trigger CI/Gated builds.

For the vast majority of cases these are the same thing, so it works fine. If that doesn't work for you, there is a way to workaround it, but it's not pretty.

You can setup the Workspace Mapping to specify which files/folders should trigger the CI build. Then customize the build workflow to not use the Workspace Mapping when downloading code, but instead you can either hardcode the path(s) to download into the workflow, or you can expose some custom Build Parameters that get set in the Build Def to specify the folders to download.

like image 200
Dylan Smith Avatar answered Nov 04 '22 20:11

Dylan Smith


I have successfully worked around this limitation as follows.

The default TFS build process template uses the built-in "CreateWorkspace" activity, which takes the mappings in the build definition and creates the corresponding TFS workspace. It doesn't look like there is any way to customize this activity directly. However, it is possible to add additional activities into the process, immediately after the "CreateWorkspace" activity, which injects additional working folder mappings to the source control workspace. These additional mappings will cause source to be retrieved from TFS and be available during the build without themselves triggering any CI builds.

The key is creating a new custom build workflow activity that is able to add a mapping to the existing workspace. I chose to extend the base activity in http://tfsbuildextensions.codeplex.com/, as follows:

using System;
using System.Activities;
using System.ComponentModel;
using System.Text;
using System.Text.RegularExpressions;
using global::TfsBuildExtensions.Activities;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

[Description("Adds a mapping to the workspace.")]
[BuildActivity(HostEnvironmentOption.All)]
public class AddWorkspaceMapping : BaseCodeActivity
{
    public InArgument<Workspace> Workspace { get; set; }
    public InArgument<string> ServerItem { get; set; }
    public InArgument<string> LocalItem { get; set; }
    public InArgument<string> BuildDirectory { get; set; }
    public InArgument<string> SourcesDirectory { get; set; }

    protected override void InternalExecute()
    {
        var ctx = this.ActivityContext;

        Workspace ws = this.Workspace.Get(ctx);

        string serverItem = this.ServerItem.Get(ctx);
        string localItem = this.LocalItem.Get(ctx);

        if (!string.IsNullOrWhiteSpace(serverItem))
        {
            localItem = ExpandEnvironmentVariables(localItem);

            ws.Map(serverItem, localItem);
        }
    }

    // Similar to the internal implementation of Microsoft.TeamFoundation.Build.Common.BuildCommonUtil.ExpandEnvironmentVariables()
    internal string ExpandEnvironmentVariables(string inputStr)
    {
        ...
    }
}
like image 32
pbar Avatar answered Nov 04 '22 19:11

pbar


The solution I use is very similar to the above. When creating the mapping in the build definition, I cloak folders I do not want to trigger CI builds. Then in the workflow I add a custom activity to remove the cloaks right after the CreateWorkspace action. Removing the cloaks allows any source in those folders to be available for the build.

This allows everything to be managed from the build definition and does not require changing the workflow if there is a need to modify which folders should trigger a CI build, or which folders need to be available to build.

This may work better for you, depending on the complexity of your workspace mappings.

The code for the activity is as follows:

using System.Activities;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

[BuildActivity(HostEnvironmentOption.All)]
public sealed class RemoveCloaksFromWorkspace : CodeActivity
{
    [RequiredArgument]
    public InArgument<Workspace> Workspace { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        var ws = this.Workspace.Get(context);
        ws.Folders.Where(f => f.IsCloaked).ToList().ForEach(f => ws.DeleteMapping(f));
    }
}
like image 33
gtmatt Avatar answered Nov 04 '22 21:11

gtmatt