如何将发布的二进制文件保持在版本控制之下?


14

如何将发布的二进制文件保持在版本控制之下?这样可以跟踪在每个发行版之间更改了哪些内容。我的意思是将发布的二进制文件与源存储库分开。发行的二进制文件可以从Continuous Integration软件构建,也可以手动编译。


“跟踪哪些内容已更改”是什么意思?您(或希望)跟踪发布二进制文件的哪些属性?这似乎很奇怪,所以我很好奇。
杰里米·海勒

例如在v1.0.0和v1.0.1之间,仅更改了ABC.exe,而依赖项DEF.dll保持不变
linquize 2012年

1
您如何通过查看二进制文件来确定这一点?
杰里米·海勒

diff同一文件的旧版本和新版本
linquize 2012年

Answers:


21

两种选择:

a)不要。只要确保您具有可复制的确定性构建,即使用相同的配置构建相同的源代码控制修订版就始终会产生完全相同的二进制文件。

b)指定某个目录作为发布构建的权威来源。确保上传二进制文件是部署/运输过程的一部分,并确保备份计划覆盖了build-build目录。您在这里不需要任何版本控制;构建是一次写入的,如果您需要更改任何内容,则可以进行新的构建。

无论哪种方式,由于多种原因,二进制文件和其他构建输出都不属于源代码控制。


7
一)通常是不可能的,当然blogs.msdn.com/b/ericlippert/archive/2012/05/31/...
JK。

@jk:不错的链接。我猜想,在很多实际场景中,具有完全由源代码控制的构建阶段的源代码和所有输入文件(并安装了正确的编译器版本)可能“足够确定”(当然,在其他场景中还不够) )。视情况而定,逐位生成可复制的二进制文件有多重要。
Doc Brown

10

将工件存储库用于二进制文件,而不是版本控制系统。发行的二进制文件的特定版本不应该随时间更改,因此版本控制没有意义,因为文件不会更改。

例如,将Maven存储库视为用于归档/发布/提供发行版和其他二进制文件(例如文档)的存储库


发行的源文件的特定版本也不应随时间更改。SCM是放置已交付的二进制文件的好地方,您只需将其与用于构建二进制文件的源文件一起存储。
gbjbaanb 2012年

2
gbjbaanb,SCM代表“源代码管理”。这应该给任何人一个暗示,即这些系统并非旨在存储二进制文件而是源文件。如果仍然要存储二进制文件,请继续。我不会
mhaller 2012年

4
SCM代表“软件控制管理”,但不错的尝试。“源代码”,往往不只是文本文件,但图像,文档,图表等
gbjbaanb

通常,“软件配置管理”。我从未听说过“软件控制管理”。
詹姆斯·麦克劳德

7

只需将它们放进去就可以了。除非您正在使用git(合并二进制文件的方式不佳,所以您必须自己管理它们)或您提交它们的次数过多(仅在提交时提交),否则就没有问题。准备发货,而不是每次建造时都可以)。

大多数SCM增量二进制文件都很好,我们过去通常将2Mb资源dll放入我们的SVN中,并且每次都会增量到几kb。

我听到很多争论,说SCM是源文件,而不是二进制文件,但是当您认为大多数软件都由图像组成时,即使它们只是图标文件,这显然是错误的。它们是二进制文件,但它们是源文件的一部分,因此请将它们放入文件中,不要过于拘泥于此。我还听说您可以仅在需要时重建二进制文件(通常是这种情况),但是对于不再受积极支持的旧系统,这可能会花费大量时间。如果您必须仅使用较旧的Service Pack或修补程序来重新创建系统,以与3年前用于构建二进制文件的系统相对应,那么您很高兴将当时的bin添加到SCM中。

唯一需要担心将构建添加到SCM的情况是,如果您在构建服务器过程中自动进行了构建,请不要这样做。您将使用对您没有好处的构建来填充SCM。而是仅在发布它们时添加它们。这样,您就可以确切地了解客户拥有什么,并且可以使用客户正在使用的二进制文件来重现客户报告的所有问题,而不是已经重建的二进制文件(例如,使用编译器或OS的最新更新)。


