持续集成工作流程& SVN

时间:2013-03-13 11:28:25

标签: svn jenkins continuous-integration

好的,这可能很长。

我正在尝试对我们在工作场所进行的设置进行标准化和专业化,以便对我们的软件进行实时更新。目前,一切都是手工的;所以我们有机会从头开始。

我已经安装了jenkins,有要使用的存储库,有一个工作模板(基于http://jenkins-php.org)并且考虑到当前的工作流程:

  • 主存储库,'trunk'位于开发服务器上的虚拟主机
  • 每个开发人员使用自己的虚拟主机
  • 为特定错误/增强/添加创建分支

1)第一个问题:在这个阶段,一旦开发人员提交给他的分支机构,是否建议练习运行jenkins job / build?这将运行单元测试和其他一些东西(根据上面链接的模板)

  • 一旦开发人员分支经过测试,批准等,首席开发人员将该分支合并到主干

2)在这个阶段,我想在合并完成后再次重新运行jenkins作业。这是可能的,这是正确的方法吗?

  • 一旦合并过程经过测试和批准,我们就会进行部署(我猜这可以作为任务/目标添加到部署作业,这是在上述步骤中传递的所有测试后自动发生的吗?)到现场。

3)我已经阅读过某些地方,人们也在实际网站上检查了一个中继,而部署任务只是执行svn更新,而不是执行文件的FTP任务。再次,这是正确的方法吗?

+++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++
我也对jenkins工作区有点困惑。我正在使用的模板设置为将build /文件夹转储到工作区中。将SVN设置为选项,这似乎也可以将项目结帐到工作区中。工作区的意图究竟是什么,以及填充后你用它做什么?

+++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++
更新:

部署到实时服务器......似乎我有3个选项:

1)在实时站点上有一个已检出的trunk副本,.svn文件和用.htaccess隐藏的目录,并在准备好后运行svn update。这样做的好处是,它的速度快,可以回滚。缺点是,安全问题?

2)svn直接导出到实时文件夹(在此过程中暂时关闭网站)或其他文件夹并将apache vhost更改为新位置

3)使用rysnc或类似的工具?

这是更好的选择,还是我错过了更好的选择?

2 个答案:

答案 0 :(得分:11)

通常,通过持续集成,所有开发人员完成的所有工作都在一个分支(或主干)上完成。实际上,Subversion的设计考虑了这种类型的工作流程。 让每个人在同一个分支上工作可能听起来很可怕。毕竟,碰撞怎么样?如果我想在下一个版本中包含一个错误/增强/添加但不包含另一个错误/怎么办?

我的经验是,强制所有开发都在一个分支上进行,效果会更好。它迫使开发人员进行小规模的小心更改并相互合作。处理发布(错误修复和增强)的顺序必须在开发周期的开始时完成,而不是在结束时尝试选择它们。管理人员喜欢在最后选择和选择的灵活性,但这意味着在发布前几天会出现大规模的合并周期,这通常会导致匆忙的测试。

如果您决定使用私有分支,我建议您设置 两个 Jenkins实例。第一个是官方。您构建了主干和发布分支,但不是开发人员分支。这个詹金斯将进行所有单元测试。它将存储发布所需的工件。它将报告测试。这将是您的QA团队将用于测试的版本。只允许您在此Jenkins上设置作业。

另一个将是开发者。他们可以根据需要设置作业并对其进行测试。它将用于他们的分支 - 私有分支或错误修复分支。

回答你的第一个问题:我根本不打算在私人分支机构上运行Jenkins。私人分支过去被称为沙箱,因为开发人员可以玩他们的。开玩笑的是,开发人员在他们的沙盒中做了很多猫咪在沙盒中做的事情。在私有分支上实施持续集成确实剥夺了该分支的目的。一旦代码被传递到主干,你真的只关心。

这就是为什么我推荐两个Jenkins设置的原因。第一个是给你的。只要发生提交/检入,它就会执行 build 。第二个是开发人员的私人分支。如果他们想要并在他们想要的时候执行构建,他们将设置作业。它的唯一目的是帮助开发人员确保一旦代码交付到主干后一切都能正常工作。

这样做完全避免了问题#2:你总是在代码传递到主干后构建,因为提交完成后就是这样。

最后一个,如何将代码放在服务器上更加神秘。我喜欢Jenkins创建一个交付工件。您可以讨论通过Jenkins内部版本号发布的内容。

" 让我们在生产服务器上发布#25版本。"

" 等等,QA从未测试过构建#25,但他们测试了构建#24。"

" 好的,让我们发布版本#24,无论如何我发现US232已经修好了。"

顺便说一下,我们使用 curl wget 将软件从Jenkins中拉出来并放到我们的服务器上。实际上,我们使用了deploy.sh脚本。从Jenkins中提取deploy.sh脚本,然后运行它。这会自动从Jenkins中下载正确的构建并安装它。它关闭服务器,备份旧安装,安装新软件,重新启动服务器,然后报告结果。

然而,有一些关于Subversion为您做送货的想法。使用各种方法。一个是Subversion在生产分支的特定时间自动进行更新。您将代码放在生产分支上,并且每天早上2:00,Subversion将提供您的代码。这是一个很好的想法,而且我已经做到了 - 特别是当你谈论PHP并不需要编译时。

我更喜欢第一种方法,因为你有更多的控制权并强迫你只部署Jenkins构建。此外,通常会出现一些问题,导致 svn update 部署方法失败(碰撞,需要删除的无版本文件等)。当然,这只会在最关键的时刻发生。当然,在你的老板填写你的年度评论之前,这将是一个惊人的失败。

