微信小游戏 Jenkins 持续集成

缘起

最近一直在做微信小游戏,和其他 Native 项目一样,我们希望也能通过 Jenkins 可以做到方便地对项目进行自动打包分发。但是微信小游戏与之前的一般项目相比,需要在微信开发者工具上扫码登录才能上传到微信后台,下面就详细说明一下这个比一般多项目多出的步骤要如何配置。

准备工作

因为我们想要在构建过程中进行扫码登录,那么就肯定需要有个地方展示这个二维码。如果展示在每次 build 的 Console Output 中的话,每次都需要点击进入 Console Output 页面,等待它 build 完成,执行到这里,而且在这里输出的都是纯文本,很难展示出可供扫描的二维码。所以我们需要安装 description setter plugin 这个插件,它可以在每次 build 任务下边展示出任何你想展示的内容。
description-setter-plugin

构建

我们当前使用的引擎是 Cocos Creator 1.9.1,和其他项目项目一样,构建过程就是通过 shell 脚本调用 Creator 的 CLI 命令,只不过这次 platform 选择的是 wecahtgame,如果有子域项目还需要先行构建子域项目。对构建过程有疑问的朋友,可以在网上搜索 Creator Jenkins 打包,有很多教程,所以构建这步本文就略过了。

上传资源

微信要求首包小于 4MB,本地资源加上代码包括 Cocos2d 引擎代码一共不能超过 4MB,所以资源稍大一些就需要上传到远程服务器在微信小游戏中再动态下载回来。具体是首次启动时全部下载还是使用到的时候就看自己的策略了。所以这里可能有一个上传资源的过程,我们这里采用的是先压缩成 zip 包,通过 scp 命令上传到服务器上,然后再 unzip,随后删除 build 目录下的 res,确保首包不大于 4MB。

1
2
3
4
5
6
7
8
9
10
echo "压缩资源包"
zipName=res.${BUILD_NUMBER}.zip
cp -rf ./build/wechatgame/res ./
zip ${zipName} -r res
rm -rf ./res
echo "上传资源到服务器"
ssh root@${REMOTE_IP} "rm -rf ${REMOTE_DIR}"
ssh root@${REMOTE_IP} "mkdir -p ${REMOTE_DIR}"
scp -r ${zipName} root@${REMOTE_IP}:${REMOTE_DIR}
rm -rf ./build/wechatgame/res

上传到微信