1
@ MarnenLaibow-Koser您显然没有在该行业工作很长时间了。构建环境会随着时间而变化,因此尽管您可以重建旧的环境,但您可能不得不花费数天时间使用正确的旧工具和SDK重新创建环境。我希望您对此进行了版本控制
。...– gbjbaanb

1
我想您将能够使用Microsoft认为不再适合发布的旧SDK来构建在XP计算机上编译的旧VC6二进制文件。如果有人要求提供该二进制文件,则可以轻松地从存储其他所有文件的同一位置获取它。与必须重建的痛苦相比,管理它的成本是巨大的,并且与源一起存储它的成本是微不足道的。我去过那里(当客户报告一个错误时,使用由第三方控制制作的VB6应用程序-获取二进制文件并运行它比重建它要容易得多,事实证明这是不可能的)
gbjbaanb

1
@gjbaanb我也将承认您与我的处境不同:我所有的外部依赖项都是OSS,因此它们不能消失,只是因为某些公司不再适合发布它们。
Marnen Laibow-Koser

1
我的观点是,供应链管理系统可以储存一切,所以没有必要单独从源存储二进制文件。它方便易用,并保证您知道几年后会发生什么。这样做没有缺点。任何给定的发行版本身也仅与一个特定的源提交同步。除了某些人认为SCM仅表示源代码文本之外,我看不到问题所在。不,使用它来存储几乎所有内容(有时使用inc生成工具或libs,如果它们不是很大的话),则生活变得容易得多。
gbjbaanb

1
@gjbaanb我的意思是您对此有误。:)当然,VCS可以存储所有内容,但是它们的存储方式设置不佳,只能存储一次提交的文件(毕竟,您不希望您的r500建在r550的存储库中;这只会令人困惑) 。将构建工件存储在存储库中的根本问题不是它们是二进制文件,而是它们是派生数据,并且将与同一存储库中的源不同步。我使用的相同参数将应用于生成的文本文件。
Marnen Laibow-Koser

5

我不将发布二进制文件保持在版本控制之下。相反,我将它们发布到定义明确的位置,以便其他工具进行检查和使用。我在Java中做了很多工作,所以这意味着我将Jars发布到本地Maven存储库。但是,我不使用这些工具来跟踪每个版本的变化。毕竟,它们是二进制文件,除了文件计数之外,没有什么可追踪的。

为了跟踪版本之间的更改,我会在版本控制系统中用版本的版本号标记或标记版本。但这实际上仅是跟踪源文件,而不是二进制文件。二进制文件是构建的工件,不需要受版本控制。


1

最好的解决方案是将CI系统专用于所有组织上重要的构建(发行版,候选发行版等)。

这系统地将发布的二进制文件与存储库内容相关联,而不必将二进制文件实际存储在存储库中。

例如,如果您使用的是SVN,请使用主要分支机构的方案;在/ trunk中进行日常开发,并在每个发行版就绪后为其创建/ tag。

配置您的CI系统以从标记以及从中继构建,并使其将输出写入网络目录,该网络目录的结构反映了回购协议的顶级结构:

  • / builds / trunk / [rev] [date] [build_id] /
  • / builds / tags / release_0_1_3beta4 / [rev] [date] [build_id] /

构建系统将需要将/ builds / trunk /目录视为循环缓冲区,存储最后的n个构建,并删除旧的构建。

/构建/标签/目录下,在另一方面,是一个永久性的存储。构建工件本身存储在目录中,该目录具有根据以下方案生成的名称:

  • [rev] [date] [build_id]

其中[rev]是SVN修订版ID,[date]是YYYYMMDD格式的日期,[build_id]是3位数字的唯一计数器,从第一个构建版本开始递增,从而使每个构建目录都是唯一的。

上面详述的过程为您带来以下好处:

  1. 构建工件被系统地绑定到生成它们的源,因此您可以非常容易地找到特定构建工件的源(反之亦然)。

  2. 这构成了进一步的发行自动化的基础。例如,自动生成发布文档等...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.