为什么要实现自动部署

小程序开发迭代里,有以下几个个头痛的问题,

  • 如何准确并快速的的把小程序上传去后台,并让测试人员进行测试?
  • 测试同事找开发要二维码,效率较低
  • 本地生成的二维码会出现携带本地代码、未及时拉取分支其他改动等问题
  • 小程序的体验发布太依赖开发者,通常只有开发者熟悉微信开发者工具一系列的上传流程,而每次发布的是有页可能因为忘记合并分支,忘记开启构建命令导致一些列不可知的错误,从而导致影响开发进度、发布流程不可控等一系列问题。

针对这些问题我们需要一套可以随时从Git上拉取最新代码选取分支和tag并自动打包构建不同环境上传至小程序后台的系统来解决以上问题。

如何实现?

开发者工具提供了命令行与 HTTP 服务两种接口供外部调用,开发者可以通过命令行或 HTTP 请求指示工具进行登录、预览、上传等操作。

传送门:
"developers.weixin.qq.com/miniprogram…"

方案

通过命令行与 HTTP 服务可以想到一下几种思路

  • 通过老牌持续集成工具Jenkins配置shell脚本调用命令行上传部署
  • 通过配置GitLab CI在项目内添加.yml编写CI文件调用命令行上传部署
  • 通过Node调用Http服务配合Gitlab-Api+shell命令为前端提供调用接口,前端调用接口实现自动编译上传部署

本文将针对第三种思路详细阐述实现一个自动化部署系统的步骤和实现过程中的思考。

为什么我不用第一种和第二种?一是因为搞这种现成的配置式的东西弄出来没什么成就感,用第三个思路写顺便可以练练Node,二是因为虽然思路有了,但配置还没玩明白,等我研究明白了再单独写吧。emmmm.....

需要用到的知识点(知识点不会的童鞋先去补课)

  • NodeJS
  • Gulp
  • Git命令
  • GitLab-Api或Github-Api(本文全部使用gitlab-api)
  • Vue+Scss+layui+Html实现前端页面功能

传统流程

你正在认真coding,和某个bug激烈战斗,已经有了头绪正准备一气呵成干掉它。突然被别人打断并告诉你需要为他提供一个测试环境的二维码...

为了这个二维码你做了以下事情


忙活完之后你将分支切换回来,不断回想刚才的思路,脑子里一万个那啥狂奔,但如果直接反手丢给他一个发布系统链接地址,那么他只要按照以下步骤点点点就可以轻易的搞定这件事而不用来冒着被砍的风险来找你:

  1. 输入git地址和小程序开发工具端口地址(配置一次即可)
  2. 选择需要发布的对应分支
  3. 选择构建环境打包
  4. 上传至小程序后台
  5. 登录小程序后台设置体验版获取二维码
  6. 搞定收工,全程无需发布人员操作任何代码相关,只要会点下一步,有发布权限即可

开发过程

流程图

后端功能实现

  • 环境依赖
  • 实现上传小程序后台接口;
  • 实现拉取git项目到本地的接口;
  • 实现获取gitlab项目信息,分支及tag的接口;
  • 实现切换分支及tag接口
  • 实现项目编译打包的接口;
  • 实现拉起开发者工具的接口;

环境依赖

在后端功能的实现上用了以下框架和模块

  • express (node框架)
  • request(网络请求模块)
  • fs (文件处理模块)
  • log4js (输出log日志)
  • process(子进程模块,用来在node中执行shell命令)

1. 拉起开发者工具的接口

mac系统上开发者工具会默认的安装路径是/Applications/wechatwebdevtools.app
通过process模块执行shell命令open /Applications/wechatwebdevtools.app即可打开开发者工具。

2. 实现上传小程序后台接口

上传接口是这个系统的核心,虽然很简单但要实现这个接口还是需要你对小程序工具的http调用有一定了解,接下来详细说一下如何完成此功能:

