【问题标题】:Include branch name in post build event on Team Build在 Team Build 的构建后事件中包含分支名称
【发布时间】:2015-06-14 11:40:50
【问题描述】:

我想在 TFS 构建过程中执行以下步骤:

  • 发布构建事件会将一些文件从我编译的项目复制到另一个预定义目录,我希望该目录路径包含分支名称。
  • 我也希望能够在我的 xaml 工作流模板中引用分支名称。

【问题讨论】:

  • TFVC 还是 Git?哪个 TFS 版本?哪个 Team Build 版本?
  • 您标记了 MsBuild,但根据您的实际问题,我怀疑这不是您想要的。只是为了确定,您是想在构建工作流程中解决这个问题,还是在项目文件中作为构建后操作来解决这个问题?
  • 1. TFVC 2013。实际上我们正在使用这两种功能。我们在大多数项目中都编写了构建后事件,并且在执行服务器构建时我们还使用了一些工作流活动。我所关心的很简单:我希望能够在 Visual Studio 的后期构建事件中使用 $(branchName) 只是为了在文件夹名称中包含分支。然后,从工作流方面,我需要在服务器中创建这个目录。

标签: tfs msbuild workflow tfsbuild workflow-foundation


【解决方案1】:

第一个比较简单。当您使用新的 TFS 2013 构建服务器和流程模板时,您只需在构建定义配置中添加构建后的 powershell 脚本,签入脚本并在构建期间运行它。

第二个取决于您使用的是 TFVC 还是 Git,在第一种情况下,使用 VersionControlServer 类来查询 BranchObjects,然后检查哪个是您的工作文件夹的根。但请注意,在 TFVC 中,可以在一个工作区中引用多个分支,因此此查询可能有多个答案,具体取决于您使用哪个文件来查找分支根。自定义 CodeActivity 可以解决问题,类似于 this check in a custom checkin policy

代码将类似于:

 IBuildDetail buildDetail = context.GetExtension<IBuildDetail>();

 var workspace = buildDetail.BuildDefinition.Workspace;
 var versionControlServer = buildDetail.BuildServer.TeamProjectCollection.GetService<VersionControlServer>();

 var branches = versionControlServer.QueryRootBranchObjects(RecursionType.Full);
 var referencedBranches = listOfFilePaths.GroupBy(
                file =>
                branches.SingleOrDefault(
                     branch => file.ServerItem.StartsWith(branch.Properties.RootItem.Item)
                )
            ).Where(group => group.Key != null);

要获取 yo 工作区中所有项目的列表,您可以使用 Workspace.GetItems

如果您使用的是 Git,您也有一些选择。最简单的就是invoke the command line

 git symbolic-ref --short HEAD   

或深入LibGit2Sharp 并使用它根据自定义活动的当前工作文件夹查找分支名称。

如果您想将其包含在 MsBuild 任务中,这也可能是可行的。这个答案完全概述了所需的步骤有点远,但是一旦你知道该怎么做就不是那么难了。

Create a custom MsBuild task that invokes the same snippet of code above,虽然不是通过BuildDetail.BuildDefinition.Workspace 访问工作区,而是through the WorkStation class

Workstation workstation = Workstation.Current;
WorkspaceInfo info = workstation.GetLocalWorkspaceInfo(path);
TfsTeamProjectCollection collection = new TfsTeamProjectCollection(info.ServerUri);
Workspace workspace = info.GetWorkspace(collection);
VersionControlServer versionControlServer = collection.GetService<VersionControlServer>();

创建任务后,您可以创建一个自定义 .targets 文件,该文件通过覆盖某些变量或在构建完成时复制数据来连接到 MsBuild 进程。您可以挂钩多个目标并定义是否需要在它们之前或之后做某事。

您可以将 &lt;import&gt; 这些添加到您的每个项目中,也可以将其放置在您的 MsBuild 版本的 ImportAfterImportBefore 文件夹中以使其全局加载。您可以在此处找到该文件夹​​:

C:\Program Files (x86)\MSBuild\{MsBuild Version}\Microsoft.Common.Targets\ImportAfter

【讨论】:

  • 谢谢。所以为了在构建的文件夹路径名中包含分支名称,我需要一个不同的脚本?以及如何将每个构建后事件(针对我的解决方案中的每个项目)集中到一个文件中?因为每个人都使用不同的路径从/向 dll 复制..似乎有点复杂..
  • 伙伴我必须创建一个脚本,在构建的 git 存储库上创建一个标签,即:如果构建运行,它会用版本标记提交。我想我可以使用构建后脚本,但不确定如何使用上面的建议!
  • @jessehouwing ,非常感谢您的详细信息。可悲的是,我不确定这是否针对我正在寻找的东西。所以我会再试一次:正如我在原始帖子中解释的那样,我的目标是将当前分支名称包含在我的项目构建事件操作中。例如 - 将复制所有二进制文件的构建后事件。 (xcopy c:\workspace\$(branchName)\$(projectName)*.* )c:\targetFolder.你能帮我解决这个问题吗?
  • 您必须自己弄清楚这一点。使用 MsBuild 任务复制文件非常容易,您不需要 Xcopy。 (msdn.microsoft.com/en-us/library/3e54c37h.aspx) 我已经向您展示了如何提取分支名称并指出如何将其包装在自定义 MsBuild 任务中。通过调用自定义任务来获取名称,然后调用 Copy 任务来复制文件,将两者结合起来是问题中最简单的部分。
  • 根据我已经提供给您的信息,尝试构建您需要的内容并提出新问题,或者用更具体的问题更新此问题。不要让我们为你做你的工作。
猜你喜欢
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
  • 2014-02-12
相关资源
最近更新 更多