CODING 最佳实践:快课网研发效能提升之路

快课企业移动学习平台是上海快微网络科技有限公司自主研发的企业级 SaaS 平台,提供移动学习、考试练习、培训管理、知识分享、统计分析等学习和培训功能,为员工、经销商及客户等全价值链合作伙伴提供全面的知识服务。本文将详细介绍快课网的研发团队是如何使用 CODING 研发管理系统提高研发效能。为什么选择 CODING快课网从创立至今已有 4 年多,作为一个规模比较小的创业团队,我们一直在寻找和尝试各种能提升研发效能的管理方案,这样能够帮助团队节省时间,更加专注于业务。第一步就是上云,我们一开始使用的是阿里云,通过容器化、弹性计算和可视化管理帮助我们节省了不少运维成本。但是仅有这些还不够,要开发还需要搭建很多服务,例如 BUG 跟踪管理、代码版本管理和同步、npm 私服、maven 私服、docker 私服等等。虽然后台团队通过使用 docker 让搭建服务方便了不少,但是我们还不满足。大量的服务为研发团队带来了极高的管理成本。再加上不菲的服务器成本、所使用的开源项目更新较慢等原因导致很多问题短时间内都解决不了,同时很多管理方案还不支持中文。所以我们决定寻找一个集成度比较高的国内的商业平台来帮助我们进行研发流程管理。当时的想法很简单,只要功能齐全,收费能够弹性一些就好。在尝试了很多平台之后,我们最后决定使用 CODING,主要是看中 CODING 的网络连接速度比较快,界面简洁,交互比较友好,功能齐全,反馈处理也非常及时,可以很好地帮我们解决代码托管和 BUG 管理等研发流程问题。我们最开始使用的是 CODING 个人版的团队功能,在 CODING 推出企业版之后我们团队很快迁移到了企业版,相对于个人版来说企业版功能更完善,管理起来也更方便,后续还有持续集成和部署相关功能升级,这些功能正是我们团队所需要的。目前快微团队的整个开发是在 CODING 和阿里云上完成的,CODING 主要用来管理代码、里程碑和持续集成等研发流程。版本规划与任务流程里程碑是我们使用比较多的功能之一。最初,我们使用 CODING 的里程碑来规划版本,比如 1.0 版本对应的里程碑就叫做 1.0,每个任务都是版本中的功能点。后来由于新版本的重构采用了分布式服务化开发,由多个子项目组成。由于各个子项目地版本相对独立导致粒度太细不方便产品的规划,便做了一些调整。目前里程碑主要是用来做长周期的规划,每一个任务都是一个小的项目,由一个或多个人来完成,比如将课件服务 1.1 版本分就单独为一个任务。快课技术团队目前的绩效考核也是基于 CODING 的任务管理和里程碑实现的:由产品发布相关版本的产品说明书,包含原型图和功能点文档部分。创建任务,分派给项目负责人,项目负责人需要评估任务的工作量。工作量给定的有参考标准,将最简单的帐号密码登录接口的工作量定为 1,最小为 1。评估工作量之后进行审核,确定起止时间和奖金。进入开发阶段,开始倒计时。开发完成之后进行验收,由技术审查代码(每次发起合并请求也有审查),产品检查 UI 交互,顺利完成验收则关闭任务,将工作量的值作为绩效值。对于不能按期完成的任务,进行惩罚措施,每逾期一天扣 10% 绩效。对于工作量比较大的任务,可以由一个人主要负责,多人完成,负责人需要为每个人安排详细的工作内容,最终由负责人按贡献比例分配绩效和奖金。这样累计下来,每半年或一年可以根据绩效进行一次评定,给表现好的员工涨薪。分支管理快课目前的分支管理方案与 CODING 文档中的最佳实践比较接近,master 作为主分支只发布正式版本,新增一个 dev 分支作为开发中的分支,并且同时对这两个分支设置保护,禁止直接推送代码到这两个分支上。快课的每个子项目都在项目配置文件里写有明确的版本号,后端 maven 项目写在 pom.xml 中,前端 node 项目写在 package.json 中。开发中的版本号一律带有 SNAPSHOT 后缀,以表示这是快照版本,会不断发生变化,不能在生产环境使用。比如正在开发 1.1 版本,此时 master 分支的版本号是 1.0.0(随着补丁的增加,最后一位也会不断增加,比如版本号有可能为 1.0.9),dev 分支的版本号是 1.1.0-SNAOSHOT。当需要开发一个新版本的时候,首先基于 dev 分支新起一个分支,可以根据实际情况来命名新分支,比如可以叫 dev-v1.1 或者 dev-tom 等等,没有限制。在新分支上完成开发之后,在 CODING 上发起合并请求申请合并到 dev,此时合并请求的标题和内容必须写的详细一些,审核之后进行合并,合并的同时删除原分支,只在 CODING 上保留 master 和 dev 两个分支。最终所有新开发内容都完整合并到 dev 分支后,测试通过,再从 dev 分支新起一个分支,更改版本号为正式版本号,进行推送并新建合并请求,合并到 master 分支上。对于已经上线的版本,如果有 bug 需要修改,则从 master 分支新起分支进行修改,完成后将版本号最后一位 +1,然后推送并新建合并请求合并到 master。持续集成我们团队很有幸获得了 CODING 持续集成功能的内测资格,之前也有尝试过自建 Jenkins 服务,对持续集成有一定积累能很快上手,于是我们便开始转向 CODING,毕竟一站式的 DevOps 工具链服务更方便,可以给研发团队节省很多精力。CODING 对 Jenkins 进行了封装,只需要在项目根目录下创建一个 Jenkinsfile 文件,配置好之后推送上去,推送完成之后在后台开启持续集成即可。持续集成主要用在后端 maven 项目上,来做规范检查(checkstyle 插件)、单元测试和代码质量检查(spotBugs 插件),这样当团队成员在创建合并请求时,管理者可以看一下代码是否规范并跑通了必要的测试,在 CODING 上构建成功后才能继续对修改进行审查。自动化构建为研发提供了很大的便利,避免了一些人为的不稳定因素,也为项目管理者节省了不少时间。目前快课的项目都是直接发布到 docker 私服上的,推送成功之后修改 k8s 中的镜像版本来完成自动部署。我们也期待 CODING 未来会上线的部署管理功能,能支持在目前的构建基础之上自动发布 docker 镜像,然后再自动更新 k8s 相关配置的镜像版本,补充 CI/CD 功能,这样的话就能更好的实现研发流程的自动化了。点击立即体验一站式 DevOps 工具链 ...

February 12, 2019 · 1 min · jiezi

GIT - 代码分支管理模型之二

书接上文在前一篇文章GIT 代码分支管理模型之一中,我们一起了解了一种叫做“成功的代码分支管理模型”。在这种模型中,我们确实可以很灵活地应对各种场景下的代码分支管理。理想总是那么美好,而现实偏偏那么蛋疼!要用好这种代码分支管理模型,需要全体开发人员对于GIT有比较深入的了解,比如merge, rebase,而且在每一次GIT的操作的时候要很清楚地知道自己正在开发的功能属于哪个分支的。对于同时开发多个功能点的同事来说,比如同时在开发一个下一版本的功能,以及进行产品线上细微改动的同事来说,确实要非常小心,稍不留神就容易怼错分支。历史背景在我们公司刚开始推行GIT的时候,领导下的指令是要让大家把精力全放在功能开发上,对于GIT只需要知道pull 跟push就可以了,经过一段历史时期的挣扎磨合,无形中我们形成了下面这种分支管理模型,称之为 “简单但啰嗦的分支管理模型"简单但啰嗦的分支管理模型主心骨这个模型主要有两种分支,一种叫DEV,一种叫REL。每一种后面都附加有对应版本号,比如DEV1.0, REL1.0RELx.0每个版本开始开发之前,都会从上一个版本的REL分支创建出一个新的REL分支,比如REL2.0是从REL1.0创建出来。当然第一个版本REL1.0就是从master分支创建出来的。这样就确保了每一个版本都是从上一个版本最新代码创建出来的。RELx.0神圣职责是作为每一个大版本发布的分支,并且是用来部署测试环境,准产品线以及产品线的分支。一般开发人员没有权限直接往RELx.0上面提交代码,只能从对应的DEV分支提交代码,再由集成人员合并到上面去。DEVx.0DEVx.0是与RELx.0对应的开发分支,所有开发人员默认都有权限往这个分支上提交代码。这也是开发人员所需要知道的分支,只需要从这上面pull最新的代码,然后把本地commit的代码push到上面去就可以了。小版本怎么办?在相当长的一段历史时期中,基本稳定在一个版本一个月左右。但有时会遇到有些小功能着急着上,等不及一个月上一次,所以就有了对应RELx.x以及DEVx.x (x > 0). 比如刚发布了REL3.0,这时有VIP客户需要上一个功能,改动不至于很大,但是也等不及下个月再上,于是我们就从REL3.0上面衍生出一条REL3.1的分支。按照之前的规则, REL分支是不允许直接修改代码的,所有对应的我们会创建DEV3.1的分支,给开发人员在上面进行开发。在这个过程中,下一版本4.0其实一直在同步进行开发的,但是这时REL4.0以及DEV4.0的分支上是没有DEV3.1的新功能的,所有在3.1的新功能上线之后,需要由持续集成人员DEV3.1的代码合并到DEV4.0上面去 (为什么不是直接REL3.1到REL4.0呢? 技术上是可行的,但是这样的话,REL4.0需要反向将代码合并会DEV4.0去,比较别扭),持续集成环境会自动将DEV4.0的新代码合并到REL4.0上面去,这样到时发布4.0的时候,才不会丢失了3.1新增的功能没bug的系统是不完整的有bug怎么办?不管是大版本还是小版本,总有可能产品线上有bug需要hotfix。在上次介绍的成功代码分支模型中,可以通过hotfix的分支进行代码修复。但在这个简单模型中,就不会新建hotfix的分支,而是在最新以上线的分支上进行修改。比如当前产品线上是REL3.0的代码,REL4.0是下一个大版本,REL3.1是准备上线的小版本,而这时产品上客户报了Level 1的case,按照SLA需要在三天内修复,我们是等不及REL3.1下周末上的,更不可能等REL4.0到下个月,所有我们要上到3.0的分支上:已上线的REL3.0以及对应的DEV3.0在上线之后就全被锁掉了,所以这时我们要找代码集成人员进行解锁然后在DEV3.0的分支上进行代码修复,直到测试通过后,合并代码分支到REL3.0进行紧急上线简单但啰嗦简单这种模型中,大部分开发人眼只需要记住版本的DEVx.x就可以了,其它REL什么的都可以不用管,不懂也没关系的。啰嗦每一个新版本开发前,管理人员都要新建对应的DEV分支,然后开发人员checkout对应分支进行开发。这样一来,一个版本,无论大小,都需要对应有两条分支,整个代码库看起来就有很多很多的分支,略显啰嗦。there is no free lunch!利弊关系上面已经做了一些简单的介绍,这种模型适合在项目比较大,团队人数较多的情况下使用,好处是开发人员不需要对GIT有过深的理解,只需会简单的pull / push,其它都由分支管理以及对应的权限管理搞定;其缺点也明显,就是整个代码库会有好多好多的分支,看起来比较啰嗦。

