CakeDC(cakephp company)Git workflow--适合于较大团队大型项目开发
CakeDC Git workflow是一个项目开发和版本发布的工作流,在这个工作流程中开发和版本发布周期是基于几个关键阶段(key phases):
- Development:
所有活跃的开发活动都由里程碑驱动,在这个阶段的产出是很不稳定的代码基线
- QA:
Quality assurance testing作为一开发周期的一部分,主要协助确保需求的满足性和质量的可接受性
- Review
客户或者评审员面对的是一个稳定的代码基线,该基线已经经过了QA流程,质量上已经被QA人员认可
- Release
发布版本在QA和review评审流程都顺利完成之后的产物。
cakeDC所使用的workflow设计是基于vincent driessen的gitflow推荐,虽然他们有一些相似性,但是也有部分的裁剪和修改,可能更加适合于较大型团队,有正式流程的项目开发
Organization:
本workflow设计的主要思想是它能适合于集成一个QA流程作为他们开发流程一部分的团队或公司,同时给客户提供一个稳定的stage server来review和approve the pending release。然而,如果你没有QA流程,或者不提供stage server for customer review/approve,这些步骤也可以轻易地被忽略。
贯穿各个phase我们项目的整个开发和发布被划分为几个不同阶段的目标,我们称之为milestones。一个milestone本身并不等同于一个release.一个项目的一个版本可以由多个milestone构成,这依赖于项目的计划和资源状况。
这些phases由"permanent永久"和"temporary临时"的分支来代表,通过这些phase,推进我们的开发流程向一个release的正确方向迈进。需要一个持续性的分支的原因是为了准备各种部署需求,允许每一个人在项目开发不同阶段产品的状态有一个清晰地认识。这两种分支包含下面的git branches,而这将形成我们的work flow的一部分。
Permanent braches:
1.develop
也被称为bleeding edge(前沿),这个分支包含为当前milestone准备的已经结束的features。这是一个alpha状态的代码基线,往往被认为是非常不稳定的。
2.qa
所有为了一个milestone而做的开发活动最终在这个分支上来做验证和测试。这是一个beta阶段的代码基线,也被认为是不稳定的。
3.stage
一旦为了一个milestone做的开发工作通过了QA测试,那么就可以用这个分支来host stable code base for review.
4.master
如果上述stage分支的代码由客户或者评审人员approval了,那么stage分支的代码就merge到master,而这个master分支将在生产环境保留项目的当前稳定版本。
Temporary branches:
1.feature
这些分支是从develop分支上创建出来,目的是为了隔离一个特定任务的开发工作。feature本身的定义往往很大程度上与管理风格有关,比如milestone是一个长的或短的sprints。
2.issue
这些分支从qa分支上创建,目的是为了解决完整测试一个milestone的软件的QA阶段报出的问题
3.hot-fix
这些分支是由生产环境中报出的紧急问题而触发的。最好的情况下,这些分支将永远不会创建,因为我们经过QA流程,质量得到了很好的保证
“永久”和“临时”的分支的重要区别是:对于permanent分支,永远不会在这个分支上直接修改代码commit代码,永久分支上永远是通过merge临时分支而得到相关代码的。完整的流程如下:
在下面的章节中,开发和版本发布的各个阶段phases将会分别描述,详细讲解各个流程
Development:
在一个milestone的实际开发活动中,开发人员将从develop分支创建feature branch
这些分支命名为"feature/xxx"。xxx通常对应着项目管理系统中的一个ticket,比如
$ git checkout -b feature/1234 develop $ git push -u origin feature/1234
通过将开发任务隔离到一个独立的分支上,开发人员能够有效避免destablize develop分支,以免影响他人的工作。而且,如果有些feature是基于其他的feature,那么这个feature分支可以被其他已经commit到develop分支的feature做updated(rebase)
如果你和其他的开发人员在做同一个feature,那么你可以checkout他们的分支,并且协同工作。
$ git checkout -t origin/feature/1234
当一个feature开发结束,它将被merge back to develop分支,feature分支本身可以被删除了。
$ git checkout develop $ git merge --no-ff feature/1234 $ git branch -d feature/1234 $ git push origin :feature/1234
develop分支本身本认为是不稳定的,所以最好开发人员能有一个部署这个branch的服务器,这样他们能够轻易地修改项目的bleeding edge version of the project,辅助讨论或者提供一个review当前进展的方式。这也帮助那些对开发流程不是非常清晰地项目经理获取到将要到来的milestone的真实状态。
Testing:
当一个milestone被认为完成时,develop分支将被merge到qa分支,QA流程启动:
非常重要一点:当develop分支被merge到qa分支时,所有的新features将构成了下一个milestone.这就允许对当前milestone的测试和对下一个milestone的开发工作完全并行化了。另外,由于QA流程是在一个专用的branch上进行的,这就允许测试阶段可以在不影响继续开发的前提下来做规划和执行。
$ git checkout qa
$ git merge --no-ff develop
在测试阶段,QA可能发现这个milestone的一些issues,也就是说有些feature是fail掉的。当这种事情发生时,为了解决这些bug我们将要从qa分支上来创建issue分支。这些分支被命名为"issue/xxxx",xxxx代表了你的项目管理或者bug tracking系统中的一个id,比如:
$ git checkout -b issue/1234 qa $ git push -u origin issue/1234
当这个issue branch存续期间,如果这个问题本身依赖于另外一个issue的结束,那么这个issue branch本身也可以被其他已经被commit到qa分支上的其他issue的commit来做updated/rebased。当问题解决了,merge到qa分支,然后这个issue分支就被删除了
$ git checkout qa $ git merge --no-ff issue/1234 $ git branch -d issue/1234 $ git push origin :issue/1234
在QA阶段,一个专用的测试服务器应该是必须的。这个服务器部署qa分支的代码,专门用于QA团队来做测试使用。
Review:
一旦一个milestone贯穿了实际的开发活动,并且完成了QA流程,新的功能现在就可以放到stage分支上做review了。
在这里qa分支将被merge到stage分支上,同时qa分支也需要merge到develop分支上去,以便为将来的milestone来使用:
$ git checkout develop $ git merge --no-ff qa $ git checkout stage $ git merge --no-ff qa
而且,为了标示milestone的结束,应该从stage分支上打一个tag,这些tag被命名为"milestone/xxxx" xxxx是一个milestone id,通常就是一个序数。
$ git tag -a milestone/1
stage分支现在可以部署到一个staging server上去了,可以邀请客户或者评审人员来review和评审。如果任何问题被发现或者新的功能在这个时间被要求,那么他们就将成为在develop分支上的当前active milestone的开发任务,或者可以计划到将来的开发任务中去。
在qa或者stage分支上,不允许直接修改commit,只允许通过feature分支merge到develop分支,随后通过QA流程。尊重这个流程非常重要,然而可能很多组织就直接在stage分支上打patch了,因为这将破坏QA流程。
Release:
当stage分支通过了review,在完成一个或多个milestone之后,一个release可以被创建了。这将是更新生产服务器代码的时
机了。
为了创建release,stage分支需要merge到master,另外,为了创建一个release,一个tag需要再master分支上打上。这些tags命名为"release/xxx" xxx为version number。
$ git checkout master $ git merge --no-ff stage $ git tag -a release/1.1.0
所有在本release之后从qa merge到stage的代码都构成了下一个版本的应用。
Hot Fixes:
在生产环境中,有时可能会发现一些重大问题,而用户又不能等到下一个release来解决,这时就需要用到hotfix了。
在这种情况下,一个hot-fix分支需要从master分支上创建,这些分支被命名为“hot-fix/xxx"xxx为bugid:
$ git checkout -b hot-fix/1234 master $ git push -u origin hot-fix/1234
依赖于QA的需求,可能需要再问题解决后,就在hot-fix分支上来做验证。有3中方法:
1.Kamakazee: 这里hot-fix分支被merge到master分支,QA直接在生产环境中测试。这是不好的方式,因为数据的不一致性可能导致问题
2.Copycat:这里hot-fix被merge到master,而master分支本身被staged到一个专用的服务器。如果生产环境是基于pushes to the repository or a scheduled build来自动部署的,那么
这就可能是不可能的。
3.Paranoid:这里hotfix分支staged on a dedicated server,QA必须评审测试,之后才能merge到master。那个staged server有可能需要replicate the data used in the production environment。但是如果由于法律问题或者数据私密问题,也可能不可行。那么一个可选项就是直接stage on the production itself.
一旦patch本身成功了,the hot-fix分支必须merge到stage,qa,develop分支上去。
$ git checkout master $ git merge --no-ff hot-fix/1234 $ git checkout stage $ git merge --no-ff hot-fix/1234 $ git checkout qa $ git merge --no-ff hot-fix/1234 $ git checkout develop $ git merge --no-ff hot-fix/1234
However, depending on the length of the milestones, it's possible that sufficient changes have been made in the pending release that the problem found in production has already been rectified, or the functionality surrounding the issue has been modified to a point where the problem no longer exists, or has been altered completely.
Finally, once the hot-fix has been applied to all the relevant branches it can now be removed.
$ git branch -d hot-fix/1234 $ git push origin :hot-fix/1234
If you find that there are numerous bugs in your production environment this can be attributed to insufficient details at the requirements stage of the project, or an inefficient QA process. Keep in mind that the QA process is only as good as the initial criteria, so validating the specification for a project is key to it's success.
It's also worth noting that any developer who creates a "temporary" branch should remain responsible for it, as they are the most likely candidates to know the status of the branch.