Jenkins血泪史


本文的大部分步骤参考的是一缕殇流化隐半边冰霜的博客,所以截图和很多步骤都是直接拷贝的该博客,然后补充了自己踩的一些坑。最后的脚本问题我没有拷贝过来,如果大家希望有所了解,可以去原博客,本文主要是个人以后回忆所用。

什么是持续集成

持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

为什么使用持续集成

1.减少风险
2.减少重复过程
3.任何时间、任何地点生成可部署的软件
4.增强项目的可见性

环境准备步骤

现在我们来开始安装Jenkins。从官网 上下载最新的pkg安装包。但是,这个时候直接安装是装不上的,Jenkins依赖于Java运行环境,因此需要首先安装Java的SDK

下载上图中JAVA的SDK,并安装。安装完成后,打开终端,cd进入到jenkins.war包所在目录,执行以下命令:

1
java -jar jenkins.war --httpPort=8080

httpPort指的就是Jenkins所使用的http端口,这里指定8080(默认的就是这个),可根据具体情况来修改。待Jenkins启动后,在浏览器页面输入以下地址:

1
http://localhost:8080

这样就打开Jenkins管理页面了。这个时候Jenkins给你新增了一个用户,名字就叫Jenkins,不过这个时候你不知道密码。你可能会去试密码,肯定是是不对的,因为初始密码很复杂。这个时候正确做法是打开http://localhost:8080 会出现下图的重设初始密码的界面。

按照提示,找到/Users/Shared/Jenkins/Home/这个目录下,这个目录虽然是共享目录,但是有权限的,非Jenkins用户/secrets/目录是没有读写权限的。


打开initialAdminPassword文件,复制出密码,就可以填到网页上去重置密码了。如下图





一路安装过来,输入用户名,密码,邮件这些,就算安装完成了。Jenkins安装完成之后,需要安装一些插件。

安装GitLab插件
GitLab用来管理源代码,Jenkins本身并没有自带GitLab插件,所以我们需要依次选择 系统管理->管理插件,在“可选插件”中选中“GitLab Plugin”和“Gitlab Hook Plugin”这两项,然后安装。

安装Xcode插件
同安装GitLab插件的步骤一样,我们依次选择系统管理->管理插件,在“可选插件”中选中“Xcode integration”安装。

安装签名证书管理插件
iOS打包内测版时,需要发布证书及相关签名文件,因此这两个插件对于管理iOS证书非常方便。还是在系统管理->管理插件,在“可选插件”中选中“Credentials Plugin”和“Keychains and Provisioning Profiles Management”安装。

安装脚本插件
这个插件的功能主要是用于在build后执行相关脚本。在系统管理->管理插件,在“可选插件”中选中“Post-Build Script Plug-in”安装。

安装完了插件,我们就可以配置一个构建项目了。


点击新建好的项目,进来配置一下General参数。

这里可以设置包的保留天数还有天数。

接着设置源码管理

由于现在我用到的是Github,在Jenkins的证书管理中添加账号、密码。在Jenkins管理页面,选择“Credentials”,然后选择“Global credentials (unrestricted)”,点击“Add Credentials”,如下图所示,我们填写自己的账号密码信息,然后点击“Save”,这样就把账号密码添加到Jenkins的全局域中去了。

如果正常的配置正确的话,是不会出现下图中的那段红色的警告。如果有下图的提示,就说明Jenkins还没有连通Github或者SVN,那就请再检查账号密码是否配置正确。

构建触发器设置这里是设置自动化测试的地方。这里涉及的内容很多,暂时我也没有深入研究,这里暂时先不设置。有自动化测试需求的可以好好研究研究这里的设置。

不过这里有两个配置还是需要是配置的

Poll SCM (poll source code management) 轮询源码管理
需要设置源码的路径才能起到轮询的效果。一般设置为类似结果: 0/5 每5分钟轮询一次
Build periodically (定时build)
一般设置为类似: 00 20 * 每天 20点执行定时build 。当然两者的设置都是一样可以通用的。

格式是这样的

分钟(0-59) 小时(0-23) 日期(1-31) 月(1-12) 周几(0-7,0和7都是周日)

构建环境设置
iOS打包需要签名文件和证书,所以这部分我们勾选“Keychains and Code Signing Identities”和“Mobile Provisioning Profiles”。
这里我们又需要用到Jenkins的插件,在系统管理页面,选择“Keychains and Provisioning Profiles Management”。