January 25, 2019 · 1 min · jiezi

GIT - 代码分支管理模型之一

就像人心散,队伍不好带一样,代码版本多,分支也不好管当产品开发到一定程度后,多版本同时开发,各种热修复等等问题,势必会带来版本分支管理的问题。今天我们准备一起来看看第一种代码分支管理方案。这里要先强调一下,分支管理的方式各有千秋,不存在谁一定比谁好,只有谁比谁更适合你而已热门的成功代码分支管理这款人们的分支管理方案只要是从这篇叫A Successful Git Branching Model 衍生出来的。很多企业的项目都是采用这种方式来进行管理。下面这张图涵盖了这种方式的各种分支设计:这个模型基本能满足企业项目开发过程中遇到的各种代码版本管理的需求,下面尝试着把这种模型分解给大家讲讲:咬住青山不放松在上面的图中,大家可以看到有两个分支的名字被加粗了:master 和 develop,这两个是分支当中的中流砥柱。#### master这是新建一个GIT repository之后的第一个分支。在这个模型中,master分支代表的是当前产品线上的版本,它的最后一个commit可能是已经上线了,或者已经经过QA/PD/PO 千万次折磨、分分钟可以上线的功能。换句话说,这条分支要做到 随时都可以上线的! 要是谁把一个开发了一般的功能提交到这个版本上去,有可能会被PO拉去祭天的! 所以如果有严格的权限管理的话,一般会把这个分支给锁起来,有且仅有上线的同事才有权限动它!另外master的每次上线都会打一个tag,表明版本号是多少develop一般灵长类动物都敬畏祭天这样的操作,所以我们需要开辟一篇新天地来大有作为。为了和大部队保持一致,develop的分支是基于master创建出来的C:\githome\github\gitdou (master) (gitdou@0.1.0) git branch* masterC:\githome\github\gitdou (master) (gitdou@0.1.0) git checkout -b developSwitched to a new branch ‘develop’C:\githome\github\gitdou (develop) (gitdou@0.1.0) git show-branch -a –no-name* [develop] add httpUtil.js ! [master] add httpUtil.js ! [origin/HEAD] add httpUtil.js ! [origin/master] add httpUtil.js—-最后的git show-branch -a –no-name 命令的输出可以看到develop的分支是基于master创建出来的如果项目不是特别大,版本管理也比较简单,那么master跟develop这两个分支就基本够用了文体两开花当项目稍微大一些的时候,会遇到各种各样的版本管理需求,但不一定每一种你都需要,当需要的时候可以再建立这些分支,比如有features, release, hotfixfeatures第一种情况比较常见,项目有很多同事并行开发,比如分了多模块给多个小组进行开发,如果各个模块都往develop分支上面丢,那么基本没办法做持续集成(Continue Integration)的操作。虽然最后集成的时候各模块一定会和谐相处的,但是在开发过程当中,不一定每一个commit都是向模块兼容,所以最好能每个模块都自行在一个旮旯捣腾,等最好确定能相亲相爱了,大家再杵到一块去。这是我们可以基于模块创建各种feature分支,有关开发人员就在相应的分支上进行开发就行,等到各个功能分支基本完成了,我们再把这些分支merge到develop上面去如果有了feature分支,那么develop分支基本就成了集成分支了release前面说了master分支代表着当前产品线上的版本,分分钟可以上线部署而不会导致祭天这种结局的。但这有些项目或团队有这样的情况,产品上线前要先部署到准产品线上去玩,内测一周左右,确定完全没有问题了再上到产品线上去。在内测的这一周,如果发现了有问题了,赶紧从develop分支进行修复,再上到准产品线来验证。如果我们用master分支来进行准产品线的部署,在内测的这一周发现问题,而这时我们的产品线上有紧急问题要fix,那么我们就无法直接拿master分支上线,这就做不到我们之前的承诺: master分分钟可以上线而不用祭天所以我们可以创建一个release的分支来进行准产品线的部署和问题修复,知道确认完全没有问题了,我们再同步到master分支去上线hotfix做系统的哪可能没有bug!当产品线上无辜出现bug的时候,我们要去哪个分支做修复呢?master :显然不合适,产品线上由于设计或者考虑不周出现bug一般是不用祭天的,但如果因为这样,在master上面一通乱改,那就有可能要祭天了release:这个是给下一个版本用的呢。如果是上一个版本的话,那新增的修改就破坏了原来版本号的意义了,比如原来分支叫release-1.0.1, 那么加了这个版本还叫这个名字吗?developer: 如果还有一些其它正在开发的功能,那一会上线的时候就会连带这个也稍上去了!feature: 这就有点扯远了看来上面这4种分支都不大合适,那就来款新的,就叫hotfix. hotfix分支是从master分支直接创建出来的,用来做一些产品线上紧急的代码修复,或者临时添加的小功能。开发人员直接在这个分支上进行开发,功能完成后直接上到master分支再上线。记得每次hotfix上线后,要把功能同步回developer,再到各feature的分支上以上就是关于 这款 成功的代码分支管理模型的讲解,基本上能满足大部分企业大部分项目的代码版本管理的需求! 后面会介绍另外一块代码分支管理模型,是指我们公司的一种管理的方式,下回见!

January 18, 2019 · 1 min · jiezi

Git 系列文章

GIT 初识Git的基础操作Git的远程操作Git的分支管理Git标签操作Git团队协作Git 多账户管理Git的相关配置Git的子模块

September 26, 2018 · 1 min · jiezi