上文说到小程序开发者工具提供了命令行与 HTTP 服务两种接口供外部调用,开发者可以通过命令行或 HTTP 请求指示工具进行登录、预览、上传等操作。

第一步(开启http服务)

打开你的开发者工具 设置——>安全设置——>服务端口,因为调用开发者工具提供的http服务一定要拼接本地的端口号,所以后续所有的操作都是要基于开发者工具开启且服务端口开启的状态下进行操作的,默认情况下服务端口是关闭的,http 服务在工具启动后自动开启,HTTP 服务端口号在用户目录下记录,可通过检查用户目录、检查用户目录下是否有端口文件及尝试连接来判断工具是否安装。


第二步(如何拿到开发者工具端口号)

在确保你的开发者工具服务端口开启的情况下,我们可以尝试通过node的fs模块去读取储存的文件信息读取端口号,端口号文件是开发者工具自动生成的,所以它的位置是固定的,但不同系统中的默认位置也不相同。

端口号文件位置:

macOS : ~/Library/Application Support/微信web开发者工具/Default/.ide

微信web开发者工具/User Data/Default/.ide

注意!!!

像是在mac中直接去读取这个默认路径是获取不到的,因为mac中一般会将工具安装在你的当前账户文件夹下,所以如果发现无法读取的情况可以到Uers的文件夹找找看。
比如我的mac上要想访问端口文件完整路径是这样的:

const portPath = '../../Users/admin/Library/Application\ Support/微信web开发者工具/Default/.ide';

读取端口的功能封装,后续会用到

第三步(上传)

接口定义:

  • URL:/upload
  • HTTP 方法:GET

通过调用获取端口号的方法,请求上传接口拼接端口,指定项目上传目录,就是编译出来的dist文件夹目录,将接收的描述和版本号一并拼接发送上传请求即可。


get请求封装

3. 实现拉取git项目到本地的接口

这个接口的实现主要是通过Node接收项目地址然后执行git clone的shell命令实现,
需要用到Node的child_process子进程模块用来执行shell脚本。

代码实现

4. 实现获取gitlab项目信息,分支及tag的接口

Gitlab有一个非常强大的API系统,几乎所有的功能都有相应的API接口,为了使用API,需要从Gitlab中获取私有token。

  1. 登陆你的Gitlab
  2. 点击登陆的帐户,点击settings
  3. 点击Access Tokens
  4. 根据自己的需要创建适合需要的Tokens

成功拿到token之后只需在请求的时候作为query参数传递即可:

项目分支信息API api/v3/projects/ [projectId] /repository/branches

小程序项目tagaAPI api/v3/projects/ [projectId] /repository/tags

5.实现切换分支及tag接口

分支和tag接口实现的思路是一样的,接到前端请求后执行各种git命令完成

  • 切换至项目目录下 cd ./project
  • git branch 拿到本地分支信息
  • 切换分支时通过接收的分支名称比对本地是否存在分支,如分支已存在就删除再切换,不存在就直接切换
  • 通过log4js输出日志,为了页面展示用

代码实现

示例为分支切换的相关代码,tag实现的思路是一样的,只不过要把相关git命令替换即可。


6. 实现项目编译打包的接口

这里需要注意一下,这个接口的实现是非常灵活的,需要根据你当前项目的编译文件进行配置,比如我的项目开发时使用gulp打包编译环境到dist,其编译命令分别为:

  • gulp build:Dev(联调环境)
  • gulp build:Test(测试环境)
  • gulp build:Slave(预发布环境)
  • gulp build:Prod(线上环境)

那么同理,配置好dist输出文件目录,收到请求后执行事先实现好的shell命令即可完成打包这一步,如果你不太了解环境编译打包这块内容,可以参考我上一篇文章"《武装你的小程序——开发流程指南》";

代码实现


目前为止我们已经实现了六个后端功能,并生成了对应路由,分别为:

  • /open 实现拉起开发者工具的接口;
  • /up 上传小程序后台接口;
  • /clone 拉取git项目到本地的接口;
  • /checkoutBranch || /checkoutTag 获取gitlab项目信息,分支及tag的接口;
  • /branches || /tags 获取gitlab项目信息,分支及tag的接口;
  • /branches 项目编译打包的接口;

前端实现

前端页面我就不提供示例代码了,ui框架和开发框架根据大家的喜好决定,因为有了上面这些接口我们就已经可以愉快的对前端页面进行你需要的一些定制了,这个时候需要我们考虑的就是一些前端的交互逻辑了,如何利用好这些接口将起串起来组成条完整的流程,如何利用gitlab的其他api扩展你需要的其他功能,比如加一个提交记录页面...

前面的流程图已经大致画出了我的思路,下面我将我的前端实现思路详细描述一下,供大家参考:

  1. 实现一个启动页面,页面可以输入git地址和本地的端口路径,点击开始按钮调用/clone接口将代码拉取到项目中,同时将端口号路径储存起来后面用。
  2. clone接口返回成功后调用/open接口拉起开发者工具
  3. 实现一个主页面,初始化页面调用/branchs/tag接口获取分支和tag信息,将其展示在页面上。
  4. 点击切换分支获取当前选取的分支名,调用/checkoutBranch 或 /checkoutTag接口传递分支名,后端调用相应的git命令。
  5. 切换分支完成后进入选择环境页,添加描述和版本号选择需要发布的环境,调用/build接口传递环境变量进行构建。
  6. 构建完成显示下一步,调用/up接口传递版本号和描述发送上传请求,上传成功页面将描述,提交人,时间,环境等必要信息展示出来。
  7. 去微信公众平台设置体验版
  8. 完成

END

到这里一个简单的小程序发布系统就完成了,本文只是记录了我的一个开发思路希望能对大家有所启发,有很多地方考虑的还是不够完善但基本能用了,大家可以发散思维实现一个自己的发布系统,也欢迎交流想法和指正我的错误,同时欢迎大家关注公众号前端小苑,我会定期在这里发表原创文章。

作者:李初五
链接:https://juejin.im/post/5c937bbcf265da6119043f4c
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Node+GitLab实现小程序CI系统的更多相关文章

  1. 生鲜配送管理系统_升鲜宝 V2.0 小程序辅助系统工具矩阵系列相关说明

    随着微信红利的进一步释放,使用人群的不断增加,小程序从2017年01月第一批开发者出现后,2018年小程序得到快速的提升,小程序开发的相关应用小工具得到了市场的青咪,社会化大分工.协同.共享.协作的思 ...

  2. 微信小程序答题系统实现随机出题 答题小程序如何实现随机出题 微信小程序 答题系统

    最近头脑王者非常火爆,公司也在开发类似头脑王者的答题系统,这个重任交到我这边来了,我们在开发的这个微信小程序答题系统,需要实现随机出题.尤其是一些比如闯关的环节,需要随机从题库里抽取若干道题目,给到用 ...

  3. Python flask构建微信小程序订餐系统

    第1章 <Python Flask构建微信小程序订餐系统>课程简介 本章内容会带领大家通览整体架构,功能模块,及学习建议.让大家在一个清晰的开发思路下,进行后续的学习.同时领着大家登陆ht ...

  4. Python flask构建微信小程序订餐系统☝☝☝

    Python flask构建微信小程序订餐系统☝☝☝ 一.Flask MVC框架结构 1.1实际项目结构 1.2application.py  项目配置文件 Flask之flask-script模块使 ...

  5. Weshop基于Spring Cloud开发的小程序商城系统

    WESHOP | 基于微服务的小程序商城系统 Weshop是基于Spring Cloud(Greenwich)开发的小程序商城系统,提供整套公共微服务服务模块,包含用户中心.商品中心.订单中心.营销中 ...

  6. Python flask构建微信小程序订餐系统✍✍✍

    Python flask构建微信小程序订餐系统  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题, ...

  7. 夏日葵电商:连锁零售店小程序o2o系统解决方案

    公众平台"附近小程序"功能上线后,一个主体账号可以同时绑定N+个门店,这对连锁零售店铺来说是重磅福利呀,无论你是通过搜索还是线下扫码进入小程序,线上与线下都完全贯通了,线上多种入口 ...

  8. 基于微信小程序的系统开发准备工作

    腾讯推出微信小程序也有一段时间了,在各种行业里面也都掀起一阵阵的热潮,很多APP应用被简化为小程序的功能迅速推出,同时也根据小程序的特性推出各种独具匠心的应用,相对传统的APP来说,微信小程序确实能够 ...

  9. node配置微信小程序解密消息以及推送消息

    上一篇文章介绍过 微信小程序配置消息推送,没有看过的可以先去查看一下,这里就直接去把那个客服消息接口去解密那个消息了. 在这里我选择的还是json格式的加密. 也就是给小程序客服消息发送的消息都会被微 ...

