单个 TFS 2010 构建定义可以用于多个分支吗?

发布于 2024-12-08 08:11:42 字数 832 浏览 0 评论 0原文

我负责我们产品的构建,并被要求提出一种自定义现有构建定义的方法,以在需要时构建不同的分支。

该产品的构建过程已经有几个自定义步骤和操作,并且该产品有大量已构建的项目文件,因此为创建的每个新分支设置新的构建定义是无效的。

构建定义设置为从主分支构建。目的是输入特定分支(使用构建排队时可以输入的工作流参数),然后将构建该分支而不是默认的主分支,而无需编辑构建定义。

我有一个单独的测试程序,用于测试所有自定义构建活动和过程。在此构建定义的工作流程中,我添加了相当多的构建消息用于记录目的,以便我可以查看构建过程中使用的变量的值。

我还基于此测试程序创建了一个分支,准备测试构建定义,该定义可用于首先构建多个分支

,我从原始分支运行原始测试解决方案的项目文件的构建,然后更改了构建定义,以便使用新分支完成相同的操作并运行另一个构建。当比较两个分支之间的构建日志时,它们之间只有一些细微的差异。 (记录详细程度设置为诊断)

第一个区别 - 我查看了构建的工作区变量和文件夹属性引用了各自的分支,特别是文件夹属性的 ServerItem 属性

第二个区别 - 正在构建的项目文件(BuildSettings.ProjectsToBuild)是来自各自的分支,

除了这些之外,我没有看到两个构建日志之间有任何其他差异

这里的主要问题

是否有一种标准方法可以交换正在为单个分支构建的分支构建定义?

如果没有,是否可以简单地将自定义工作流模板(在 Workspace 和 BuildSettings.ProjectsToBuild 中)中对默认 Main 分支的所有引用更改为排队构建时输入的分支?

一如既往,提前感谢您的任何和所有帮助

I look after builds of our products and have been asked to come up with a way of customising an existing build definition to build different branches when required.

The build process for this product has several custom steps and actions already and the product has a large amount of project files that are built so its not effective to set up a new build definition for every new branch that is created.

The build definition is set up to build from the Main branch. The aim is to enter a particular branch (using a workflow argument that can be entered when a build is queued) which will then be built instead of the default Main branch without having to edit the build definition.

I have a separate test program that I use for testing all my custom build activities and procedures on. In the workflow for this build definition, I have added a fair few build messages for logging purposes so that I can view the values of variables used in the build process.

I have also created a branch based on this test program ready for testing of a build definition that can be used to build more than one branch

first off, I ran a build for the original test solution's project files from the original branch, then changed the build definition so that the same would be done using the new branch and ran another build. When comparing the build logs between the 2 branches there are only a few minor differences between them. (Logging Verbosity set to Diagnostic)

1st difference - I looked a the Workspace variable and the Folders property of the builds reference their respective branches, specifically the ServerItem property of the Folders property

2nd difference - The project files being built (BuildSettings.ProjectsToBuild) are coming from the respective branches

I haven't seen any other differences between the 2 build logs other than these

The main question here:

Is there a standard way of swapping the branches being built for a single build definition?

If not, would it be possible to simply change all references to the default Main branch in the customised workflow template (in Workspace and BuildSettings.ProjectsToBuild) to the entered branch when queueing a build?

As always, thanks in advance for any and all help

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情深如许 2024-12-15 08:11:42

我已设法修改构建的工作流程模板,以便可以构建解决方案的多个分支。为了实现这一目标,我必须更改工作流程中的某些内容,并为运行构建的服务帐户创建一些额外的工作区。

  1. 我向工作流添加了一个参数,以便在构建排队时可以输入所需的分支。

  2. 我更改了构建的放置位置,以便它与输入的分支相关(可选)

  3. 在构建计算机上为分支构建创建了一个单独的源目录

  4. 初始化了 WorkspaceName 和 SourcesDirectory,以便它们与新的工作空间名称和源目录文件夹匹配

  5. 我创建了一个自定义活动来更改 BuildSettings.ProjectsToBuild 中的项目/解决方案列表,以便它们从

  6. 我在测试阶段注意到,即使我输入的分支的新工作区最初是设置为使用输入的分支作为其 ServerItem,它仍然会使用在构建定义中输入的 ServerItem 创建工作区。为了解决这个问题,我创建了另一个自定义活动来重新映射分支工作区,以便 ServerItem 指向正确的分支

我的工作流程中还涉及到其他一些内容,但它们是我的开发人员要求的更多调整,上述步骤导致了单个构建定义的多个分支构建。

I have managed to amend my build's workflow template so that builds for multiple branches of the solution are possible. To achieve this I had to change certain things within the workflow and also create some extra workspaces for the service account that run the builds.

  1. I added an argument to the workflow so that the required branch can be entered when the build is queued.

  2. I changed the drop location for the build so that it is relevant for the entered branch (optional)

  3. Created a separate sources directory on the build machine for the branch build

  4. Initialised the WorkspaceName and SourcesDirectory so that they match the new workspace name and sources directory folder

  5. I created a custom activity to change the list of projects/solutions in BuildSettings.ProjectsToBuild so that they were referencing them from the entered branch

  6. I noticed through my testing phase that even though my new workspace for the entered branch was initially set up to use the entered branch as its ServerItem, it would still create the workspace with the ServerItem that was entered in the build definition. To get around this, I created another custom activity to remap the branch workspace so that the ServerItem was pointing to the correct branch

There are a few other things that I have involved in my workflow, but they are more tweaks that my developers have requested, the above steps have resulted in multiple branch builds for a single build definition.

十六岁半 2024-12-15 08:11:42

我还希望在构建定义中具有更多的分支敏捷性,因此我实现了一个代码活动来更改 ProjectsToBuild(如上面 Vermin 的步骤 5)。这是代码(删除了项目特定的内容):

[BuildActivity(HostEnvironmentOption.All)]
public sealed class ConvertProjectsAccordingToBranch : CodeActivity
{
    public static string s_MainBranch = "$/MyTeamProject/Main";

    public InArgument<IBuildDetail> BuildDetail { get; set; }
    public InArgument<BuildSettings> BuildSettingsOriginal { get; set; }
    public OutArgument<BuildSettings> BuildSettingsConverted { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        Logger.Instance.Init(context);
        IBuildDetail buildDetail = BuildDetail.Get(context);
        BuildSettingsConverted.Set(context, ConvertProjects(BuildSettingsOriginal.Get(context), buildDetail.BuildDefinition));
    }

    /// <summary>Returns a BuildSettings with ProjectsToBuild converted according to the build definition's workspace</summary>
    public BuildSettings ConvertProjects(BuildSettings settingsOriginal, IBuildDefinition buildDefinition)
    {
        var mappings = buildDefinition.Workspace.Mappings;
        if (mappings.Count() != 1)
        {
            throw new BuildProcessException(string.Format(CultureInfo.InvariantCulture,
                "Build definition must have exactly one workspace mapping. Build definition ID:{0} has {1} mappings",
                buildDefinition.Id,   // IBuildDefinition doesn't have any Name property, seriously!
                mappings.Count()));
        }

        string definitionBranch = mappings.First().ServerItem;
        var settingsConverted = new BuildSettings()
        {
            PlatformConfigurations = settingsOriginal.PlatformConfigurations,
        };

        foreach (string projectOriginal in settingsOriginal.ProjectsToBuild)
        {
            var projectConverted = projectOriginal.Replace(s_MainBranch, definitionBranch);
            if (!projectConverted.StartsWith(definitionBranch))
            {
                throw new BuildProcessException(string.Format(CultureInfo.InvariantCulture,
                    "Project {0} is not under main branch {1},  Definition branch: {2}",
                    projectOriginal, s_MainBranch, definitionBranch));
            }

            settingsConverted.ProjectsToBuild.Add(projectConverted);
            Logger.Instance.Log("Converted ProjectToBuild: {0},  original: {1}", projectConverted, projectOriginal);
        }

        return settingsConverted;
    }
}

我还有 ConvertProjects() 的单元测试,但它依赖于本地内容,所以我没有将其发布在这里。很琐碎,绝对值得写!

