0

在我们的网络代理商店中,我们有多个客户。我们使用 SVN,但我们不使用 CI。我想更改它并设置 CC.NET,但我无法启动它,因为我无法确定最佳方法。我在这里有机会以正确的方式重组事物,我想抓住它,但我无法制定出“理想”的结构。

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

但是,我们的一个客户更大,拥有多个存储库、解决方案和网站,在某些情况下,这些存储库跨多个存储库共享公共库。此外,该客户的一些解决方案具有项目引用,其中实际项目只不过是很少更改的包装器。对我来说,构建这些项目然后只包含程序集引用是有意义的。

我目前正在考虑类似下面的结构,但我怀疑它使事情复杂化,而不是帮助,特别是对于多个装配级别。我认为我应该删除顶层程序集,它位于任何客户端存​​储库之外,并且只接受 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 文件夹中,从而使更新的版本可用于依赖它的任何其他项目。

我是不是把事情复杂化了?这种设置的理想回购/解决方案/项目/目录结构是什么?

4

2 回答 2

0

结构

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

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

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

然后对于每个项目,我们使用 svn:externals 功能,我们在其中引用了项目所需的任何其他库,并且在 References 中可用。
内部用于我们自己的库。外部用于第 3 方。

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

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

CCNet

要考虑的另一件事是不同项目的 CCNet 配置。由于我们每个项目都有相似的结构,因此复制每个项目并修改几个属性(解决方案文件名、存储库路径等)很容易,甚至有一些简单的应用程序可以为我做这件事。

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

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

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

于 2013-05-09T10:31:52.817 回答
0

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

[供应商名称] [库名称] [版本号]

您已经打开了被称为“如何处理我的 BINARY 依赖项”的蠕虫罐头。

并试图找到一个处理该问题的 SVN 解决方案。

所以你想找出快速修复?或者你准备好投入一些时间了吗?

…………

自 2005 年以来,来自 Apache 的“Ivy”一直在处理二进制依赖问题。“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(即使在 Microsoft 世界中),因为我在说出“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(使用命令行选项)。

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

===================编辑

至于“源代码结构”,我这样做:

\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”。

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

于 2013-05-10T14:35:34.107 回答