11

好的,这可能是一个很长的。

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

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

  • 主存储库,“主干”位于其自己的虚拟主机中的开发服务器上
  • 每个开发人员都为特定的错误/增强/添加创建一个分支,并拥有自己的虚拟主机

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

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

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

  • 一旦该合并过程经过测试和批准,我们就会进行部署(我猜这可以作为任务/目标添加到部署作业中,这会在上述步骤中通过所有测试时自动发生?)到实时站点。

3)我在某处读到人们也在现场检查了一个主干,并且部署任务只是执行 svn 更新而不是执行文件的 FTP 任务。再次,这是正确的方法吗?

++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++
我也对詹金斯工作区有些困惑。我使用的模板设置为将 build/ 文件夹转储到工作区中。将 SVN 设置为选项,这似乎也将项目检出到工作区中。工作区的目的到底是什么,一旦它被填充,你会如何处理它?

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

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

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

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

3) 使用 rysnc 或类似工具?

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

4

2 回答 2

13

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

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

如果您决定使用私有分支,我建议您设置两个Jenkins 实例。第一个将是官方的。您构建了主干和发布分支,而不是开发者分支。这个 Jenkins 会做所有的单元测试。它将存储发布所需的工件。它将报告测试。这将是您的 QA 团队提取版本进行测试的地方。只有您可以在此 Jenkins 上设置作业。

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

回答您的第一个问题:我根本不会在私人分支机构上运行 Jenkins。私有分支曾经被称为沙箱,因为开发人员可以玩他们的。开玩笑的是,开发人员在他们的沙箱中所做的几乎就像小猫在沙箱中所做的那样。在私有分支上强制执行持续集成确实剥夺了该分支的目的。您真的只关心将代码交付到主干后。

这就是为什么我推荐两个 Jenkins 设置。第一个是给你的。每当发生提交/签入时,它将执行构建。第二个是为他们的私人分支的开发人员。他们会根据需要设置作业并在需要时执行构建。它的唯一目的是帮助开发人员确保一旦他们的代码交付到主干,一切都会正常工作。

这样做完全避免了问题 #2:您总是在代码交付到主干之后进行构建,因为那是提交完成的时间。

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

让我们在生产服务器上发布 build #25。

等等,QA 从来没有测试过 build #25,但他们测试了 build #24。

好吧,让我们发布 build #24,我发现它已经修复了 US232 问题。

顺便说一句,我们使用curlwget将软件从 Jenkins 中拉出并放到我们的服务器上。事实上,我们有一个deploy.sh我们使用的脚本。你deploy.sh从 Jenkins 中提取脚本,然后运行它。这会自动从 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 来创建下一个泛型!可以创建一个新的Generic 。听起来很简单:旧基线 + 选定的更改 = 新基线。

不幸的是,MR 会影响文件相同的文件。事实上,新泛型包含不是由实际开发人员编写的文件版本的情况并不少见。此外,一个 MR 最终依赖于另一个 MR。经理会声明 MR 1001、1003 和 1005 在下一个版本中。我们尝试将这些 MR 添加到基线中,我们发现 MR 1003 依赖于 MR 1002,而 MR 1002 也依赖于我们不想释放的 MR 1008。我们在接下来的一周里试图制定出一组可发布的 MR,并最终发布从未经过彻底测试的软件。

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

2)没有时间限制——每个任务都可以慢慢完成,并且不会影响其他任务。

任务总是会相互影响,除非它们是针对两个完全不同的软件包,这些软件包在两台完全不同的机器上运行,并具有两个独立的数据库。

所有任务都有时间限制,因为时间有成本,任务有收益。一项耗时长但收益甚微的任务是不值得做的。

开发的工作之一是确定这些任务的优先级:哪些应该先完成,哪些应该稍后完成。耗时过长的任务应分解为子任务。

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

3) - 发布和部署也可以在每个任务的基础上完成,而不是等待其他任务完成,然后在固定时间点进行多任务发布(我们试图摆脱这种情况)

我所说的都不意味着您不能进行基于任务的开发。使用 Git 的网站经常这样做。敏捷过程假设了这一点。这并不意味着您要回到瀑布方法,在这种方法中,在布置好每一个令人痛苦的细节之前,不允许任何人触摸键盘。但是,您不能简单地执行 50 个单独的任务,然后在发布前一天挑选您想要包含的任务。你不是发布任务,而是发布一个软件产品。

使用任务分支。但是,就您而言,任务在其更改位于主干之前是不完整的。开发人员对此负责。他们必须变基(将主干的更改合并到他们的分支中),测试他们的变基代码,然后交付(将他们的更改合并回主干),然后项目才能认为该任务完成。

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

想想 Git 和 Linux 的工作原理。Linux 有一个官方的 Git 存储库。你从这个存储库中拉取并在你的机器上创建你自己的 Git 存储库。您可以与您的朋友共享此 Git 存储库。你可以随心所欲地做任何事。您可以从您的 Git 存储库创建另一个 Git 存储库,或者提取官方 Git 存储库的另一个副本,或者找到其他拥有 Linux 的 Git 存储库的人并从那里提取。

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

于 2013-03-13T12:46:02.413 回答
0

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

我知道 Git 的学习曲线很陡峭,但我已经使用这个过程将近一年了,它确实改进了这个过程。

于 2013-03-13T11:56:43.467 回答