理想的cruisecontrol.net svn多个解决方案/ repo /项目的目录结构

时间:2013-05-09 01:18:30

标签: svn cruisecontrol.net

在我们的网络代理商店,我们有多个客户。我们使用SVN,但我们不使用CI。我想改变这个并设置CC.NET,但我无法实现它,因为我无法确定最佳方法。我有机会以正确的方式重组事物,我想接受它,但我无法弄清楚“理想”的结构。

大多数客户都有一个简单的结构,例如每个客户端包含一个解决方案/网站的存储库从长远来看,无论我选择什么,都应该很容易为这些小型项目设置。

但是,我们的一个客户规模较大,有多个存储库,解决方案和网站,在某些情况下,它们共享多个存储库中的公共库。此外,这个客户端的一些解决方案有项目引用,其中实际项目只不过是很少改变的包装器。对我来说,构建这些项目然后只包括Assembly引用是有意义的。

我目前正在考虑类似下面的结构,但我怀疑它的复杂性不仅仅是帮助,特别是对于多个装配级别。我想我应该删除顶级程序集,这些程序集将位于任何客户端存​​储库之外,并且只接受MVC或NUnit必须存储在每个客户端下的多个文件夹中。我还需要在开发人员机器上考虑这种结构,而不仅仅是构建服务器。

D:/Projects

    Tools
        // Folders containing dlls and libraries relating to the 
        // CI build process, e.g. FXCop, StyleCop settings, etc.

    Assemblies
        // third party/common assemblies referenced by multiple clients, 
        // e.g. NUnit, MVC:

        [VendorName]
            [LibraryName]
                [VersionNumber]

    [ClientName]
        [Assemblies] (Possibly a new SVN repository?)
            // Third party assemblies that are used only by this client.
            // and also where the client's own shared assemblies will live
            // after a successful build, for other Projects to reference.

            [ThirdPartyVendor]
                [ThirdPartyLibrary]
            [ClientName]
                [ProjectName.dll]

        [Library/Website]
            ProjectName.sln
            CC.NET project build scripts
            [ProjectName] // The main codebase
            [ProjectName.Tests] // Unit Tests
            [Artifacts] // CC.NET Artifacts
            [Documentation] // For XML Docs that will be built nightly

这个想法是,当一个库构建并完成相关测试时,如果另一个项目依赖于它,它会将生成的DLL复制到客户端的Assemblies文件夹中,使更新版本可用于依赖它的任何其他项目。

我是不是太复杂了?这种设置的理想repo / solution / project /目录结构是什么?

2 个答案:

答案 0 :(得分:0)

<强>结构

我没有遇到你的确切情况,但是一旦我们遇到类似的情况,我认为 - 我们为同一个客户提供了多个项目。这些项目实际上是相似的 - 它们具有相似或相同的文件夹结构,它们大多使用相同的外部库等等。

在某些时候,我们还决定将所有这些库保存在一个地方,并将它们提供给所有项目。所以在我们的例子中,我们有以下结构:

Client_name/  
-- References  
-- -- Internal  
-- -- External  
-- Project 1  
-- -- ...  
-- Project 2  
-- -- ...  

然后,对于每个项目,我们使用了svn:externals功能,我们引用了项目所需的任何其他库,并在参考文献中提供。
内部是我们自己的图书馆。第三方外部。

这样我们可以在一个地方控制所有依赖项。当然,在每个项目中更新特定引用都是手动过程 - 它没关系,因为我们想确保新库不构建任何东西,有时我们需要一些修改版本等因此每个项目的自动更新是不是真的建议。虽然可能很容易做到。

稍后,其中一些内部引用被转换为nuget包,在构建之后我们将它们放在共享位置,只需单击Visual Studio即可轻松更新。

<强> CCNET

另一件需要考虑的事情是针对不同项目的CCNet配置。由于每个项目都有类似的结构,因此复制每个项目并修改多个属性(解决方案文件名,存储库路径等)都很简单,甚至还有一些简单的应用程序可以帮我完成。

然而,现在,我将使用更多巡航控制的预处理器功能和变量定义和覆盖。

这意味着创建一些基本模板,其中包含为每个项目更改的所有属性,并为每个项目覆盖它们。这样您就可以轻松添加具有类似配置的新项目。

对我来说,这一点至关重要,好像你有多个项目,每个项目都有不同的构建,然后CI很快失控并导致坏事......因此,一致性是关键。或者是为了我们:)

答案 1 :(得分:0)

装配     //多个客户端引用的第三方/公共程序集,     //例如NUnit,MVC:

[VENDORNAME]     [库名称]         [VERSIONNUMBER]

你已经打开了一堆被称为“如何处理我的BINARY依赖”的蠕虫。

试图找到一个能够解决这个问题的SVN解决方案。

所以你试图弄清楚快速修复?或者你准备好花点时间了吗?

.......

自2005年以来,Apache的“常春藤”一直在处理二进制依赖问题。几年前,“Nuget”已经登陆。

我们来看一个简单的案例。

您有一个名为“MyPDFHelper.dll”的第三方库(最初版本为1.0.0.1)。 您有2个解决方案,每个包含3个项目。 (VS .sln和.csproj)。

Sln1, CSProjA, CSProjB, CSProjC
Sln2, CSProjW, CSProjX, CSProjY

