针对同一项目的不同组件的多组开发人员(不位于同一地点)的 svn 部署策略

发布于 2024-09-24 12:35:53 字数 1262 浏览 2 评论 0原文

我们的项目是一个内容管理系统,支持我们的几十个网站。开发团队从小规模开始,在一个地点,我们采用了相当标准的编码/部署策略。

我们对行李箱进行了编码,并坚持要求行李箱干净。每隔几天,我们就会标记主干并部署到测试服务器。如果一切顺利,我们将部署到生产并继续。

这种做法在一段时间内运作良好,直到团队壮大。我们经常遇到这样的情况:标记的修订版存在问题,需要在投入生产之前修复。当负责的开发人员致力于这些修复时,我们让其他开发人员对主干进行更改。一旦原始开发人员的修复完成,添加的新提交就必须随之进行,从而进一步延迟构建,因为现在需要完成额外的验证。

为了纠正这个问题,我们创建了一个单独的主干,严格用于发布。人们会在主干中工作,然后要求项目经理或开发主管将他们的更改合并到发布主干中。

这种做法持续了一段时间,直到团队规模变得更大、更加脱节。我们有 3-5 人的团队,在 4 个地理位置工作 - 一些在相同的组件上,另一些在具有不同优先级和发布计划的不同组件上。这几乎是一份全职工作,对于管理构建的人来说成了一场噩梦。

为了解决这个问题,我们开始根据最新的 Production 标签创建“发布分支”。人们只会承诺那些准备好进行测试并投入生产的东西。其他人会致力于主干,直到轮到他们合并为止。这将合并和解决冲突的负担从构建经理身上转移到了拥有代码的人身上。

这工作了大约一周,直到我们开始不得不进行几个“高优先级紧急”版本。这实际上意味着我们将:

  1. 从最新的 Production 标签创建一个分支
  2. 将紧急内容添加到该分支
  3. 标记该分支并发布到 Production
  4. 将该分支中所做的所有更改合并到常规“发布分支”中坐在质量检查中。

这就是每一天。有时一天两次。

我试图将其与一个开源项目联系起来,其中到处都有开发人员,他们甚至彼此不认识,但他们似乎仍然相处得很好……但是当新的稳定版本经过测试时,这种比较就崩溃了,具有生产价值的构建预计每周(或每天)多次供“公共”使用。例如,如果 Firefox 的日常构建充满了错误,至少用户可以返回到以前的版本或使用最新的稳定版本。对于我们的用户来说情况并非如此。如果我们的发布不完美,它们就无法工作。

背景故事已经完成,我现在提出一个问题:

给定一个环境......

  1. 开发人员遍布各地并致力于不同的组件。
  2. 某些组件的更改可能要等一周才能发布,而另一些组件甚至连一天都等不了。
  3. 该应用程序是关键任务,更改在发布之前必须经过测试并保持稳定。

...您可以推荐哪些建议或替代工作流程来促进更明智的流程,使大部分负担不再由一个人承担?

Our project is a content management system supporting several dozen of our websites. The development group started off small and in one location, and we dealt with a fairly standard coding/deployment strategy.

We coded off of trunk and insisted on a clean trunk. Every few days we would tag trunk and deploy to the test server. If all worked out, we'd deploy to Production and move on.

That worked well for a while until the team grew. We frequently faced situations where the revision that was tagged had problems that needed to be fixed before going to Production. While the developer responsible was working on those fixes, we had other developers committing changes to trunk. Once the original developer's fixes were complete, the new commits that were added would have to go along for the ride, further delaying the build because now there's additional validation that needs to be done.

In an attempt to rectify this, we created a separate trunk used strictly for releases. People would work in the main trunk, and then ask the project manager or development lead to merge their changes into the release trunk.

This worked for a while until the team got even bigger and more disjoint. We have teams of 3-5 people working in 4 geographic locations - some on the same components, others on different components with different priorities and release schedules. This was pretty much a full-time job and became a nightmare for the person managing the builds.

In an attempt to work around that, we started creating "release branches" off of whatever the latest Production tag was. People would commit to there ONLY what is ready to be tested and go to Production. Others would commit to trunk until it was their turn to merge. That took the burden of merging and resolving conflicts off of the build manager and on to the person owning the code.

This worked for about a week until we started having to do several "high priority emergency" releases. This effectively meant that we would:

  1. Create a branch off of the latest Production tag
  2. Add the emergency stuff to that branch
  3. Tag that branch and release to Production
  4. Merge all of the changes that were made in that branch into the regular "release branch" that is sitting in QA.

This is every day. Sometimes twice a day.

I've tried to relate this a bit to an open source project where there are developers all over the place who don't even know each other and they still seem to get by... but that comparison falls apart when new stable, tested, production-worthy builds are expected for "public" consumption several times a week (or day). If Firefox's daily build is a buggy mess, for example, at least users can go back to a previous version or use the latest stable release. That's not the case for our users. If our release is not perfect, they can't work.

Backstory completed, I now pose the question:

Given an environment where...

  1. Developers are all over the place and working on different components.
  2. Changes to some components can wait a week before being released, others can't wait even a day.
  3. The application is mission-critical and changes must be tested and stable before being released.

... what suggestions or alternative workflows can you recommend to promote a saner process where the majority of the burden is not on one person?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦萦几度 2024-10-01 12:35:53

组合维护和发布分支

我认为您和我们的员工有着类似的需求。 CI 可以帮助您实现自动化,但它不能解决根本的组织挑战。

因此,您有两种类型的签入:

  • 正常的非紧急代码(预计每隔一段时间发布一次)
  • 紧急“修补”代码(如果某些内容未经足够的测试而漏掉,或者当客户 X 打电话因为他想要该按钮时,则在发布后发生 )粉色不是紫色,他威胁要放弃合同:P)

两种情况不同,你需要将它们分开。我认为您的方法已经接近答案,但您做得“太多”

让我向您描述我们所做的事情:

存储库布局

trunk (is our project with components and all)
branches
|
-- 1.0-stable-week-40
|
-- 2.0-stable-week-42
|
-- 3.0-stable-week-44
tags
|
-- 1.0.0
|
-- 1.0.1
|
-- 1.0.2
|
-- 2.0.0
|
-- 2.0.1
|
-- 3.0.0

正如您所看到的,我们有一个用于所有主要开发工作的主干。我们还每两周创建稳定的分支用于发布准备和测试,并在所有版本上线时对其进行标记。

发布生命周期(概括)

新版本发布后,我们会维护分支(例如 1.0),直到推出下一个主要版本。
我们的政策是,在此期间,只能将关键修复签入该分支。它们仅经过最少的测试,并且可以通过从我们的维护分支创建新标签在几分钟内发布。

在维护期的中间(发布后 1 周),我们从主干创建了一个名为“2.0”的新分支。主干中所有不那么紧急的开发都将自动包含在此版本中。可以“仔细”添加更多内容,例如来自当前活动维护分支的紧急修复(从 1.0 到 2.0 合并到主干)。

又一周过去了,所有测试都完成了,2.0 分支被标记为 2.0.0 并发布,因为没有出现重大问题。 1.0维护分支最终将被放弃并删除。

这样我们就可以将紧急更改与非紧急更改分开,并获得相对无痛且稳定的发布。
您所做的几乎相同,但是您从一个标签分支,当您完成时,您再次标记。那就有点多了:)。
从标签分支也是不好的风格。来自分支的分支。


用于发布和维护的稳定分支

分支策略

如果您写下策略,这会对团队有所帮助对于您的每种分支类型,使他们能够自己做更多事情,而无需发布人员不断地坐在他们的脖子上并引诱他们的提交;)

