根据项目需求,现要在团队内部搭建一个统一的打包平台,实现对iOS和Android项目的打包。并且为了方便团队内部的测试包分发,但愿在打包完成后能生成一个二维码,体验用户(产品、运营、测试等人员)经过手机扫描二维码后就能直接安装测试包。html
该需求具备必定的广泛性,基本上全部开发APP的团队均可能会用到,所以我将整个需求实现的过程整理后造成此文,而且真正地作到了零基础上手,到手即飞、开箱即用
,但愿能对你们有所帮助。java
首先,先给你们展现下平台建设完成后的总体效果:正则表达式
该平台主要实现的功能有3点:docker
.ipa
、.app
、.apk
、info.plist
等文件),供有须要的用户进行下载。接下来,本文就开始对平台建设的完整实现过程进行详细介绍。shell
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有很是多的插件,能够实现各类功能的扩展。oracle
针对搭建的iOS/Android持续集成打包平台,我使用到了以下几个插件。
安装方式也比较简单,直接在Jenkins的插件管理页面搜索上述插件,点击安装便可。
在Jenkins中,构建项目以Job的形式存在,所以须要针对每一个项目建立一个Job。有时候,一个项目中可能有多个分支同时在进行开发,为了分别进行构建,也能够针对每一个分支建立一个Job。
建立Job的方式有多种,本次只须要建立Freestyle project
类型的便可。
Main page
->New Item
->Freestyle project
对于一个持续集成打包平台,每次打包都由4步组成:触发构建、拉取代码、执行构建、构建后处理。对应的,在每一个Job中也对应了这几项的配置。
要对项目进行构建,配置项目的代码仓库是必不可少的。因为当前咱们的项目托管在GitHub私有仓库中,所以在此须要对Git
进行配置。
在【Source Code Management】
配置栏目下,若是以前GIT plugin
安装成功,则会出现Git
选项。
配置Git代码仓库时,有三项是必须配置的:仓库URL地址(Repository URL
)、仓库权限校验方式(Credentials
),以及当前Job须要构建的代码分支(Branches to build
)。
在配置Repository URL
时,选择HTTPS URL
或SSH URL
都可。不过须要注意的是,Credentials
要和Repository URL
对应,也就是说:
Repository URL
是HTTPS URL
形式的,那么Credentials
就要采用GitHub用户名密码的校验方式;并且,若是在GitHub中开启了2FA(two-factor authentication)
,那么还须要在GitHub中建立一个Personal access token
,输入密码时将这个Personal access token
做为密码进行输入。Repository URL
是SSH URL
形式的,那么就须要先在Jenkins所在的服务器上建立一个SSH
秘钥对,并将公钥添加到GitHub的SSH keys
中,而后在填写Credentials
时,选择SSH Username with private key
的校验方式,填入GitHub Username、SSH私钥、以及建立SSH
秘钥对时设置的Passphrase
。若是对Git权限校验的概念还比较模糊,能够参考《深刻浅出Git权限校验》。
在配置Branches to build
时,能够采用多种形式,包括分支名称(branchName
)、tagName
、commitId
等。其中分支名称的形式用的最多,例如,如果构建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】
栏目。
触发器支持多种类型,经常使用的有:
构建触发器的选择为复合选项,若选择多种类型,则任一类型知足构建条件时就会执行构建工做。若是全部类型都不选择,则该Jenkins Job
不执行自动构建,但可经过手动点击【Build Now】
触发构建。
关于定时器(Schedule)的格式,简述以下:
MINUTE HOUR DOM MONTH DOW
一般状况下须要指定多个值,这时能够采用以下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页面中,同时也会显示在历史构建列表中。
有了这个前提,要将二维码图片展现在历史构建列表中貌似就能够实现了,能直观想到的方式就是采用HTML
的img
标签,将<img src='qr_code_url'>
写入到build描述信息中。
这个方法的思路是正确的,不过这么作之后并不会实现咱们预期的效果。
这是由于Jenkins出于安全的考虑,全部描述信息的Markup Formatter
默认都是采用Plain text
模式,在这种模式下是不会对build描述信息中的HTML编码进行解析的。
要改变也很容易,Manage Jenkins
-> Configure Global Security
,将Markup Formatter
的设置更改成Safe HTML
便可。
更改配置后,咱们就能够在build描述信息中采用HTML
的img
标签插入图片了。
另外还须要补充一个点。若是是使用蒲公英(pyger)
平台,会发现每次上传安装包后返回的二维码图片是一个短连接,神奇的是这个短链接竟然是固定的(对同一个帐号而言)。这个短链接老是指向最近生成的二维码图片,可是对于二维码图片的惟一URL地址,平台并无在响应中进行返回。在这种状况下,咱们每次构建完成后保存二维码图片的URL连接就没有意义了。
应对的作法是,每次上传完安装包后,经过返回的二维码图片短连接将二维码图片下载并保存到本地,而后在build描述信息中引用该图片的Jenkins地址便可。
每次完成构建后,编译生成的文件较多,可是并非全部的文件都是咱们须要的。
一般状况下,咱们可能只须要其中的部分文件,例如.ipa/.app/.plist/.apk
等,这时咱们能够将这部分文件单独收集起来,并在构建页面中展现出来,以便在须要时进行下载。
要实现这样一个功能,须要在【Post-build Actions】
栏目中新增Archive the artifacts
,而后在Files to archive
中经过正则表达式指定成果物文件的路径。
设置完毕后,每次构建完成后,Jenkins会在Console Output
中采用设定的正则表达式进行搜索匹配,若是能成功匹配到文件,则会将文件收集起来。
本文主要是对如何使用Jenkins搭建iOS/Android持续集成打包平台的基础概念和实施流程进行了介绍。对于其中涉及到的执行命令、构建脚本(build.py),以及Jenkins的详细配置,出于篇幅长度和阅读体验的考虑,并无在文中进行详细展开。
为了实现真正的开箱即用
,我将Jenkins的配置文件和构建脚本抽离出来造成一套模板,只须要导入到Jenkins中,而后针对具体的项目修改少许配置信息,便可将这一套持续集成打包平台运行起来,实现和文章开头插图中彻底相同的功能效果。