使用 Jenkins 搭建 iOS/Android 持续集成打包平台【转】

背景描述

根据项目需求,现要在团队内部搭建一个统一的打包平台,实现对iOS和Android项目的打包。并且为了方便团队内部的测试包分发,但愿在打包完成后能生成一个二维码,体验用户(产品、运营、测试等人员)经过手机扫描二维码后就能直接安装测试包。html

该需求具备必定的广泛性,基本上全部开发APP的团队均可能会用到,所以我将整个需求实现的过程整理后造成此文,而且真正地作到了零基础上手,到手即飞、开箱即用,但愿能对你们有所帮助。java

首先,先给你们展现下平台建设完成后的总体效果:正则表达式

 

 

 

 

该平台主要实现的功能有3点:docker

  • 按期对GitHub仓库进行检测,如有更新则自动执行构建打包;
  • 构建成功后根据ipa/apk生成二维码,并可在历史构建列表中展现各个版本的二维码,经过手机扫描二维码可直接安装对应版本;
  • 在构建结果页面中展现当次构建的成果物(Artifact,如.ipa.app.apkinfo.plist等文件),供有须要的用户进行下载。

接下来,本文就开始对平台建设的完整实现过程进行详细介绍。shell

安装Jenkins

Jenkins依赖于Java运行环境,所以须要首先安装Java安全

安装Jenkins的方式有多种,能够运行对应系统类型的安装包,能够经过docker获取镜像,也能够直接运行war包。服务器

我我的倾向于直接运行war包的形式,只需下载jenkins.war后,运行以下命令便可启动Jenkins。markdown

$ nohup java -jar jenkins_located_path/jenkins.war --httpPort=88 &

若是不指定httpPort,Jenkins的默认端口为8080。网络

Jenkins插件

Jenkins有很是多的插件,能够实现各类功能的扩展。oracle

针对搭建的iOS/Android持续集成打包平台,我使用到了以下几个插件。

  • GIT plugin
  • SSH Credentials Plugin
  • Git Changelog Plugin: 获取仓库提交的commit log
  • build-name-setter:用于修改Build名称
  • description setter plugin:用于在修改Build描述信息,在描述信息中增长显示QRCode(二维码)
  • Post-Build Script Plug-in:在编译完成后经过执行脚本实现一些额外功能
  • Xcode integration: iOS专用(可选)
  • Gradle plugin: Android专用(可选)

安装方式也比较简单,直接在Jenkins的插件管理页面搜索上述插件,点击安装便可。

建立项目(Job)

在Jenkins中,构建项目以Job的形式存在,所以须要针对每一个项目建立一个Job。有时候,一个项目中可能有多个分支同时在进行开发,为了分别进行构建,也能够针对每一个分支建立一个Job。

建立Job的方式有多种,本次只须要建立Freestyle project类型的便可。

Main page -> New Item -> Freestyle project

对于一个持续集成打包平台,每次打包都由4步组成:触发构建、拉取代码、执行构建、构建后处理。对应的,在每一个Job中也对应了这几项的配置。

配置Git代码仓库

要对项目进行构建,配置项目的代码仓库是必不可少的。因为当前咱们的项目托管在GitHub私有仓库中,所以在此须要对Git进行配置。

【Source Code Management】配置栏目下,若是以前GIT plugin安装成功,则会出现Git选项。

配置Git代码仓库时,有三项是必须配置的:仓库URL地址(Repository URL)、仓库权限校验方式(Credentials),以及当前Job须要构建的代码分支(Branches to build)。

在配置Repository URL时,选择HTTPS URLSSH URL都可。不过须要注意的是,Credentials要和Repository URL对应,也就是说:

  • 若是Repository URLHTTPS URL形式的,那么Credentials就要采用GitHub用户名密码的校验方式;并且,若是在GitHub中开启了2FA(two-factor authentication),那么还须要在GitHub中建立一个Personal access token,输入密码时将这个Personal access token做为密码进行输入。
  • 若是Repository URLSSH URL形式的,那么就须要先在Jenkins所在的服务器上建立一个SSH秘钥对,并将公钥添加到GitHub的SSH keys中,而后在填写Credentials时,选择SSH Username with private key的校验方式,填入GitHub Username、SSH私钥、以及建立SSH秘钥对时设置的Passphrase

若是对Git权限校验的概念还比较模糊,能够参考《深刻浅出Git权限校验》。

在配置Branches to build时,能够采用多种形式,包括分支名称(branchName)、tagNamecommitId等。其中分支名称的形式用的最多,例如,如果构建master分支,则填写refs/heads/master,如果构建develop分支,则填写refs/heads/develop