I also wanted some more branch agility in my build definitions, so I implemented a code activity to change ProjectsToBuild (like Vermin's step 5 above). Here's the code (removed project-specific stuff):

[BuildActivity(HostEnvironmentOption.All)]
public sealed class ConvertProjectsAccordingToBranch : CodeActivity
{
    public static string s_MainBranch = "$/MyTeamProject/Main";

    public InArgument<IBuildDetail> BuildDetail { get; set; }
    public InArgument<BuildSettings> BuildSettingsOriginal { get; set; }
    public OutArgument<BuildSettings> BuildSettingsConverted { get; set; }

    protected override void Execute(CodeActivityContext context)
    {
        Logger.Instance.Init(context);
        IBuildDetail buildDetail = BuildDetail.Get(context);
        BuildSettingsConverted.Set(context, ConvertProjects(BuildSettingsOriginal.Get(context), buildDetail.BuildDefinition));
    }

    /// <summary>Returns a BuildSettings with ProjectsToBuild converted according to the build definition's workspace</summary>
    public BuildSettings ConvertProjects(BuildSettings settingsOriginal, IBuildDefinition buildDefinition)
    {
        var mappings = buildDefinition.Workspace.Mappings;
        if (mappings.Count() != 1)
        {
            throw new BuildProcessException(string.Format(CultureInfo.InvariantCulture,
                "Build definition must have exactly one workspace mapping. Build definition ID:{0} has {1} mappings",
                buildDefinition.Id,   // IBuildDefinition doesn't have any Name property, seriously!
                mappings.Count()));
        }

        string definitionBranch = mappings.First().ServerItem;
        var settingsConverted = new BuildSettings()
        {
            PlatformConfigurations = settingsOriginal.PlatformConfigurations,
        };

        foreach (string projectOriginal in settingsOriginal.ProjectsToBuild)
        {
            var projectConverted = projectOriginal.Replace(s_MainBranch, definitionBranch);
            if (!projectConverted.StartsWith(definitionBranch))
            {
                throw new BuildProcessException(string.Format(CultureInfo.InvariantCulture,
                    "Project {0} is not under main branch {1},  Definition branch: {2}",
                    projectOriginal, s_MainBranch, definitionBranch));
            }

            settingsConverted.ProjectsToBuild.Add(projectConverted);
            Logger.Instance.Log("Converted ProjectToBuild: {0},  original: {1}", projectConverted, projectOriginal);
        }

        return settingsConverted;
    }
}

I also have unit test for ConvertProjects(), but it's dependent on local stuff, so I didn't post it here. It's trivial, and definitely worth writing!

扭转时空 2024-12-15 08:11:42

我知道这已经很老了,但以防万一有人发现这篇文章。

我们有相同的要求:能够构建一个功能分支,以在合并到开发之前提供用于测试的特定功能的构建。

这就是我们的做法:

创建了一组 Visual Studio 扩展:

  • 创建分支构建
  • 启动分支构建
  • 删除分支

创建分支构建将克隆用作模板的构建定义。根据分支更改构建定义名称和工作区。构建定义将在团队资源管理器 (VS2012) 中可见。

启动分支构建将找到构建定义并启动构建。

删除分支会找到构建定义,删除所有构建,删除构建定义,并删除分支(清理)。构建和分支的生命周期很短,因此清理它们很重要。

I know this is very old, but in case anybody finds this post.

We have the same requirement: Being able to build a feature branch to provide a build of a specific feature used for testing before merged to Development.

This is how we have done it:

Created a set of Visual Studio extensions:

  • Create branch build
  • Launch branch build
  • Delete branch

Create branch build will clone a build definition which are used as a template. Change the build definition name and workspace based on the branch. The build definition will be visible in Team Explorer (VS2012).

Launch branch build will find the build definition and launch the build.

Delete branch will find the build definition, delete all builds, delete the build definition, and delete the branch (Clean up). The builds and branch have a short lifetime, so it is important that these are cleaned up.

一身软味 2024-12-15 08:11:42

简而言之:否和是:-)

对这些答案进行更多详细说明,TFS 系统默认模板更喜欢为您想要构建的每个分支拥有单个构建定义,或者指定需要一次构建的所有分支,但是在单个构建定义中。没有标准方法可以从队列新构建对话框中的可用分支中进行选择。

下一个答案是肯定的,因为您确实可以自定义构建模板,而且我知道您已经开始这样做了。根据您的分支结构,向模板添加一个属性应该相当容易,该属性显示在“队列新构建”对话框中,并且有一个(例如)半列分隔的字符串,其中包含您想要在运行期间构建的所有分支,并为该列表中的每个元素添加一个解决方案,以便在模板实际开始迭代该列表之前在工作流程中构建。

这应该可以完成工作,但是,我感兴趣的是你最终是如何想要这种能力的?你没有使用VS解决方案文件吗?

In short: No and Yes :-)

A bit more elaboration on those answers, the TFS system default templates prefer to have a single build definition for every branch you want to build, or specify all branches that need to be build at onces, but in a single build definition. There is not a standard way to choose from the available branches you have in the Queue new build dialog.

Next answer would be Yes, because indeed you can customize your build template and I understand you already started doing that. Depending on your branching structure it should be fairly easy to add a property to your template that shows up in the Queue new build dialog, and have a (for example) semi-column seperated string with all branches your want to build during a run, And for each element in that list add a solution to build in the workflow process before the template actually startes iterating that list.

That should do the job, however, I am interested in how you ended-up in wanting this ability? Are you not using VS solution files?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文