所以,回答你的第三个问题。我首选的方法是不涉及Subversion。相反,我直接在Jenkins服务器上 ftp 构建的工件(使用wgetcurl),并运行真正的部署脚本来处理所需的所有内容。

顺便说一句,我们正在研究与Jenkins集成的各种部署工具,如LiveRebel。想法是Jenkins将构建可交付包并将其部署到LiveRebel,然后IT可以使用LiveRebel将其部署到我们的服务器。我们不确定每个Jenkins构建是否将部署到LiveRebel,或者我们将使用构建促销插件让QA选择要部署到LiveRebel的构建。第二个将阻止我们部署QA未经认证的构建。

附录

  

感谢您的回复和见解。我在考虑每个任务分支的原因有很多原因:

我会回复你的每个理由......

  

1) - 允许任务与主干隔离。

任务也可以彼此孤立地完成。问题是生成的代码与这些任务没有隔离,这些任务可能彼此不兼容。

许多管理者喜欢认为这种隔离将允许他们选择要在下一版本中包含哪些任务,并且他们能够在发布时执行此操作。最早的CM软件包之一被称为AT& T的Sablime,它基于这一理念。

在Sablime中,你有一个 Generic ,这就是他们所说的版本。这是所有更改的基础。每个更改都分配了一个修改请求(MR编号),所有工作必须在MR上完成。

您可以通过采用旧基线通用,添加选定的MR和tada来创建下一个通用!可以创建新的通用。听起来很简单:旧基线+选定的更改=新基线。

不幸的是,MR会影响同一文件的文件。实际上,新泛型包含一个不是由实际开发人员编写的文件版本并不常见。另外,一个MR最终取决于另一个。经理会声明MR 1001,1003和1005在下一个版本中。我们尝试将这些MR添加到基线中,并且我们发现MR 1003依赖于MR 1002,MR 1002也依赖于MR 1008,这是我们不想要释放的MR 1008。我们花了下一周试图找出一套可释放的MR,并最终发布从未经过全面测试的软件。

为了解决这个问题,我们最终在基线之间进行了较小的更改。我们每周会做一个新的 Generic ,有时候会有两个。这使我们能够确保合并工作,并确保在依赖于MR的MR之前首先包含依赖MR。但是,它也消除了整个选择概念。剩下的就是Sablime内置的大量开销。

  

2)没有时间限制 - 每项任务都可以花时间完成,并且不会对其他任务产生影响。

任务将始终相互影响,除非它们是两个完全不同的软件包,它们在两个完全不同的机器上运行,并且有两个独立的数据库。

所有任务都有时间限制,因为存在与时间相关的成本以及与该任务相关的好处。这项任务耗时很长,但收效甚微,值得做。

开发工作之一是优先处理这些任务:首先应该完成哪些任务,哪些应该在以后完成。花费太长时间的任务应该分解为子任务。

在敏捷开发中,没有任何任务可以占用比 sprint 所能承受的资源更多的资源。 ( sprint 是一个迷你版本,通常涵盖两周时间。)在这两周内,开发人员可以实现一定数量的积分有点与小时有关,但不是真的。只是假设一个点代表这个思想实验的X小时工作。)如果开发人员每周可以做15分,那么需要30分的任务对于冲刺来说太大了必须划分为子任务。

  

3) - 也可以在每个任务的基础上完成发布和部署,而不是等待其他任务完成,然后在固定的时间点执行多任务发布(我们试图获得的内容)远离那个)

我所说的一切都意味着你无法进行基于任务的开发。使用Git的网站会做很多事情。敏捷过程假定这一点。这些都不意味着你回到瀑布方法,在每一个令人难以忍受的细节布局之前,不允许任何人触摸键盘。但是,您不能简单地执行五十个单独的任务,然后在发布选择的前一天选择您要包含的任务。您没有发布任务,而是发布了一个软件产品。

使用任务分支。但是就您而言,任务不是完成,直到其更改位于主干中。开发人员对此负责。他们必须 rebase (将更改从trunk合并到他们的分支中),测试他们的重新定义的代码,然后交付(将他们的更改合并回trunk),然后项目才能考虑该任务完整的。

这就是为什么我告诉你,你可以拥有两个Jenkins实例:一个用于主干和发布分支的官方构建,一个用于开发人员完成任务构建。开发人员可以通过他们的Jenkins及其分支机构和他们的开发获得世界上所有的乐趣。它直到它在主干上并且你用你的Jenkins构建它才算不算。

想想Git以及Linux的工作原理。有一个适用于Linux的官方Git存储库。您从此存储库中提取并在您的计算机上创建自己的Git存储库。您可以与朋友分享此Git存储库。你可以做你心中想要的事。你可以从你的Git仓库创建另一个Git仓库,或者拔掉官方Git仓库的另一个副本,或者找一个拥有Linux的Git仓库的人,并从那里开始。

但是,在将这些更改推回到唯一的官方Git存储库之前,您所做的所有更改都不会被视为Linux的一部分。

答案 1 :(得分:0)

我建议使用Gerrit(https://code.google.com/p/gerrit/)。这是一个基于Git的代码审查系统。它与Jenkins(https://wiki.jenkins-ci.org/display/JENKINS/Gerrit+Trigger)很好地集成,因此它可以为每个提交的审核触发构建(即每个提交用于在trunk中合并的提交由jenkins构建)。首席开发人员批准UI中的提交,并将其合并到主干中。

我知道Git学习曲线很陡,但我现在已经使用这个过程差不多一年了,它确实改善了这个过程。