我们的政策可以这样描述:

  • 主干:

    • 没有提交有语法错误
    • 接收来自维护的合并
    • 此分支没有直接发布
  • branches/XX-stable

    • 可能仅收到紧急修复
    • 应始终处于“发布就绪”状态
    • 开发人员必须将他的提交从这里合并到任何较年轻的稳定分支
    • 如果没有更年轻的稳定分支可用,则合并到主干
  • 标签/*

    • 此处没有提交
    • 用于部署

提交 一旦您尝试仅合并到一个“方向”,合并也不再是一种思维训练。 (你可能想用谷歌搜索豆腐秤,但现在有点过时了)。
确保合并是由开发人员而不是发布经理连续完成的,以限制瓶颈。
虽然一个版本已经上线并积极维护并接收修补程序,但我们已经准备好开始准备下一个版本,将其与主干中可能不稳定的变化隔离开来,并给它时间“成熟”。

当然,您可能对代码孵化和测试的持续时间或发布迭代的长度有不同的要求。适应 :)

Combined maintenance- and release-branches

I think you are having similar requirements like our people. A CI would help you automate but it does not solve the underlying organisational challenge.

So you have 2 types of checkins:

  • normal non-urgent code (slated for release every once in a while)
  • urgent "hotfixing" code (happens after a release if something slips through without enough testing or when customer X calls because he wanted the button pink not purple and he threatens to drop the contract :P)

Both cases are different and you need to seperate them. Your approach is allready close to an answer I think but you are doing "too much"

Let me describe you what we do:

Repository Layout

trunk (is our project with components and all)
branches
|
-- 1.0-stable-week-40
|
-- 2.0-stable-week-42
|
-- 3.0-stable-week-44
tags
|
-- 1.0.0
|
-- 1.0.1
|
-- 1.0.2
|
-- 2.0.0
|
-- 2.0.1
|
-- 3.0.0

As you can see we have a trunk for all the main development work. We also create stable branches for release preparation and testing every 2 weeks and we tag all releases when they go live.

Release lifecycle (generalized)

After a new release we maintain the branch (1.0 for example) until the next major release is pushed out.
Our policy is that during that time ONLY critical fixes may be checked in to that branch. They go through minimal testing only and can be released in a matter of minutes by creating a new tag from our maintenance branch.

Halfway through the maintenance period (1 week after the release) we create a new branch from our trunk called "2.0". All not-so urgent development allready in the trunk will be in this release automaticly. More things can be added "carefuly" like urgent fixes that come from the currently active maintenance-branch (merge from 1.0 to 2.0 to trunk).

After another week passed and all testing was done the 2.0 branch gets tagged as 2.0.0 and released, given no major problems arised. The 1.0 maintenance-branch will be abandoned and deleted eventually.

This way we can seperate urgent from non-urgent changes and have relatively pain-free and stable releases.
What you do is pretty much the same but you branch from a tag which when you'r finished you tag again. Thats a bit much :).
Branching from tags is also bad style. branch from branches.


stable branches for release & maintenance

branch policies

It helps the team if you write down the policy for each of your branch-types enabeling them to do more on their own without having a release-guy constantly sitting in their neck and luring over their commits ;)

Our policies could be described this way:

  • trunk:

    • no commits with syntax errors
    • receives merges from maintenance
    • no direct releases from this branch
  • branches/X.X-stable

    • may receive urgent fixes only
    • should be "release-ready" at all times
    • developer MUST merge down his commit from here to any younger stable branch
    • If no younger stable branch is available merge to trunk
  • tags/*

    • No commits here
    • used for deploy

Merging becomes also less of a mind-training once you try to merge into one "direction" only. (You might want to google for the tofu scale but thats getting a bit OT now ).
See that merges are done continuously by developers and not release managers to limit the bottleneck.
While one release is live and actively maintained receiving hotfixes, we allready start to prepare the next, isolating it from possibly unstable changes in the trunk and giving it time to "ripe".

You might have different requirements for the duration of code-incubation and testing or length of release iterations of course. Adapt :)

硬不硬你别怂 2024-10-01 12:35:53

我非常喜欢持续集成和测试驱动开发。

我建议您查看以下一些链接:

I'm a big fan of continuous integration along with test driven development.

Here's some links I'd recommend checking out:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文