接下来就是把 build 目录下的 wechatgame 上传到微信后台,发布体验版了。微信开发者工具支持命令行和 HTTP 调用,这里是官方文档:命令行调用HTTP 调用

  • 第一步,生成登录二维码:

    我们首先通过命令打开微信开发者工具,然后调用登录命令。
    这里需要注意一下,命令行提供两种登录方式:一是将登录二维码转成 base64 给用户,让用户自己集成到自己系统中使用;二是将二维码打印在命令行中。经测试,将二维码打印在终端中展示还是不错的,但是输出在 Jenkins 系统的 console output,再通过网页中展现来就都成了 unicode 码了,根本没有办法使用。而且通过命令行登录会导致执行 shell 的进程卡住,直到用户扫码登录,这会导致我们后续的动作都无法执行。所以我们在这里通过 HTTP 的方式拿到登录二维码 base64 之后的数据,然后通过一小段 python 脚本转换成图片文件。以下是 shell 脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/bash
    UPLOAD_WECHAT=$1
    if [ "${UPLOAD_WECHAT}" = "true" ]
    then
    echo '生成微信开发者工具登录二维码'
    WX_CLI=/Applications/wechatwebdevtools.app/Contents/Resources/app.nw/bin/cli
    $WX_CLI -o
    PORT=$(cat ~/Library/Application\ Support/微信web开发者工具/Default/.ide)
    curl http://127.0.0.1:$PORT/login?format=base64 > qrcode.txt
    $(python ./tools/base64tojpeg.py qrcode.txt qrcode.jpg)
    echo [QRCode generated succeed]$BUILD_NUMBER
    fi

    这是上面使用到的 base64tojepg.py 脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #!/usr/bin/python
    import os,base64,sys
    if len(sys.argv) == 3:
    inputFileName=sys.argv[1]
    outputFileName=sys.argv[2]
    allstr=open(inputFileName).read()
    idx=allstr.find(',')
    bstr=allstr[idx+1:]
    imgdata=base64.b64decode(bstr)
    file=open(outputFileName,'wb')
    file.write(imgdata)
    file.close()
    else:
    print('Useage: python base64tojpeg.py inputFileName outputFileName')

    至于上面 shell 脚本最后输出的 [QRCode generated succeed]$BUILD_NUMBER,则是为了能够使用我们上面安装的 description setter plugin 来展示出我们转换好的 qrcode.jpg。下面第二步详细说明。

  • 第二步,展示登录二维码:

    在项目配置 Build 这一步中加入 set build description 这一步骤:
    add-build-step
    如果没有这一项,请检查准备工作中的插件是否安装成功。
    这一步骤详细配置如下:
    build-description-configuration
    上面是配置一个正则表达式,只要在 Console Output 里输出了我们要匹配内容,就会在 Build History 里展示出下面我们配置的内容。
    我们目前配置的是一个指向我们转换好的二维码图片的 <img>标签和一段提示文案:
    <img src= "http://{your-jenkins-server.com}/view/{your-project-name}/job/{your-project-name}/ws/qrcode.jpg?t=_\1" height= "200" width= "200" /><br/>扫描登录微信开发者工具
    截图中红框遮挡的内容分别是 Jenkins 系统域名、项目名称、项目名称。
    展示出来就是下面这个样子,我们就可以扫码确认登录了。
    build-history

  • 第三步,上传

    我们最后调用微信的上传命令把 wechatgame 这个目录上传到微信后台就可以了。这一步需要注意的是,上传命令必须在登录后调用,否则就会报错。一开始我是在展示出登录二维码之后手动 sleep 15 秒,但这样做有两个问题,一是如果在 15s 内没有扫码登录,就会导致上传失败,二是即使很快就扫码登录了,真正的上传过程还是在 15 秒之后才开始执行的。后来我想到微信的命令行调用上传是会卡住进程的,扫码登录成功后会执行后续脚本,为什么不利用这个特性呢?
    以下是上传过程的 shell 脚本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    #!/bin/bash
    UPLOAD_WECHAT=$1
    if [ "${UPLOAD_WECHAT}" = "true" ]
    then
    WX_CLI=/Applications/wechatwebdevtools.app/Contents/Resources/app.nw/bin/cli
    WX_VERSION="$MAIN_VERSION.$BUILD_NUMBER"
    PRO_ROOT=$(pwd)/build/wechatgame
    PORT=$(cat ~/Library/Application\ Support/微信web开发者工具/Default/.ide)
    $WX_CLI -l --login-qr-output base64@qrcode_cli.txt
    echo '上传到微信后台体验版本'
    $WX_CLI -u "$WX_VERSION@$PRO_ROOT"
    #clean up
    rm qrcode.txt
    rm qrcode.jpg
    cp expired.jpg qrcode.jpg
    fi

最后的清理工作,是删除掉临时产生的二维码 base64 文本,以及为了不影响最新的扫码登录二维码展示,把 Build History 中展示的二维码替换成一个“已过期”的图片。
这样我们配置好了微信小游戏的自动化打包以及上传,只需要点击一下 Build,然后等待二维码展示,扫码确认登录,就自动上传到微信后台了,十分方便。

PS. 如果多个开发者上传,在微信公众平台的后台里是不会互相覆盖的,想要切换体验版需要在后台里选择对应版本,选择为体验版,所以最好是同一个微信号做这个持续集成分发的工作。这个步骤我暂时没有找到可以自动化执行的方法,如果有朋友找到了的话,可以评论下告知我,感谢~


小结

  • 安装 description setter plugin 插件
  • 通过 HTTP 调用微信开发者工具拿到登录二维码数据
  • 使用 description setter plugin 插件展示登录二维码
  • 调用微信开发者工具命令行登录卡住进程,扫码登录,上传完成

以上就是我最近总结的微信小游戏 / 小程序使用 Jenkins 系统自动化打包分发的经验,有哪里写得不对或是可以改进的地方,欢迎多多留言评论~