通过脚手架发布

我们需要先设计出脚手架发布的整体流程,在后续开发的时候才能更加得心应手。

整体流程

脚手架发布.png

git flow流程图

单人开发流程

git flow流程.png
首先通过远程master分支clone项目到本地master分支,保证本地master分支和远程master分支同步,在本地创建Feature/Hotfix分支进行开发,比如需求v0.0.1,v0.0.2等等,把功能开发完成后,把本地代码Merge到远程Develop分支等待测试人员测试,如果是测试不通过,就在本地原有代码上进行修改,修改完成后继续Merge到Develop分支让测试人员测试,如果测试通过就Merge到远程master分支,同时把代码更新到本地master分支,最后打Tag值发布到release分支之后删除本地Feature/Hotfix中的v0.0.1等需求的分支和线上Develop v0.0.1分支。

多人协作开发流程

git flow多人开发.png
相比于单人开发,多人协作开发就比较麻烦,首先就要确定远程Develop分支,从master分支拉去多个开发分支,比如v0.0.1,v0.0.2等等。假设A,B同学开发的是v0.0.1分支,C同学开发的是v0.0.2分支,A和B去拉取v0.0.1,C拉取v0.0.2。现在假设A开发的v0.0.1功能现在需要提测,那么他提交到Develop v0.0.1上面,如果提测有问题同单人开发那块一样的流程。相对于B而言,A已经提交了一次了,那么B要提测需要先Pull Develop v0.0.1代码到本地,然后提交代码到Develop v0.0.1,同理A在提交代码的时候也要去Pull代码;测试如果说都通过了,那么推送到master分支,打上Tag到release分支,删除Develop v0.0.1分支,同步代码到本地(这块流程和之前单人流程一样)。对于C,假设他提交代码的时候v0.0.1需求已经上线了,需要把远程master分支拉去到本地,然后提交,后续操作都是一样的。

发布流程的具体逻辑

git flow自动化流程.png

  • prepare阶段

就是对git仓库的一个准备阶段,在后续init和todo阶段一旦涉及到远程仓库相关的内容的时候,我们直接就处于一个ready状态。首先检查用户主目录(保证后续缓存的时候都能找到对应的目录)和缓存目录。读取.git_server文件进行判断,一旦读取到文件表示我们明白或者了解当前程序需要将远程仓库存在哪一个远程平台(github,gitee),创建GitServer对象,目的是为了确认我们git平台相关的所有操作包括远程Api,我们全部聚合到GitServer里面;如果没有读取到那说明首次进入,我们需要让用户自己选择托管平台,选择完成后,也是需要创建GitServer对象。第二步就需要拿到远程平台的token,拿到token后才能调用Api;读取.git_token文件,如果token不存在,我们就要引导用户去生成token,如果读取到了token,就需要在GitServer对象里面设置token;根据token拿到用户信息和组织信息,确认仓库到底是个人仓库还是组织仓库;读取.git_own(决定仓库类型)和.git_login(确定是哪个组织,如果是个人仓库,那么就是用户名是什么,),如果没有读取到就选择git仓库类型(个人、组织),然后选择个人(就是当前这个用户)或组织(选择是那个组织),创建远程仓库,创建.gitignore文件(有些仓库是没有创建的,在这创建了避免一些不必要的麻烦)。

  • init阶段

都是对本地git操作的一些处理。首先在本地init之前我们需要确认一点生成Git Remote地址,然后判断这个地址是否存在,存在执行git init操作添加git操作,然后执行git add remote,相当于把刚刚生成的Git Remote添加到当前本地git仓库中,方便后续push操作;下一步执行检查代码冲突,只有当没有代码冲突的时候我们去执行git add & git commit初始化操作,操作完成后去拉去远程master分支,确保和远程master分支是同步的。

  • todo阶段

分为两个过程,第一个过程为代码提交过程(commit),第二个过程为云构建云发布功能。

  • commit过程

在commit的时候,首先需要生成版本号(major大版本,minor小版本,patch),生成完版本号之后需要检查stash区看看还有没有缓存的代码在本地,紧接着检查代码冲突,当代码没有冲突之后我们提交未提交的代码(这里在提交未提交的代码是因为init阶段是初始化的时候才走的流程,如果说init阶段的流程的信息都已经存在了就会直接跳过这个阶段进行后续流程,因此这里需要提交一下未提交的代码);下一步是比较关键的一步,切换master分支,然后自动合并远程master和开发分支(保证每次代码和远程是同步的),当这些动作都完成了之后,就可以推送分支到远程开发分支。

  • CloudBuild和CloudPublish

在这个过程的时候我们需要做发布前的检查,读取.git_publish缓存文件,用途是用来标识我们发布所选取的静态资源平台,因为有可能我们选取OSS,也可能选择自己搭建的平台,为了后续可拓展,用.git_publish文件,那么通过这个文件就可以标识出当前发布的平台;如果没有.git_publish文件,我们需要用户去选择静态资源平台,如果已经确认过了之后或者有缓存文件我们就生成静态资源平台,然后进行云构建和云发布,完成之后我们还需要做一步操作,就是由于我们在做history路由模式的时候我们需要把我们的模板文件index.html文件上传到我们另一个静态资源文件,对于hash和history两种模式我们需要做两种处理方式。

  1. - 云构建+云发布

生成CloudBuild对象,通过这个对象调用我们远程的websocket服务,同时完成云构建等等这些功能,包括和远程的一些交互;然后进入prepare阶段,做一些基础的判断;下一步进入init阶段,创建websocket通信,对建立websocket的过程中可能出现的一些问题进行判断;下一步进入build阶段;下一步判断是否构建成功,成功以后我们进行云发布;

     - prepare阶段

我们需要根据之前选择的静态资源平台获取测试或正式资源文件,查看资源文件是否存在,存在就询问用户是否覆盖发布,是就进入init阶段,否则终止发布;

     - init阶段

创建WeSocket通信,建立后需要进行一些列判断,例如timeout、connect、disconnect、error;在connect过程中我们回去打印websocket传递过来的消息,因为运行服务端向脚手架发送一些消息,如果客户端接受到消息就需要把它打印出来,如果你没有处理打印逻辑,那么服务端发送的消息,客户端是没有办法感知的;disconnect、error一旦碰到这种错误的时候,如果服务端没有中断的时候,我们需要在客户端手动中断websocket链接;timeout通过一个定时任务去触发,判断当前链接是否超时,因为服务端可能因为各种原因迟迟没有响应,我们需要在客户端实时去监听当前是否超时,如果说出现超时了,就需要手动断开链接,释放系统资源。

     - build阶段

客户端脚手架向服务端发送一个build命令,这是双方约定的一个命令,服务端通过websocket接收了指令之后去执行命令,同时我们需要在远程去自定义三个事件,第一个事件是timeout超时事件;第个二事件是build事件,build事件表示整个构建是完成了;第三个事件是building事件,表示我们当前正在进行构建。如果说超时了,那么就需要去中断websocket链接;如果没有中断,在build和building过程中需要打印websocket消息,同时我们判断如果当前是build过程,我们就进入最后的云发布过程

  • finish阶段

首先创建Tag并推送至远程Tag,紧接着我们需要将本地代码切换master分支,将开发分支代码合并到master分支,将代码推送到远程master分支,完成之后删除本地开发分支和远程开发分支。