5

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.

4

3 回答 3

4

不幸的是,TFS 使用构建定义中定义的工作空间映射有两个目的:定义哪些文件下载到构建服务器,以及定义哪些文件/文件夹触发 CI/Gated 构建。

对于绝大多数情况,这些是相同的,所以它工作正常。如果这对你不起作用,有一种方法可以解决它,但它并不漂亮。

您可以设置工作区映射以指定哪些文件/文件夹应触发 CI 构建。然后自定义构建工作流程以在下载代码时不使用工作区映射,但是您可以将要下载的路径硬编码到工作流程中,或者您可以公开一些在构建定义中设置的自定义构建参数以指定要下载的文件夹。

于 2013-09-13T18:11:09.820 回答
1

我已经成功地解决了这个限制,如下所示。

默认的 TFS 构建过程模板使用内置的“CreateWorkspace”活动,该活动采用构建定义中的映射并创建相应的 TFS 工作区。看起来没有任何方法可以直接自定义此活动。但是,可以在“CreateWorkspace”活动之后立即将其他活动添加到流程中,这会将其他工作文件夹映射注入源代码管理工作区。这些额外的映射将导致从 TFS 检索源并在构建期间可用,而不会触发任何 CI 构建。

关键是创建一个新的自定义构建工作流活动,该活动能够将映射添加到现有工作区。我选择在http://tfsbuildextensions.codeplex.com/中扩展基础活动,如下:

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)
    {
        ...
    }
}
于 2014-01-30T15:09:26.543 回答
1

我使用的解决方案与上述非常相似。在构建定义中创建映射时,我隐藏了不想触发 CI 构建的文件夹。然后在工作流程中,我在 CreateWorkspace 操作之后添加了一个自定义活动来移除斗篷。删除 cloaks 允许这些文件夹中的任何源可用于构建。

这允许从构建定义中管理所有内容,并且如果需要修改哪些文件夹应该触发 CI 构建,或者哪些文件夹需要可用于构建,则不需要更改工作流程。

这可能对您更有效,具体取决于您的工作区映射的复杂性。

活动代码如下:

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));
    }
}
于 2014-06-05T17:27:31.177 回答