TeamCity + artefacts +链式构建+ MSBuild + csproj / dll引用问题

时间:2013-12-25 20:55:53

标签: visual-studio build msbuild teamcity csproj

我正在为非常大的系统(300多个项目)编写build / ci / deploy过程。这是一个C#.net项目,我们使用Visual Studio进行开发IDE和MSBuild(来自psake任务)来编译我们的解决方案。

有多个解决方案包含多个项目,更糟糕的是,一些项目被引用为.csproj文件,一些项目被引用为.dll。构建重构的第一步将是实现所有项目将通过csproj文件相互引用。这样我就可以创建一个包含所有项目的主解决方案,并使用MSBuild支持的并行构建,这将非常适合CI构建。

但是对于部署版本,我想使用链式构建和artefact依赖。

我想象我的构建如下:
1.构建CommonLibrarry
1.1将人工制品中的.dll存储为common.zip
2.使用1.1中的人工制品并构建CoreProduct
2.1将来自CoreProduct的.dll存储在artefacts中作为product.zip
...等等(这样的20多个步骤)......

问题是CoreProduct将CommonLibrary引用作为.csproj,并且那些.csproj文件将不会作为CoreProduct构建出现,为什么会因为已经构建了CommonLib并且人工制品准备好了。 MSBuild项目文件(CSPROJ文件)包含有关需要编译的文件和有关引用项目而不是解决方案文件的信息,因此我无法为部署系统创建单独的.csproj文件,开发人员将使用并将其类文件添加到不同的项目文件中我必须管理这两个项目文件之间的困难同步(例如real.csproj和real.CI.csproj)。 我可以使用T4模板来生成两个文件,但这样我就会从Visual Studio中轻松添加文件。

.csproj中的条件部分是不合适的,因为有超过50个开发人员并且了解到添加引用现在需要调整.csproj文件是不可能的:)

我正在寻找如何解决这个问题的模式/想法

2 个答案:

答案 0 :(得分:1)

正如您自己已经发现的那样,两个要求(仅项目引用+链式构建)相互矛盾。至少我想不出办法让他们玩起来。所以他们中的一个必须以某种方式改变。

第一个想法:你真的需要链式构建吗?设置需要一段时间,最后你可能想要构建所有内容,那么为什么不默认构建所有内容呢?

如果上述答案为“是”:假设毕竟不使用项目引用。直接使用dll引用是一团糟,但不推荐它。你可以用某种方式使用NuGet。这意味着例如CommonLibrary被构建到一个包中,而其他构建通过NuGet使用该包,这意味着它仍然是一个dll引用,但安装是自动的。我见过人们用TeamCity这样做(因为它可以作为包服务器)但我不知道设置的细节,而不知道如何处理本地开发构建。它的确意味着教你的开发团队当然只能使用NuGet添加引用。

另一种方式:保留项目引用(yay!),但对于链式构建,您在所有项目文件上运行一个脚本,删除引用并用程序集引用替换它。声音凌乱,但我也是这样的东西,一旦设置它几乎是万无一失的。在实践中,您需要为TC添加一些构建步骤,以便获得如下构建流程:

  • checkout CommonLibrary,构建和存储人工制品
  • 结帐CoreProduct,运行脚本,构建和存储人工制品
  • 结账XYZ,运行脚本,构建和存储人工制品

脚本会:

  • 寻找ProjectReference件商品
  • 存储Name代码
  • 的值
  • 删除ProjectReference
  • 对于上面找到的每个Name,添加一个简单的引用,例如<Reference Include=name HintPath=/path/to/artefacts>
  • 保存项目文件

如果您使用C#和Microsoft.Build.Construction命名空间中的类,那么编写这样的程序相对容易,因为它们可以处理项目文件。否则你可以使用自己喜欢的xml库。

修改

回应您的评论/回答:您的构建环境似乎有点瘫痪。你可以花很多时间来找出变通方法等,或者你可以一劳永逸地修复它。根据我的经验,第一个选项导致越来越多的问题,最终你会留下一个单片块,即使是最轻微的改变也会导致问题的瀑布需要更多的时间来解决所有问题。另一方面,第二个选项(例如,不依赖于SolutionDir并将目标放在所有项目可访问的公共位置 - 没有具有相同名称的不同项目输出程序集,......)现在可能需要更多时间,但是最终它将是值得的,你将留下一个相当干净的构建系统,易于扩展,你将不会浪费更多的时间在未来。此外,如果您现在解决所述问题,您可能只需使用类似我的上一个解决方案,而您不需要选择元素/多个项目/条件/ ...等:该脚本创建一个刚刚用于的全新项目文件链式构建,没有别的。

答案 1 :(得分:0)

@stijn:

由于此消息太长而无法发表评论,我将其作为答案撰写 感谢您的回复和所有建议。 正如您所提到的,使用NuGet会使开发人员的环境变得复杂,因此这是不可能的。 我正在使用从.dll到.csproj的Microsoft.Build库切换引用来构建一个“主”解决方案。我喜欢你的想法,我也一直在考虑它,导入目标时出现问题,它们依赖于MSBuild的SolutionDir属性,与命名项目不一致,我们有两个不同的项目(。网络版)和相同的AssemblyName,.... 我可以继续使用条件构建并重新创建新的解决方案文件,例如* .TeamCity.sln,* .Dev.sln
我可以使用条件与导入,引用,... 我可以创建一个工具,自动删除新引用并将它们添加到Choose部分,从VisualStudio中删除引用已完成属性(它会删除ProjectReference部分中的Choose标记),以及我的提交后工具可以检测到这些更改。由于公司的政策是所有项目都有前缀,我可以很容易地区分哪些项目与我相关。相当大的问题是Microsoft.Build.Evaluation不支持Choose部分,因此我必须编写整个项目解析,例如XDocument

我对此解决方案仍然不是100%满意,我仍然愿意接受建议。