评论

微信小程序CI流程搭建教学(2) -- jenkins一键发布

相信长期在做小程序的同学都有过以下经历:只有固定的几台机器能发版,换台机器总担心出现点问题 (心力成本), 多个小程序发版,切换多个仓库,甚至要用开发者工具去打开不同的项目(体力成本)...

教学仓库: https://github.com/jinxuanzheng01/blog-xcx-ci-demo/tree/master,可以clone下来跟着教程一起尝试


CI流程搭建教学三部曲:

背景

相信长期在做小程序的同学都有过以下经历:

  • 只有固定的几台机器能发版,换台机器总担心出现点问题 (心力成本)
  • 多个小程序发版,切换多个仓库,甚至要用开发者工具去打开不同的项目(体力成本)
  • 频繁发版 + 发版流程琐碎 + 可能存在的多个小程序,一天的时间被机械劳动的事耗掉半天(时间成本)

本文主要来分享一下我这边的一套解决,实现一键发布,统一管理,在读之前最好先看下上一篇文章,不然可能会有些阻碍

关于jenkins:https://www.jenkins.io/zh/

案例

这个是目前我们已经搭建好的一套服务,可以看到整个流程都做了那些事?

  • 拉取代码
  • 询问当前需要变更的版本号
  • 构建(gulp, webpack,npm)
  • 存储当前版本镜像到静态资源服务器
  • 版本信息插入数据库
  • 更改后的版本文件提交到git仓库


其中红色为必须项,黑色看情况添加,如果你想也可以加入你想要添加的任何环节,下图是我们的版本发布管理后台的界面,存储的mysql的版本信息大概是这个样子:

关于管理后台第三章再讲,本文先着重描述怎么接入jenkins


Let’go

首先你需要一台云服务器用来搭建jenkins环境,推荐2核4g,不过1核2g也能跑


安装java

jenkins依赖于java环境,所以先安装java

yum install -y java-1.8.0-openjdk.x86_64

安装jenkins包

官方教程: https://www.jenkins.io/zh/doc/book/installing/

仓库地址: http://pkg.jenkins-ci.org/redhat-stable/

sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins

# 运行
service jenkins start   


运行成功后访服务器端口号8080



如果想修改端口号 vim /etc/sysconfig/jenkins, 找到JENKINS_PORT,修改后执行 service jenkins restart 即可

关于插件安装个人比较懒,点推荐快速过,后面有用到的一些插件慢慢会介绍

插件装完,中间需要创建管理员账号,一路确定最终安装成功

创建流水线pipeline

首先创建一个任务, 这里选择流水线(有兴趣可以了解下其他项), 点击确定

点击流水线找到编辑script的地方

这里可以选择在服务器上编写,还是从项目代码中读取jenkinsfile文件,我这里为了方便调试直接在jenkins机器上编写了


pipeline script

流水线语法官方教程: https://www.jenkins.io/zh/doc/book/pipeline/,里面讲的比较详细,可以先按下面的代码运行,遇到问题再查教程


流水线结构

写流水线之前,先想好我们整个发布流程需要做什么?

以当前例的话,大致分为5个环节:

  • 拉取代码
  • 询问需要更改的版本号
  • 安装npm包
  • 执行发布
  • 提交修改的版本号信息到仓库


每一个环节都是一个stage,先把stage列好,接下来我们一个一个补充

pipeline {
   agent any
   stages {
        // 拉取git代码
        stage('git pull') {
            steps {
            }
        }
        // 询问当前版本信息
        stage('inquirer version') {
            steps {
            }
        }
        // 构建
        stage('build') {
            steps {
            }
        }
       
        // 推送版本信息到git仓库
        stage('push version2git') {
            steps {
            }
        } 
   }
}


流水线语法

很多插件的语法使用还是比较复杂和琐碎的,这里提供了一个自动生成pipieline语法的功能

以git为例,会自动生成相应的语法,避免很多查文档的时间



拉取git代码

