【问题标题】:Trigger a build only when check in to specific folder and subs - Continuous Integration TFS仅在签入特定文件夹和子目录时触发构建 - 持续集成 TFS
【发布时间】:2013-09-17 10:23:55
【问题描述】:

我有一个使用持续集成的 TFS 构建设置。一切正常。

我正在尝试将触发构建的签入限制为特定文件夹(和子文件夹)。

目前,对我定义中设置的源代码管理文件夹的任何签入都会导致项目构建,但我希望仅在将代码签入到其中一个子目录(并且它是子目录)时触发构建) 在源代码管理文件夹中。

有人有什么想法吗?我已经进入默认构建模板尝试进行更改,但到目前为止没有运气。

【问题讨论】:

  • TFS 使用工作区映射来确定哪些签入会触发构建。你唯一能做的就是限制你的工作空间,但你需要包含代码成功编译所需的所有文件

标签: tfs continuous-integration build-automation tfsbuild


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    默认的 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)
        {
            ...
        }
    }
    

    【讨论】:

      【解决方案3】:

      我使用的解决方案与上面的非常相似。在构建定义中创建映射时,我隐藏了不想触发 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));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-15
        • 1970-01-01
        • 2011-04-18
        • 2010-11-22
        • 2013-11-29
        • 1970-01-01
        • 2014-12-18
        • 1970-01-01
        相关资源
        最近更新 更多