注意:这里可以上传的一种是login.keychain文件一种是ProvisioningProfiles文件。这里需要的Keychain,并不是cer证书文件。这个Keychain其实在/Users/管理员用户名/Library/keychains/login.keychain,当把这个Keychain设置好了之后,Jenkins会把这个Keychain拷贝到/Users/Shared/Jenkins/Library/keychains这里,(Library是隐藏文件)。Tips:后面的Code Signing Identity里面的开发者账号是手写的,而不是上传完keychain文件之后,自动识别的,这里坑了我好久

找到对应的Provisioning Profiles文件(这个文件不是直接在开发者平台下载下来的文件名字,而是安装到本地之后的文件名)上传之后, Provisioning Profiles也直接拷贝到/Users/Shared/Jenkins/Library/MobileDevice文件目录下。Tips: 如图的那个路径也是填写的,而不是上传后直接识别的,同上。

这样证书和签名文件就在Jenkins中配置好了,接下来我们只需要在item设置中指定相关文件即可。 回到我们新建的item,找到构建环境,按下图选好自己的相关证书和签名文件。Tips:在这里有时候你发现上传完上面的文件并填写完相应的账号和路径之后,点击下拉箭头,啥都没有,这个时候点击保存,然后退出,从新进来配置,多试几次。

接下来在进行构建的设置,这里没有用Xcode插件,用的是执行脚本。我本地项目Xcode证书和描述文件不是自动配置的,而是手动选择的。本地配置好之后,一定要执行git上传到远程仓库。

在导出ipa包的时候,注意xcodebuild 命令,里面选项配置是一个plist文件,我在下面贴出来plist内容

脚本内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 工程名
APP_NAME="KIFTestDemo"
# 证书
CODE_SIGN_DISTRIBUTION="iPhone Distribution: China Mobile Group Guangdong Company Limited"
# info.plist路径
project_infoplist_path="./${APP_NAME}/Info.plist"
#取版本号
bundleShortVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${project_infoplist_path}")
#取build值
bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" "${project_infoplist_path}")
DATE="$(date +%Y%m%d)"
IPANAME="${APP_NAME}_V${bundleShortVersion}_${DATE}.ipa"
#要上传的ipa文件路径
IPA_PATH="$HOME/${IPANAME}"
echo ${IPA_PATH}
echo "${IPA_PATH}">> text.txt
RchivePath="./KIFTestDemo.xcarchive"
IPAPath="./KIFTestDemoipa"
optionsPlist="./EnterpriseExportOptions.plist"
echo "=================clean================="
xcodebuild clean -workspace "${APP_NAME}.xcworkspace" -scheme "${APP_NAME}" -configuration 'Release' clean
echo "+++++++++++++++++build+++++++++++++++++"
xcodebuild archive -workspace "${APP_NAME}.xcworkspace" -scheme "${APP_NAME}" -sdk iphoneos -configuration 'Release' -archivePath $RchivePath
xcodebuild -exportArchive -archivePath $RchivePath -exportPath $IPAPath -exportOptionsPlist $optionsPlist

plist内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>compileBitcode</key>
<false/>
<key>provisioningProfiles</key>
<dict>
<key>com.gmcc.gdmobileimoa</key>
<string>ee4c1dc2-cf62-41d5-9871-93f0abbacad5</string>
</dict>
<key>method</key>
<string>enterprise</string>
</dict>
</plist>

构建后,将ipa包上传到蒲公英

构建后脚本内容

1
2
3
4
5
6
7
8
9
10
蒲公英上的User Key
uKey="24d26944ee1ffacec4faeb1ac73a0a48"
#蒲公英上的API Key
apiKey="8d418599c52f8bf47f6cd7db1c3116b7"
#要上传的ipa文件路径
IPA_PATH="./KIFTestDemoipa/KIFTestDemo.ipa"
#执行上传至蒲公英的命令
echo "++++++++++++++upload+++++++++++++"
curl -F "file=@${IPA_PATH}" -F "uKey=${uKey}" -F "_api_key=${apiKey}" http://www.pgyer.com/apiv1/app/upload

这里我们选择Execute a set of scripts,这里也是一个脚本,这个脚本用来上传自动打包好的ipa文件。

至此,我们的Jenkins设置就全部完成了。点击构建,就会开始构建项目了。

构建一次,各个颜色代表的意义如下:

如果构建失败了,可以去查看Console Output可以查看log日志。

总结

Jenkins自动打包,断断续续持续了一年才成功,开始的时候一直失败,中间一段时间因为没有时间尝试,最近重新拾起来了。遇到的坑,我想起来的时候,会持续补充

参考
iOS持续集成 Jenkins2.0 + shenzhen + 蒲公英 + GitLab
手把手教你利用 Jenkins 持续集成 iOS 项目