小程序结合Jenkins实现CICD

小程序结合Jenkins实现CICD

在将公司前后端大多数项目都接入了 CI 流程后,发布效率快的一批。但是我最近发现我司在微信小程序这的发布,居然还是手动??? 程序员天生就对重复的事情敏感,这些事情得想个法弄成自动的。
但是在微信小程序出现,上传体验版/生成开发版都需要利用微信开发者工具,最开始是依赖于人手动去点 ide 上的上传按钮,再然后就是,微信开放出了命令行调用接口

之前看了一些利用 Mac Os + JenkinsCI,这个方案并不能够适用所有项目组,我们重点还是希望通过服务器进行 CI,于是就去翻找小程序文档以及网上文章, 天无绝人之路,发现小程序的文档多了 CI 这一项

miniprogram-ci 从 1.0.28 开始支持第三方平台开发的上传和预览,调用方式与普通开发模式无异

20210508105525

整理目录结构

因为 miniprogram-ci 需要依赖于 npm 安装,但是又不需要与我们项目的包相关,所以就有了如下结构

20210508140343

npm install miniprogram-ci

获取小程序代码上传秘钥

在公众平台的开发管理 -> 开发设置中,需要先将秘钥下载下来,我们可以写入到项目的根目录的 ci-private.key 文件中,加入版本管理,因为我们有 IP 白名单,所以泄露也不打紧

20210508140910

配置本次版本更新内容

我们将配置放入到根目录中,方便自动更新的时候获取

  • version.config.json
{
    "version":"1.1.5",
    "versionDesc":"Test Jenkins"
}

CI程序编写

  • start.js
const ci = require('miniprogram-ci');
const fs = require('fs');

/* 项目配置 */
const projectConfig = require('./project.config.json'); // 就是小程序的配置文件
const versionConfig = require('./version.config.json');


// new ci实例
const project = new ci.Project({
    appid: projectConfig.appid,
    type: 'miniProgram',
    projectPath: projectConfig.miniprogramRoot,
    privateKeyPath: './ci-private.key',
    ignores: ['node_modules/**/*'],
});

/** 上传 */
async function upload({version = '0.0.0', versionDesc ='test'}) {
    await ci.upload({
        project,
        version,
        desc: versionDesc,
        setting: {
            es7: true,
            minify: true,
            autoPrefixWXSS: true
        },
        onProgressUpdate: console.log,
      })
}



/** 入口函数 */
async function init() {
    // 上传
    await upload(versionConfig);
}

init();

测试能否上传成功

node start.js

20210508141906

20210508141930

这样就是可以成功了,然后我们利用 Jenkins 让我提交代码时自动发布体验版

接入Jenkins

  • git秘钥等凭据添加

20210508142730

  • 安装钉钉通知插件、NodeJs环境插件
  • 配置钉钉机器人、Node别名

20210508142809
20210508142845

  • 创建流水线项目
  • 项目基本配置 webhook、构建记录滚动配置等

编写Jenkinsfile

pipeline {
   agent any
   // 环境变量 
   environment {
       GIT_ADDRESS = 'git@xxxx/wechat-blog.git'
       BRANCH_NAME = 'master'
   }
   stages {
        // 拉取git代码
        stage('git pull') {
            steps {
                git branch: "${BRANCH_NAME}", credentialsId: '1', url: "${GIT_ADDRESS}"
            }
        }

        // 构建
        stage('build') {
            steps {
                nodejs('nodejs') {
                    sh "npm install"
                    sh "node start.js"
                }
            }
        }
   }

   post {
		success {
            dingtalk (
                robot: '58f10219-2cd3-4de7-a1af-f85f4010c10a',
                type: 'MARKDOWN',
                title: "水商城构建通知 - $BRANCH_NAME",
                text: [
                    '# 水商城构建通知 - $BRANCH_NAME',
                    '',
                    '---',
                    "- 任务: ${env.BUILD_NUMBER}",
                    '- 状态: <font color=blue>构建成功</font>',
                ]
            )
		}
		
        failure {
            dingtalk (
                robot: '58f10219-2cd3-4de7-a1af-f85f4010c10a',
                type: 'MARKDOWN',
                title: "构建通知 - $BRANCH_NAME",
                text: [
                    '# 构建通知 - $BRANCH_NAME',
                    '',
                    '---',
                    "- 任务: ${env.BUILD_NUMBER}",
                    '- 状态: <font color=red>构建失败</font>',
                    ]
            )
		}
	}
}

Git提交测试

钉钉通知成功

20210508142555

注意

如果上传失败,要记得去增加 IP白名单

您的支持是对我最大的鼓励!

发表于: 作者:憧憬。
关注互联网以及分享全栈工作经验的原创个人博客和技术博客,热爱编程,极客精神
Github 新浪微博 SegmentFault 掘金专栏