根据上文所述,我们需要生成流水线脚本,但是想要让仓库和jenkins建立ssh链接,需要配置git仓库的公钥和jenkins的私钥凭据


配置git仓库公钥

jenkins拉取git仓库代码,为了方便需要配下ssh秘钥

# 生成秘钥(没有要求一路回车即可)
ssh-keygen -t rsa -C "616347058@qq.com"
# 查看生成的ssh文件
cd ~/.ssh && ls  # 一般会有id_rsa id_rsa.pub两个文件, 一个私钥一个公钥

点击个人头像点击setting找到ssh,粘贴 id_rsa.pub 里的内容到输入框,点击add添加完成

配置jenkins私钥

除了在git上配置公钥外,还需要在jenkins上配置下凭据,点击添加

选择类型为ssh username,其他input的可以自己定一下的,这里需要一下,关于private项填的是私钥,需要复制id_rsa的内容,填写完成后点击添加,并在 Credentials 一栏选择刚才添加的证书

当前页面没有显示红字即为成功


pipeline code

// 拉取git代码
stage('git pull') {
    steps {
        git branch: 'test', credentialsId: '1', url: 'git@github.com:jinxuanzheng01/blog-xcx-ci-demo.git'
    }
}

添加到指定位置后,点击保存,尝试构建一次查看是否成功,点左下角#5可以查看当前构建进程

点击console output可以查看当前log,workspaces可以查看当前工作空间

可以看到当前工作空间为仓库代码

询问当前版本信息

jenkins是不支持交互式命令的,所以需要换一种实现,查了下文档jenkins是有api支持的,方法名为 input,不过在进行调用之前需要获取之前的版本信息,即读取version.config.json这个文件,整体代码如下:

// 询问当前版本信息
stage('inquirer version') {
    steps {
        script { 
            // 读取版本信息
            def versionJson = readJSON file: './version.config.json', text: ''

            // 设置问题描述
            def userInput = input(
                id: 'versionInput',
                message: '请设置版本信息', 
                parameters: [
                    [defaultValue: versionJson.version, description: '设置版本号', name: 'VERSION', $class: 'TextParameterDefinition'],
                    [defaultValue: 'jenkins CI is upload trial version as: ' + new Date().format('yyyy-MM-dd HH:mm:ss'), description: '设置版本描述(please use english)', name: 'VERSIONDESC', $class: 'TextParameterDefinition']
                ])

            // 设置全局变量
            env.VERSION = userInput.VERSION;
            env.VERSIONDESC = userInput.VERSIONDESC;

            // 重写本地版本文件(为后续进行版本提交做准备)
            writeJSON file: './version.config.json', json: [version:  env.VERSION, versionDesc: env.VERSIONDESC], pretty: 4;
        }
    }
}

运行下, 会发现会提示等待,鼠标点击后弹出模态框,可以看到里面有从本地文件里提取出来的上个版本的信息,手动修改下即可

注: readJSON和 writeJSON方法依赖 Pipeline Utility Steps 这个插件,没有的话会报错


执行构建

这里实际都是构建流程,直接统一用一个“build stage” 即可, 这里步骤很简单,可以想一下从git clone下来一个项目应该干什么,这里实际就是在做这样一件事情

// 构建
stage('build') {
    steps {
        sh "npm install"
        sh "npm run build"
    }
}

不过这里依赖node环境,需要先处理下,不然会报npm not found  


安装nodejs环境

这里的运行环境和本机没有关系,类似于一个沙盒,所以如果要安装node环境需要安装Config File Provider PluginNodeJS Plugin这两个插件

配置全局工具

安装完成后添加全局工具,找到"系统管理 -> 全局工具配置 -> NodeJS" ,点击nodejs安装,默认项即可,点击保存,重启jenkins服务,回到服务器,输入命令 service jenkins restart 


pipeline code

 // 构建
stage('build') {
    steps {
        nodejs('NodeJS 14.3.0') {
            sh "npm install"
            sh "npm run build"
        }
    }
}


上传成功

