C#,TeamCity - 避免在TeamCity服务器上执行后构建事件

9

我有许多项目在开发环境中输出到一个中央DLL存储库。这是通过在项目的Post-build事件命令行中添加XCopy命令实现的。

XCOPY $(TargetDir)$(TargetFileName) C:\DEV\library /I /R /Y

我希望在开发模式下实现这一点,但在TeamCity服务器上,我希望避免脚本被执行。有什么最好的方法吗?我将搜索谷歌和文档,但希望其他人以类似的方式使用TeamCity,并建议如何实现。
谢谢。
编辑:
XCopy应该将dll复制到一个中央文件夹(C:\ DEV \ library),依赖于它们的外围项目可以访问该文件夹。实际上,我已经从项目中删除了xcopy,因为我觉得使用它更像是一种hack而不是一种帮助。感觉像是把方形钉子塞进圆孔里。

你能否更新一下你的问题并解释一下为什么首先要使用xcopy?根据你使用它的原因,可能会有更好的解决方案。 - Bronumski
3个回答

3
据我所知,您之前使用XCopy将生成的输出复制到外部文件夹,以便相关解决方案可以使用该输出作为程序集引用。您正确地发现,使用后期构建事件和XCopy是错误的,因为它开始给您带来痛苦。我们的API解决方案中有类似的目标,我将尝试描述一下我们如何处理,但请记住,没有万能的方法,有时仍需要妥协。

项目结构

项目结构指的不是Visual Studio内部的结构,而是如何组织源代码、库和其他项目所需的外部项的方式,这个模式适用于大多数编程语言。项目结构应该清晰、易于理解,并且对所有项目保持一致。我使用一种与许多开源项目一致的结构,通常包括以下内容。
- root
|-- bin
|-- build
|-- lib
|-- src
|-- tools
  • root - 根目录应该尽可能少的包含项目文件。
  • bin - 编译输出文件应该放在 bin 文件夹中。如果只有一个输出文件,例如 Web 项目,则可以保留在原地。我发现没有必要为调试和发布版本建立子文件夹。
  • build - 包含构建文件,如 MSBuild 或 NAnt 脚本用于构建源代码、运行测试、代码覆盖率、代码分析、文档等。
  • lib - 包含所有第三方库,无论是外部还是内部,这些库都是项目输出所依赖的。我通常为每个库使用子文件夹,但不确定是否真的需要。
  • src - 包含打开项目、编辑、构建和在所选 IDE 中运行所需的所有文件。尽量使此处的结构尽可能平坦,因为试图使其过于复杂是没有意义的,因为其他开发人员不太可能像你一样有条理,你最终会得到错误的项目文件夹。我最多只创建一个测试文件夹来存放所有测试,但这也不是真正必要的。
  • tools - 此文件夹包含所有应用程序、程序集、外部文件,构建依赖于它们,但源代码不应该依赖于它们,因为它们的依赖关系在库上。

文件路径

项目中的所有文件路径都应该是相对的。一旦你开始使用绝对文件路径,就会感到痛苦。在开发机器上,开发人员的源代码位于不同的驱动器上或在构建服务器上时,问题将会出现,这样很难强制执行项目的运行位置。

通常的经验法则是项目应该是自包含的。在理想情况下,不应该有任何依赖于根目录之外的东西。有时这很困难,特别是在遗留项目中或者当您需要 com、注册表或服务要求时,但通过一点思考和重构,大部分这些问题都可以得到缓解。最终,您希望能够尽可能轻松地将项目放入给定的计算机并运行它。

构建输出

当我做 API 项目时,我将项目输出放入了上面提到的 bin 文件夹中。你已经在后期构建事件中使用 XCopy 来实现这一点。这并不是完全错误的,因为它可以实现你想要的效果,但在 Visual Studio 中,有更好的方法。如果您进入项目属性的构建部分,您可以更改输出位置。在更改之前,请记得选择所有构建配置。

从外部项目引用程序集

将API分离为单独的解决方案并将其输出作为程序集引用而不是项目引用的原因之一是因为要么解决方案变得太大,要么需要从多个解决方案中引用它们。如上所述,项目不应依赖于项目根目录之外的任何内容。因此,您不应该依赖于外部项目的输出,因此依赖于A.开发人员计算机上存在该项目和B.位于正确位置。
我有几种方法可以克服这个问题:
1. 将API项目作为子项目嵌入到主项目中,使用类似Git的Sub Modules或SVN的Externals。这在某种程度上有效,但需要注意一些预防措施,互联网上有丰富的知识。
2. 将程序集添加到依赖项目的lib文件夹中,并将其视为第三方程序集,这才是它们真正的身份。
第二步是我首选的方法,这可以在构建服务器上自动完成,也可以通过将构建服务器的输出手动复制到本地项目来手动完成。这完全取决于您想要持续集成还是定期集成。

1
+1 谢谢你的回答,我觉得这是最好的答案,因为我感觉使用 XCopy 就像在以混乱的方式黑客我的代码来实现我想要的功能。你所概述的方法简洁明了,是其他开发人员现在正在使用的模式,但最重要的是,你没有直接回答我的问题,而是问了我的问题是什么,最终给了我一个更好的解决方案。 - Mr. Mr.

3

在您的构建配置或构建代理配置中定义环境变量,并仅在未设置变量时触发复制命令,如此处所述:抑制后期生成事件


1

你可以用自己的程序替换“xcopy”,比如说myXCopy。
myXCopy可以检查一个环境变量来决定是否进行复制。
然后你可以控制何时设置这个环境变量。

或者

编写自己的MsBuild任务来执行复制操作。
将你的任务挂接到标准编译任务的末尾。
让TeamCity传递一个MsBuild变量给你的自定义任务进行检查。


谢谢Ian,我会进行测试并告诉你结果。 - Mr. Mr.

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