除了以上关于Git的必填配置项,有时根据项目的实际状况,可能还须要对Jenkins的默认配置项进行修改。

比较常见的一种状况就是对clone的配置进行修改。

在Jenkins的默认配置中,clone代码时会拉取全部历史版本的代码,并且默认的超时时限只有10分钟。这就形成在某些项目中,因为代码量自己就比较大,历史版本也比较多,再加上网络环境不是特别好,Jenkins根本无法在10分钟以内拉取完全部代码,超时后任务就会被自动终止了(错误状态码143)。

这种问题的解决方式也很简单,无非就是两种思路,要么少拉取点代码(不获取历史版本),要么提升超时时限。对应的配置在Advanced clone behaviours中:

  • Shallow clone:勾选后不获取历史版本;
  • Timeout (in minutes) for clone and fetch operation:配置后覆盖默认的超时时限。

配置构建触发器

代码仓库配置好了,意味着Jenkins具备了访问GitHub代码仓库的权限,能够成功地拉取代码。

那Jenkins何时执行构建呢?

这就须要配置构建触发策略,即构建触发器,配置项位于【Build Triggers】栏目。

触发器支持多种类型,经常使用的有:

  • 按期进行构建(Build periodically)
  • 根据提交进行构建(Build when a change is pushed to GitHub)
  • 按期检测代码更新,若有更新则进行构建(Poll SCM)

构建触发器的选择为复合选项,若选择多种类型,则任一类型知足构建条件时就会执行构建工做。若是全部类型都不选择,则该Jenkins Job不执行自动构建,但可经过手动点击【Build Now】触发构建。

关于定时器(Schedule)的格式,简述以下:

MINUTE HOUR DOM MONTH DOW

  • MINUTE: Minutes within the hour (0-59)
  • HOUR: The hour of the day (0-23)
  • DOM: The day of the month (1-31)
  • MONTH: The month (1-12)
  • DOW: The day of the week (0-7) where 0 and 7 are Sunday.

一般状况下须要指定多个值,这时能够采用以下operator(优先级从上到下):

  • *适配全部有效的值,若不指定某一项,则以*占位;
  • M-N适配值域范围,例如7-9表明7/8/9均知足;
  • M-N/X*/X:以X做为间隔;
  • A,B,C:枚举多个值。

另外,为了不多个任务在同一时刻同时触发构建,在指定时间段时能够配合使用H字符。添加H字符后,Jenkins会在指定时间段内随机选择一个时间点做为起始时刻,而后加上设定的时间间隔,计算获得后续的时间点。直到下一个周期时,Jenkins又会从新随机选择一个时间点做为起始时刻,依次类推。

为了便于理解,列举几个示例:

  • H/15 * * * *:表明每隔15分钟,而且开始时间不肯定,这个小时多是:07,:22,:37,:52,下一个小时就多是:03,:18,:33,:48
  • H(0-29)/10 * * * *:表明前半小时内每隔10分钟,而且开始时间不肯定,这个小时多是:04,:14,:24,下一个小时就多是:09,:19,:29
  • H 23 * * 1-5:工做日每晚23:00至23:59之间的某一时刻;

配置构建方式

触发策略配置好以后,Jenkins就会按照设定的策略自动执行构建。但如何执行构建操做,这还须要咱们经过配置构建方式来进行设定。

经常使用的构建方式是根据构建对象的具体类型,安装对应的插件,而后采用相应的构建方式。例如,如果构建Android应用,安装Gradle plugin以后,就能够选择Invoke Gradle script,而后采用Gradle进行构建;如果构建iOS应用,安装Xcode integration插件以后,就能够选择Xcode,而后选择Xcode进行构建。

该种方式的优点是操做简单,UI可视化,在场景不复杂的状况下能够快速知足需求。不过缺点就是依赖于插件已有的功能,若是场景较复杂时可能单个插件还没法知足需求,须要再安装其它插件。并且,有些插件可能还存在一些问题,例如对某些操做系统版本或XCode版本兼容不佳,出现问题时咱们就会比较被动。

我我的更倾向于另一种方式,就是本身编写打包脚本,在脚本中自定义实现全部的构建功能,而后在Execute Shell中执行。这种方式的灵活度更高,各类场景的构建需求都能知足,出现问题后也能自行快速修复。

另外,对于iOS应用的构建,还有一个须要额外关注的点,就是开发者证书的配置。