这时候如果没问题的话代码应该已经发布到体验版了,这里如果报ip错误记得去微信公众后台添加一下上传的ip白名单

提交新的版本号信息到仓库

pipeline code

基本就是将之前手动输入的命令写到脚本里

// 推送版本信息到git仓库
stage('push version2git') {
    steps {
        sh "git config --local user.name ${GIT_USER_NAME} && git config --local user.email ${GIT_USER_EMAIL}"
        sh "git add version.config.json"
        sh "git commit -m 'docs: 更改版本号为${VERSION}'"
        sh "git push origin ${BRANCH_NAME}"
    }
} 

关于上面代码中的"${}",其实是预设的环境变量,我们可以把一些固定的东西提出来,避免硬编码,例如:

pipeline {
   agent any
   // 环境变量 
   environment {
       GIT_USER_NAME = 'jenkinsCI'
       GIT_USER_EMAIL = 'test@163.com'
       GIT_ADDRESS = 'git@github.com:jinxuanzheng01/blog-xcx-ci-demo.git'
       BRANCH_NAME = 'master'
   }
}


更改jenkins账号权限

直接进行push的话,git会报权限不足,这里倒不是因为ssh秘钥有问题,而是jenkins在执行的时候使用的不是linux机器的root权限,而是一个jenkins的账号

所以最快速的做法是将jenkins运行环境修改为root权限

# 打开配置文件
vim /etc/sysconfig/jenkins

# 修改jenkins_user为root, 默认为jenkins
$JENKINS_USER="root"

# 修改相关文件夹权限组
chown -R root:root /var/lib/jenkins
chown -R root:root /var/cache/jenkins
chown -R root:root /var/log/jenkins
# 重启jenkins
service jenkins restart 


运行pipeline

重新构建,jenkins无报错,查看git仓库,执行成功


Running success

到此为止,整个pipeline已经work,你可以很轻松的尝试一键发布小程序

尤其是有多个小程序项目的时候,可以单独建个分组,方便集中管理,再也不需要手动切入不同的仓库,甚至使用小程序开发者工具去打开各个小程序,大概如下

项目集中管理不香么?

Tips: jenkins流水线代码已经放到仓库里了,地址 https://github.com/jinxuanzheng01/blog-xcx-ci-demo/blob/master/Jenkinsfile


额外补充

权限管理

jenkins有很多的功能插件,比如权限管理,这个还是个比较刚需的功能,可以自行Google下并不难


发送http请求

在pipeline中有时候需要去请求一些我们的其他服务,可以使用HTTP Request Plugin这个插件,文档地址:https://plugins.jenkins.io/http_request/里面有一些demo


npm切换私有仓库

方法一:  npm可以直接用npm_token登录

方法二:项目内设置.npmrc,填写私有仓库 + 用户信息


jenkins使用docker报权限不足

修改jenkins账号权限为root权限即可,上文有写,也可以直接修改docker.sock这个文件权限,如 chmod 777 /var/run/docker.sock 



手动安装jenkins插件

使用jenkins的插件管理安装插件很慢,有的时候还会失败,这里提供一个手动安装的方法


jenkins插件库: http://updates.jenkins-ci.org/download/plugins/config-file-provider/

搜索需要的插件下载(一般是*.hpi格式的),打开jenkins "系统管理 -> 插件管理 -> 高级",选择下载的文件上传即可


最后一次编辑于  2020-05-28  
点赞 2
收藏
评论

3 个评论

  • Autumn、
    Autumn、
    2022-03-22

    大佬这边是直接把代码打包编译好了?


    2022-03-22
    赞同
    回复
  • $
    $
    2021-10-09

    构建的时候 会把 ci也构建上去导致包很大

    2021-10-09
    赞同
    回复
  • beautyLee
    beautyLee
    2020-06-18

    我要是想在打包之后生成小程序的二位码改怎么操作,我看了下miniprogram-cli

    提供了qrcodeOutputDest,但是这边不知道具体结合jenkines怎么来操作


    2020-06-18
    赞同
    回复
登录 后发表内容