随机推荐

  1. 关于ARM CM3的启动文件分析

    下面以ARM Cortex_M3裸核的启动代码为例,做一下简单的分析.首先,在启动文件中完成了三项工作: 1.  堆栈以及堆的初始化 2.  定位中断向量表 3.  调用Reset Handler. ...

  2. django数据查询之聚合查询和分组查询

    <1> aggregate(*args,**kwargs): 通过对QuerySet进行计算,返回一个聚合值的字典.aggregate()中每一个参数都指定一个包含在字典中的返回值.即在查 ...

  3. NPOI 笔记

    前言 文档:http://npoi.codeplex.com/documentation 示例:https://npoi.svn.codeplex.com/svn/ 下载:https://www.nu ...

  4. Python3中操作字符串str必须记住的几个方法

    几个Python的字符串常用内建函数 1.方法:Python3 isdigit()方法 描述:Python isdigit() 方法检测字符串是否只由数字组成. 语法:str.isdigit() 参数 ...

  5. php学习----异常处理(接上篇)

    PHP异常处理之抛出一个异常 从PHP5开始,PHP支持异常处理,异常处理是面向对象一个重要特性,PHP代码中的异常通过throw抛出,异常抛出之后,后面的代码将不会再被执行. 既然抛出异常会中断程序 ...

  6. March 06th, 2018 Week 10th Tuesday

    Hope for the best, but prepare for the worst. 抱最好的愿望,做最坏的打算. To hope for the best and prepare for th ...

  7. Spring中事务配置以及事务不起作用可能出现的问题

    前言:在Spring中可以通过对方法进行事务的配置,而不是像原来通过手动写代码的方式实现事务的操作,这在很大程度上减少了开发的难度,本文介绍Spring事务配置的两种方式:基于配置文件的方式和基于注解 ...

  8. 假设在本地搭一个server和mysql数据库环境,假设使用java来訪问数据库

    我们能够使用speedamp来搭一个server环境,能够在http://download.csdn.net/detail/baidu_nod/7630265下载 解压后无需安装直接能够使用.点击Sp ...

  9. Python 特殊函数解析(lambda 函数,map 函数,filter 函数,reduce 函数)

    写在之前 今天给大家介绍几个比较特殊的函数,他们具有函数式编程的特点,有人将它们视为 Python 可进行 「函数式编程」 的见证,至于什么是函数式编程,不是本篇文章的重点,感兴趣的可以去了解一下.老 ...

  10. [matlab] 4.M函数

    函数文件的编写 新建一个函数文件 函数的第一行的格式 :function [输出的参数] =函数名 (输入的参数) 输入和输出的参数可以有多个 保存函数文件的时候,注意文件名要和函数名一样 函数头和函 ...