Sln1/CSProjA depends on MyPDFHelper.dll, 1.0.0.1.
Sln2/CSProjX depends on MyPDFHelper.dll, 1.0.0.1.

PDFHelper发布新版本的MyPDFHelper.dll,1.0.0.2。没有突破性的变化,一切都很酷。

PDFHelper发布了MyPDFHelper.dll 2.0.0.1的新版本。 突然变化。

Sln2 / CSProjX上的开发人员想要使用MyPDFHelper.dll,2.0.0.1。 但是,这将如何影响没有计划从1.0.0.1更新的Sln1 / CSProjA。

显然,您已经看到了这个问题,因为您有[VersionNumber]。

但这是一个哲学问题。 SVN是为源代码(基本上是文本文件)还是作为源代码和二进制存储库的组合而创建的?

Ivy和Nuget是BINARY存储库。

现在,我使用Ivy(即使在微软世界中),因为我在“Nuget”一词被说出之前解决了依赖问题。

...

这是一个稍微不同的问题,但类似。

您拥有相同的“申请”项目。

Sln1, CSProjA, CSProjB, CSProjC
Sln2, CSProjW, CSProjX, CSProjY

但你也有一个带有“框架”片段的.sln。 让我们说它是封装好的电子邮件发送代码。

MyCompany.EmailLibrary.sln MyCompany.EmailLibrary.csproj 它构建到MyCompany.EmailLibrary.dll

Sln1 / CSProjB uses MyCompany.EmailLibrary.dll.
Sln2 / CSProjX uses MyCompany.EmailLibrary.dll.

当您在自己的框架中进行重大更改时会发生什么?

.........

简而言之。

不是将代码放入源代码库,而是

“将其发布”到二进制存储库

在我们的示例中

MyPDFHelper.dll, 1.0.0.1. would be published
MyPDFHelper.dll, 1.0.0.2. would be published
MyPDFHelper.dll, 2.0.0.1. would be published

然后每个“依赖于”MyPDFHelper.dll的项目,它将具有某种配置值,表示“我想使用此版本的MyPDFHelper.dll”。

常春藤符号就像是

“1.0.0+”或“1 +”。

当2.0.0.1为“发布”时,Sln2的配置可以更改为“2.0.0+”。 Sln1配置保持不变,“1.0.0 +”

这样,每个Sln(1和2)将“检索”符合其需要的MyPDFHelper.dll版本。 最终(当开发人员选择这样做时)Sln1可以更改为“2.0.0+”,但开发人员可以在他/她想要时处理重大更改,而不是当其他开发人员将新的第三方dll放入源控制。

.........

现在,谈到MyCompany.EmailLibrary.dll。 基本上,每次MyCompany.EmailLibrary.sln构建时,您都会将新构建放入二进制存储库中。如果您所做的只是错误修复,那么您始终可以发布(并覆盖)版本“1.0.0.1”,但我更喜欢使用递增的数字进行发布。

MyCompany.EmailLibrary.dll v 1.0.0.333
MyCompany.EmailLibrary.dll v 1.0.0.334
MyCompany.EmailLibrary.dll v 1.0.0.444

(数字不重要,只是它们增加的事实。

.........

我会查看Nuget(带有私有存储库)或Ivy(使用COMMAND LINE选项)。

我没有为您提供确切的解决方案,而是向您介绍二进制存储库的概念。

=================== EDIT

就“源代码结构”而言,我这样做:

\DotNet\src\v20Base\v20\
\DotNet\src\v20Base\v20\Applications\
\DotNet\src\v20Base\v20\Framework\
\DotNet\src\v20Base\v20\ThirdParty\


\DotNet\src\v20Base\v35\
\DotNet\src\v20Base\v35\Applications\
\DotNet\src\v20Base\v35\Framework\
\DotNet\src\v20Base\v35\ThirdParty\


\DotNet\src\v40Base\v40\
\DotNet\src\v40Base\v40\Applications\
\DotNet\src\v40Base\v40\Framework\
\DotNet\src\v40Base\v40\ThirdParty\

\DotNet\src\v40Base\v45\
\DotNet\src\v40Base\v45\Applications\
\DotNet\src\v40Base\v45\Framework\
\DotNet\src\v40Base\v45\ThirdParty\



Example Application
\DotNet\src\v40Base\v40\Applications\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\SodaManagerSolution.sln
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\Pres.AspNet\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\Pres.WPF\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\BusinessLogic\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\DataLayer\
\DotNet\src\v40Base\v40\Applications\SodaManagerSolution\SqlScripts\

Example Framework
\DotNet\src\v40Base\v40\Framework\
\DotNet\src\v40Base\v40\Framework\MyCompany.EmailLibrary\
\DotNet\src\v40Base\v40\Framework\MyCompany.EmailLibrary\MyCompany.EmailLibrary.sln
\DotNet\src\v40Base\v40\Framework\MyCompany.EmailLibrary\MyCompany.EmailLibrary.csproj

DotNet 3.5(和3.0)在2.0上“覆盖”。因此3.5解决方案可以使用2.0 dll而没有问题。 4.0是一个新的CLR,因此是新的“v40Base”。

它可能感觉有点过分,但是当框架在大型源代码存储库中发生变化时,它会开始让哪个项目可以引用其他项目而感到困惑。