构建服务器/CI 设置 - 在应用程序中使用最新组件
我终于开始抽出时间来了解持续集成过程。 我已经开始在家里组装一个构建服务器,并尝试了解如何处理构建中的不同情况。
如果我有应用程序“B”使用的组件“A” - 告诉构建服务器编译“A”然后使用新编译的“A”编译“B”的“最佳实践”是什么显然
,我希望了解如何集成工作组件,我看到了很多数据库示例,但没有看到有关使用 DLL 等的内容。
非常感谢!
I have finally started to take the time out to grok the continuous integration process. I have started putting together a build server at home and trying to grok how to deal with different situations in building.
If I have component "A", which is used by application "B" - what is the "best practice" for telling the build server to compile "A" and then compile "B" using the newly compiled "A"
Obviously, I am looking to see how I integrate working components, I see lots of database examples but nothing on working with DLL's etc.
Thanks a lot!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有两种方法可以解决此问题:
1 - 您的依赖组件是否独立并在各处重用
或
2 - 这是一个大型系统的一部分,该系统相互依赖但很好地模块化到不同的项目中。
我不能 100% 确定第一种情况下的最佳实践是什么,但我可以解释我在第二种情况下所做的事情。
假设您有以下结构
/trunk
/trunk/Rob.Core
/trunk/Rob.MyCoolApplication.Server
/trunk/Ron.MyCoolApplication.Client
每个都是“顶级”应用程序,每个应用程序都有自己的解决方案和目标,它们独立编译,但它们是同一系统的一部分。
为了以最小的麻烦获得“平滑”的构建集成,我总是建议尝试在开发和构建服务器上重现相同的环境。 因此,当您签出编辑这些应用程序时,您应该将 /trunk 签出到 /MyTrunkFolder。
现在,我倾向于做的是,作为对任何可重用的 .dll 或组件的构建后操作,设置一个构建后操作,将其构建输出(在发布模式下)复制到:
/trunk/CompiledOutputs/AppOrLibName
/重要的是,该文件夹永远不会签入,它应该通过构建先决解决方案来生成。
现在,当将 Rob.MyCoolApplication.Server 中的引用添加到 Rob.Core 时,您实际上添加了对 /trunk/CompiledOutputs/Rob.Core/some.dll 的引用。
这样您的开发环境看起来就像您的构建服务器一样。
正确连接依赖项后,您需要在 CI 系统中添加触发器。 在 CCNET 中,对于上面的示例,我在 Rob.Core 的成功构建上放置了一个触发器,以触发 Rob.MyCoolApplication.Server 的构建。
当您对系统进行全新检查时,建议使用一个批处理脚本来按依赖顺序触发 msbuild 来构建您的环境。
仅当您始终希望根据最新版本的组件构建应用程序时,上述内容才有效。 如果不是这种情况,您可能希望将引用的程序集的检入文件夹作为使用它们的应用程序的一部分,然后在有效时手动更新到已编译组件的新版本所以。
关于这个主题的文章很少,所以大部分只是在 3-4 个项目中摸索和推断的,但它在我最近的两个大型项目中肯定是可重复和可靠的。 显然,一如既往,您的里程可能会有所不同。
There are two ways to approach this problem:
1 - Are your dependant components stand alone and reused everywhere
or
2 - Is this part of a large system that's co-dependant but well modularised into different projects.
I'm not 100% sure what the best practice would be in the first scenario but I can explain what I do in the second.
Say you have the following structure
/trunk
/trunk/Rob.Core
/trunk/Rob.MyCoolApplication.Server
/trunk/Ron.MyCoolApplication.Client
Each of those are "top level" applications, each with their own solution and targets, they compile independently but they're part of the same system.
In order to get "smooth" build integration with minimal fuss, I'd always recommend trying to reproduce the same environment on both dev and build servers. As such, when you check out to edit these applications, you should check out /trunk into /MyTrunkFolder.
Now, what I've tended to do, is as a post build action on any reusable .dll's or components, set up a post build action that xcopys it's build output (in release mode) to:
/trunk/CompiledOutputs/AppOrLibName/
It's important that this folder is never checked in, it should be generated by building the pre-requisite solutions.
Now, when adding references in Rob.MyCoolApplication.Server to Rob.Core, you actually add a reference to /trunk/CompiledOutputs/Rob.Core/some.dll.
This way your development environment looks exactly like your build server.
Once you have your dependencies wired up correctly, you then need to add triggers in your CI system. In CCNET, for the above example, I'd put a trigger on the successful build of Rob.Core to trigger the build of Rob.MyCoolApplication.Server.
When you do a fresh checkout of your system, it's advisable to have a batch script that triggers msbuild in dependency order to build your environment.
The above is only valid when you always want your applications to be build against the latest versions of your components. If that wasn't the case, you'd probably want to have a checked in folder of the referenced assemblies as part of the application that used them, and then manually update to new versions of your compiled components as and when it's valid to do so.
There's very little written on this subject so most of this was just felt out and extrapolated over 3-4 projects, but it's certainly been repeatable and reliable on my last two LARGE projects. As ever, obviously, your mileage may vary.
几乎所有 .net 构建服务器都使用该解决方案来获取项目引用/依赖项。 要考虑的主要事情是构建路径必须镜像您的开发路径。
现在,需要明确的是,如果您正在使用 GAC 的程序集,那么这些程序集也必须在您的构建服务器上经过 GAC 的处理。 否则你会遇到问题。
以您的示例为例,您的解决方案文件中应同时包含项目 A 和 B。 此外,A 应该存在对 B 的项目依赖性。您可以通过右键单击项目 B 中的“引用”文件夹,选择“项目”选项卡,然后选择“项目 A”来完成此操作。
该信息与项目 B 一起存储。解决方案维护链接B 的参考文献和项目 A 之间的关系。我希望这是有道理的。
Pretty much all of the .net build servers work off of the solution in order to get the project references / dependencies. The main thing to take into consideration is that the build path must mirror your dev path.
Now, to be clear, if you are using GAC'd assemblies, then those assemblies must also be GAC'd on your build server. Otherwise you will run into problems.
Taking your example, your solution file should have both projects A and B in it. Further, there should be a project dependency on B for A. You accomplish this by right clicking on the References folder in project B, select the Projects tab, and select Project A.
That info get's stored with Project B. The solution maintains the link between B's reference and project A. I hope that makes sense.
Ant 和 nAnt 是几个用于 Java 和 .Net 的构建工具,它们是可能有帮助的脚本示例。 Msbuild 或 巡航控制 如果您想要更多想法,也可能是有用的工具。
我可能会使用一些脚本,说明在构建 B 时必须首先构建 A,这是大多数现代构建工具支持的依赖项。
Ant and nAnt are a couple of build tools for Java and .Net that are examples of scripts that may help. Msbuild or Cruise Control may also be useful tools if you want some more ideas.
I'd probably use some script that says in building B that A has to be built first, which is a dependency that most modern build tools support.