为什么需要进行小程序持续化集成与部署 小程序开发有别于web开发,我们开发好的代码,需要通过小程序开发工具上传到腾讯的服务器。预览我们开发好的小程序,也需要通过小程序开发者工具进行构建。 如果是一个人开发,这种通过在开发者本机并经过小程序开发者工具构建上传的方式不会有什么问题,但是,一旦同一个小程序开发的人员多了,就很容易因为开发环境不一致而出现种种问题。 而通过持续化集成,提供统一的构建环境,则可以避免这一问题。
实现原理 实际上,我们是在一台局域网mac上安装并注册了一个GitLab Runner(可以理解为一个用来执行软件集成脚本的容器,Runner可以分布在不同的主机上,同一个主机上也可以有多个Runner。)
,当GitLab-CI(一套配合GitLab使用的持续集成系统)
检测到了变化,例如有新的push,会通知这台runner拉取新的代码,然后进行构建以及后续的操作。
代码编译完成后,我们使用小程序开发者工具提供的命令行工具进行代码上传。
当然,不一定要用mac, 只要能安装小程序开发者工具的设备,均可以。但是目前微信只提供了mac 和 windows版本的开发者工具,所以只能在基于mac 或者 windows系统上进行构建。
步骤 安装小程序开发工具 下载微信官方小程序开发者工具,并安装到GitLab Runner对应的设备上。
安装并配置 GitLab Runner 我们以mac系统为例:
安装GitLab Runner 1 2 sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64 sudo chmod +x /usr/local/bin/gitlab-runner
注册GitLab Runner 首先,需要到GitLab管理界面中的Runners页面去找注册需要使用的token。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 gitlab-runner register Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/): https://xxx.com/ (这里填写你gitlab的地址) Please enter the gitlab-ci token for this runner: xxxxxx (刚刚获取到的token) Please enter the gitlab-ci description for this runner: xxxxxx (随便填) Please enter the gitlab-ci tags for this runner (comma separated): wxapplet (这个我很重要,识别这个runner的标志) Whether to run untagged builds [true/false]: [false]: false Whether to lock the Runner to current project [true/false]: [true]: false Registering runner... succeeded runner=xxxx Please enter the executor: docker-ssh, virtualbox, docker+machine, docker-ssh+machine, docker, parallels, shell, ssh, kubernetes: shell Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
运行刚刚注册过的GitLab Runner 1 2 3 cd ~ gitlab-runner install gitlab-runner start
此时,如果在GitLab管理页面中的Runner页面,你可以看到一个Tags名称为wxapplet
的runner,说明注册成功。
编写 .gitlab-ci.yml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 image: node:latest before_script: - npm install after_script: - rm -r ./dist cache: paths: - node_modules/ stages: - build build-package: stage: build tags: - wxapplet only: - tags script: - regex="^prod-.*$"; if [[ $CI_COMMIT_TAG =~ $regex ]]; then npm run build; fi - regex="^freeze-.*$"; if [[ $CI_COMMIT_TAG =~ $regex ]]; then npm run freeze; fi - npm run deploy -- --tag ${CI_COMMIT_TAG}'
上面的文件表示,在build阶段,当push中带了tag时,将会启动build-package
这个任务。GitLab Runner将会依次执行以上的script。前两个script表示,当以prod-
或者freeze-
开头时,才会执行当前的命令。
我们可以根据tag的不同,去执行不同的脚本。
因为我们使用了小程序开发的第三方框架,所以上面的npm run build
或者npm run freeze
,均是生成小程序所需代码到dist目录中。如果你没有使用框架开发小程序,可忽略这两部,直接npm run deploy
。
npm run deploy
实际上执行了在package.json
中定义的脚本"node ./deploy/index.js"
,并且将CI_COMMIT_TAG作为参数传入。
deploy/index.js 核心(伪)代码如下;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 let cmd = '' ;if (/^login.*$/ .test(tag)) { cmd = '/Applications/wechatwebdevtools.app/Contents/Resources/app.nw/bin/cli -l --login-qr-output' ; } else { cmd = `/Applications/wechatwebdevtools.app/Contents/Resources/app.nw/bin/cli --upload ${小程序版本} @${小程序dist所在目} / --upload-desc ${这个版本的描述} ` ; } if (/^prod-.*$/ .test(tag)) { execSync('cp ./deploy/prod/project.config.json ./dist/project.config.json' ); } if (/^freeze-.*$/ .test(tag)) { execSync('cp ./deploy/freeze/project.config.json ./dist/project.config.json' ); } const child = exec( cmd, (error) => { if (error) { throw error; } }, ); child.stdout.on('data' , (data ) => { process.stdout.write(data); }); child.stderr.on('data' , (data ) => { process.stdout.write(data); throw new Error ('构建失败' ); });
对于 project.config.json 的说明
参考: