以SVN+RMS为核心的发布系统,对前端开发的影响上来看,存在如下问题:
- 覆盖式的发布,容易致使线上问题。 js一旦发布,就有可能被任意其余页面使用。被引用的越多,就越重要。一旦核心js出现故障,影响面巨大。
- 发布的基本粒度过于细节,基本发布单位是文件。相对后端每次发布整个应用,文件粒度的发布体现出对应用复杂度缺少深刻理解。
- 手工挑选文件发布,容易发生人为错误。SVN+RMS的模式使得前端开发在各类GUI工具间切换,使得发布环节效率低下。在前端工具逐渐命令行,一键式,自动化,集成编辑器的大趋势下,愈发显得效率低下和对前端开发者不友好。
- 在发布与版本管理系统深度耦合的状况下,使用中心式版本系统的SVN无力高效的支持分支开发、主线发布的开发/上线模式。在版本控制领域,SVN合并分支效率低、有瑕疵的分支合并算法、基于文件而非仓库的版本管理,容易引入Bug,已是一个过期工具。
以上问题在项目交接的场景中会更加容易犯错,如下是一个案例:
开发者甲实现特性1修改了A文件而且提交到SVN。于此同时,开发者乙为了实现特性2同时修改了A、B两个文件,也提交到了SVN。因为工做安排变化,甲交接特性1给开发者丙,开发者丙从SVN更新整个应用代码,在本地继续特性1的bug修改(在不知道特性2其实也被加入进来的状况下)。上线时,开发者丙在RMS中,观察到文件B可能也须要被发布的状况下,因为被告知特性1仅与文件A有关,为了最小影响,选择只发布文件A上线。因为文件A依赖文件B,上线后出现故障。
固然,若是使用了svn分支,这个问题也能避免。问题是,svn分支很厚重。前端
改进目标:
- 让前端Assets发布过程更加安全、高效、工程化。在解决全部现状问题的基础上,发布体系还应可以达成如下目标:
- 一旦发布出现问题,前端可以快速回滚
- 流畅的支持beta,灰度发布( 比目前更容易的)
- 简化发布步骤,减小犯错的环节
核心机制
一、非覆盖发布
发布的Assets永远不会覆盖线上代码。基于这个机制,给每次发布的文件/模块/应用一个版本号/时间戳,保证文件名不与线上重名。一方面,前端代码有由于其容易被引用的特色,实际上已成为一种“一旦发布即永远存在”的服务。另外一方面,这样作还可以带来如下好处:git
- 不覆盖线上文件,不会影响未知的引用模块/页面。
- 再也不须要预发环境验证,简化产品发布流程,减小工做量的同时减小犯错。
- 不用担忧误发布。由于前端老是先发布。这样发布后还有一次机会作“真正的线上测试”。
- 发布工程而非文件。发布粒度从文件转换到项目。前端针对产品总体发布,每次发布都是一个项目的某个总体状态。直接效果是规避掉全部漏发js文件。其深远意义更在于,为前端提供一个工程化思考的底层环境。
二、自动化
解决此方案给前端开发效率带来的问题算法
- 静态资源引用[^1]的路径变动。静态资源引用的/文件名将会携带版本/时间戳信息,一旦产生一次发布,大量的引用路径变化会引入不少手工劳动。
- 动态资源引用[^2]的路径变动。模块加载路径也会携带版本/时间戳信息。在发布时修改大量动态资源引用路径的会引入不少手工劳动,增长引入错误的几率。
这样前端须要一套调试、构建工具,灵活高效的处理在联调、测试、预发、发布、紧急Bugfix等各类场景下,对站点、项目、模块、组件的发布问题。windows
三、从SVN转移到GIT
这是一个有助于全面提高效率的转变。后端
- 首先这种转变对于解决问题1所提到的误发布有帮助;
- 其次对于问题2的分支/主干式的发布方式有自然的良好适应性;
- 最后,GIT的运行包提供了一个很是强大的命令行环境,
对于问题3所提到的效率困境也有很大帮助。安全
SVN的版本粒度是文件级,GIT的版本粒度是仓库级。GIT认为,版本管理的最小单位应该在仓库,项目在某个时刻的全部文件构成的“快照”体现了一个真正“版本”,所以,每一个“版本”都应该保证本身是可工做的最小特性集合。这是GIT与SVN在版本管理哲学上的本质区别。这个重要的特性使得前面提到的项目交接的案例可以得以解决。服务器
GIT中,分支操做成本极低,仅仅体现为一个本地文件指针更改。高效强大的分支特性使得合并分支,和基于分支的开发成为一件愉悦的事情。在SVN中每当启动一个分支时都当心翼翼相比,GIT能够随时随意的开启、合并分支。架构
在windows平台下GIT提供了全套命令行环境有助于提高前端的工具化程度,提升前端开发者为本身制造工具的可能性。前端构建
解决方案
- 代码直接经过GitLab发布。经过GitLab发布的内容,在SVN将不可见。
- 将不影响在SVN维护的老代码,新项目启动逐步经过 GitLab作版本管理,慢慢废弃SVN。
- GitLab上,按照各前端团队的需求为各团队创建本身的Group。一个团队能够有多个 Group[^4]。Group是受控的,由SCM团队统一管理。须要发布的Git仓库放在团队Group下。
- 每一个须要发布的Git仓库须要在GitLab配置中中指定一个该仓库的发布路径,鼓励将demo和Assets放到同一个库中维护。发布时只发布构建目录。 开发时候对开发人员友好,上线后对线上环境友好。基于此思想,前端代码必然会存在两种型式,将来前端构建会愈来愈流行。
- 在SCM的视角,从新理解“应用垂直化”的含义。前端代码有本身的仓库,构建后的ASSETS和模板成为对应用的输出,在应用的仓库中有一个路径存放或者前端代码干脆拆分出来。
发布路径
非覆盖发布
Git仓库的内容发布路径按照http://a.tbcdn.cn/g/[Group]/[Git仓库]/[Tag]/[发布路径]的规则发布。其中“发布路径”是一个Gitlab新增配置项。编辑器
覆盖发布
提供简单发布接口,不增长时间戳(Git Tag)路径,直接将组件发布到对应路径。这样作的缘由是组件级开发,其发布路径也是对外接口的一部分,须要组件开发者彻底掌握其最终发布路径。
发布路径为:http://a.tbcdn.cn/g/[Group]/[Git仓库]/[发布路径]
发布路径跟Git强行约定而非配置的缘由以下:
在团队内基于约定大于配置的思路,可以提升效率。
经过GitLab的自然检查重复仓库的机制,保证仓库发布不会覆盖线上路径。
工做流
- Git仓库中master分支没有权限直接push。全部的开发都在daily分支上进行。daily分支的命名为daily/x.y.z,其中x.y.z是以数字或者点符号组成的字符串,用来标记版本,如1.2.1 、20130401。
- 每当开始一个项目,本地启动一个**daily/x.y.z**分支,在本地分支上进行开发。
- 本地分支开发完成,须要发布到平常环境测试或者联调时,推送 dayly/x.y.z分支到gitlab。gitlab将经过hook将代码实时发布至平常环境。
- 联调完成,经过测试,须要最终发布上线时,给 daily/x.y.z分支打标签(又叫作tag或者里程碑) publish/x.y.z。推送该标签到gitlab服务器,作一系列检查后,最后部署文件到CDN。一旦一个daily分支被发布。服务端将删除远程daily分支,而且拒绝再次被推送此版本号。这样作的目的是保证版本号不会重复发布。
- 修改线上Bug时,须要从新拉出daily分支,而且以新的版本号发布。
影响分析
新发布方案与现有方案最大的不一样有两点。
- 时间戳由发布系统强制增长。时间戳致使的Assets路径变动引入更多的工做量。各团队须要一个本身的构建系统或者其余方案妥善解决这个问题。
- 须要转变项目组织思路。目前的发布是单个文件粒度,能够选择发布单个文件。转变到新方案后,发布的最小粒度是项目,一次发布即发布整个仓库(和Git的版本管理思路一脉相承的)。采用新方案后,应该更加细粒度,扁平化的组织仓库结构,将真正高内聚的一些页面和组件组织到一个项目中,对项目架构有必定要求。
- 新方案基于整个仓库的发布、以及上线后还有一次机会作真正的线上测试,这些机制可以比较好的解决本文最初提到的极端案例。