若是是采用Xcode integration插件进行构建,配置会比较复杂,须要在Jenkins中导入开发证书,并填写多个配置项。不过,若是是采用打包脚本进行构建的话,状况就会简单许多。只要在Jenkins所运行的计算机中安装好开发者证书,打包命令在Shell中能正常工做,那么在Jenkins中执行打包脚本也不会有什么问题。

构建后处理

完成构建后,生成的编译成果物(ipa/apk)会位于指定的目录中。可是,若是要直接在手机中安装ipa/apk文件还比较麻烦,不只在分发测试包时须要将好几十兆的安装包进行传送,体验用户在安装时也还须要经过数据线将手机与计算机进行链接,而后再使用PP助手或豌豆荚等工具进行安装。

当前比较优雅的一种方式是借助蒲公英(pgyer)fir.im等平台,将ipa/apk文件上传至平台后由平台生成二维码,而后只须要对二维码连接进行分发,体验用户经过手机扫描二维码后便可实现快速安装,效率获得了极大的提高。

上传安装包文件,生成二维码

无论是蒲公英仍是fir.im,都有对应的Jenkins插件,安装插件后能够在Post-build中实现对安装包的上传。

除了使用Jenkins插件,fir.im还支持命令上传的方式,蒲公英还支持HTTP Post接口上传的方式。

我我的推荐采用命令或接口上传的方法,并在构建脚本中进行调用。灵活是一方面,更大的好处是若是上传失败后还能进行重试,这在网络环境不是很稳定的状况下极其必要。

Jenkins成功完成安装包上传后,pgyer/fir.im平台会生成一个二维码图片,并在响应中将图片的URL连接地址进行返回。

展现二维码图片

二维码图片的URL连接有了,那要怎样才能将二维码图片展现在Jenkins项目的历史构建列表中呢?

这里须要用到另一个插件,description setter plugin。安装该插件后,在【Post-build Actions】栏目中会多出description setter功能,能够实现构建完成后设置当次build的描述信息。这个描述信息不只会显示在build页面中,同时也会显示在历史构建列表中。

有了这个前提,要将二维码图片展现在历史构建列表中貌似就能够实现了,能直观想到的方式就是采用HTMLimg标签,将<img src='qr_code_url'>写入到build描述信息中。

这个方法的思路是正确的,不过这么作之后并不会实现咱们预期的效果。

这是由于Jenkins出于安全的考虑,全部描述信息的Markup Formatter默认都是采用Plain text模式,在这种模式下是不会对build描述信息中的HTML编码进行解析的。

要改变也很容易,Manage Jenkins -> Configure Global Security,将Markup Formatter的设置更改成Safe HTML便可。

更改配置后,咱们就能够在build描述信息中采用HTMLimg标签插入图片了。

另外还须要补充一个点。若是是使用蒲公英(pyger)平台,会发现每次上传安装包后返回的二维码图片是一个短连接,神奇的是这个短链接竟然是固定的(对同一个帐号而言)。这个短链接老是指向最近生成的二维码图片,可是对于二维码图片的惟一URL地址,平台并无在响应中进行返回。在这种状况下,咱们每次构建完成后保存二维码图片的URL连接就没有意义了。

应对的作法是,每次上传完安装包后,经过返回的二维码图片短连接将二维码图片下载并保存到本地,而后在build描述信息中引用该图片的Jenkins地址便可。

收集编译成果物(Artifacts)

每次完成构建后,编译生成的文件较多,可是并非全部的文件都是咱们须要的。

一般状况下,咱们可能只须要其中的部分文件,例如.ipa/.app/.plist/.apk等,这时咱们能够将这部分文件单独收集起来,并在构建页面中展现出来,以便在须要时进行下载。

要实现这样一个功能,须要在【Post-build Actions】栏目中新增Archive the artifacts,而后在Files to archive中经过正则表达式指定成果物文件的路径。

设置完毕后,每次构建完成后,Jenkins会在Console Output中采用设定的正则表达式进行搜索匹配,若是能成功匹配到文件,则会将文件收集起来。

总结

本文主要是对如何使用Jenkins搭建iOS/Android持续集成打包平台的基础概念和实施流程进行了介绍。对于其中涉及到的执行命令、构建脚本(build.py),以及Jenkins的详细配置,出于篇幅长度和阅读体验的考虑,并无在文中进行详细展开。

为了实现真正的开箱即用,我将Jenkins的配置文件和构建脚本抽离出来造成一套模板,只须要导入到Jenkins中,而后针对具体的项目修改少许配置信息,便可将这一套持续集成打包平台运行起来,实现和文章开头插图中彻底相同的功能效果。

相关文章
相关标签/搜索