持续集成策略 - 项目参考与分支/合并

6
假设您的遗留代码库(企业API)中有7个核心项目。该代码库大约有50个应用程序引用了一个或多个核心项目。在手动进行vss到tfs迁移后,只有其中几个应用程序仍然可用。为了使这些应用程序再次正常工作,许多应用程序已经从企业API中取出,并放置在自己的TFS项目中。
我试图说服同事们不要将核心项目分支并将其复制到单独的TFS项目中,而是在发布到生产环境后才将核心项目的添加合并回企业API。显然,当变更较少时,持续集成会更加困难。
我试图说服同事们最好将核心项目从企业API中取出并放入自己的TFS项目中,然后引用bin/Debug目录。
是将分支分别复制到单独的TFS项目中再合并(并在最后查看冲突),还是封装核心项目并强制20人团队仅使用每个核心项目的一个副本更好呢?

2
这个问题怎么会不适合在SO上讨论呢?我觉得我们的程序员姊妹站点可能更适合讨论这个问题。 - Lieven Keersmaekers
2个回答

4

这取决于你的共享代码的成熟程度。我认为有三种方法可以遵循,每种方法都有其优缺点:

选项1:直接从它们自己的团队项目中引用它们

Team Project Application 1
-->  Development
        --> ...
-->  MAIN
        --> Sources
            --> Application 1
                --> Application1.sln

Team Project Application 2
-->  Development
        --> ...
-->  MAIN
        --> Sources
            --> Application 2
                --> Application1.sln

Team Project CoreProject 1
-->  Development
        --> ...
-->  MAIN
        --> Sources
            --> CoreProject1.csproj

采用这种方法,您可以在CI构建中设置所有应用程序开始构建,一旦您已经检入了一个核心项目。但是请注意,您必须按照一定的约定将团队项目本地映射(否则编译将会中断)。
如果您不断更改核心项目并需要快速反映到所有受影响的应用程序,则此方法很好。这还意味着,如果核心项目的破坏性变化对某个应用程序产生影响,那么您可以承担一定的不稳定性。
选项2:通过分支间接引用它们。
Team Project Application 1
-->  Development
        --> ...
-->  MAIN
        --> SharedSources
            --> CoreProject1_branch
                --> CoreProject1.csproj
        --> Sources
            --> Application 1
                ---> Application1.sln

Team Project Application 2
-->  Development
        --> ...
-->  MAIN
        --> SharedSources
            --> CoreProject1_branch
                --> CoreProject1.csproj
        --> Sources
            --> Application 2
                ---> Application1.sln

Team Project CoreProject 1
-->  Development
        --> ...
-->  MAIN
        --> Sources
            --> CoreProject1.csproj

采用这种方法,每次在CoreProject1中检查更改时,您需要对每个受影响的应用程序进行合并。这需要一定的努力,但可以让您有时间在CoreProject自己的工作区稳定后再将其合并到您的应用程序中。
这种方法意味着您还必须为每个CoreProject设置一个构建定义。
总的来说,如果您重视CoreProject的稳定性并且不能承担因更改而导致问题而“污染”您的应用程序,则这是一个不错的方法。顺便说一下,这也是我们采取的方法。

选项3:在每个应用程序中进行文件引用

Team Project Application 1
-->  Development
        --> ...
-->  MAIN
        --> SharedBinaries
            --> CoreProject1_branch
                --> CoreProject1.dll
        --> Sources
            --> Application 1
                ---> Application1.sln

Team Project Application 2
-->  Development
        --> ...
-->  MAIN
        --> SharedBinaries
            --> CoreProject1_branch
                --> CoreProject1.dll
        --> Sources
            --> Application 2
                ---> Application1.sln

Team Project CoreProject 1
-->  Development
        --> ...
-->  MAIN
        --> Sources
            --> CoreProject1.csproj

采用这种方法,您需要检查每个应用程序中CoreApplication构建的二进制输出。
只有当您确信CoreApplication很稳定且不需要经常调试时才建议使用此方法。
实质上,选项2和选项3是相似的,它们之间存在着一个著名的辩论“项目引用 vs 文件引用”。可以通过搜索获取更多信息。请参见SO资源
如果您的核心项目经常更改和/或单元测试覆盖率低,那么应选择选项2(或3)。如果您对其质量有信心,则选择选项1是一个不错的选择,因为它将极大地提高您的整体生产力。
根据您提供的相当大的数字(20人,50个解决方案,7个核心项目),在没有了解您的产品及其质量的情况下,我会选择选项2/3。
另一个重要的提示:共享项目经常没有任何分离测试的手段。如果是这种情况,并且Core Projects没有自己的单元测试、专门的测试计划等,那么除了选项1之外别无选择。
关于这个问题的另一个重要资源是ALM rangers的工作

2
我相信您希望您的团队已经构建了核心API的二进制文件。正确的重用粒度是发布的粒度(版本化构建),请参阅Robert C Martin在96年的C ++报告以及我们在此处的解释:http://www.urbancode.com/html/resources/articles/reuse-maturity-model.html
基本上,似乎团队正在恐慌中,只是做一些最简单的事情,让他们能够重新交付。这条路线是可以理解的,但我认为最好他们承认将共同库作为共享代码库,并且重用代码而不是dll是不好的,并且技术债务需要在事态稳定后解决。

1
+1 这是我期待的回答,但我会将另一个回复标记为答案,因为它包含赞成和反对的论据。感谢您的时间,非常感激。 - Jeremy Thompson
我希望能够接受两个答案...请其他人给这位同学点个赞,那个链接就是我的大杀器! - Jeremy Thompson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接