【Jenkins】Jenkins集成IOS全自动打包专题
1 全局配置
1.1 Keychain全局配置
1.1.1配置Provisioning Profiles
1、将/Users/管理员用户名/Library的MobileDevice文件夹拷贝到/Users/Shared/Jenkins/Library下;
/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles
/Users/HJDev/Library/MobileDevice/Provisioning Profiles
1.1.2 配置login.keychain文件
2、将/Users/管理员用户名/Library/Keychains/下的login.keychain及login.keychain-db这两个文件拷贝到/Users/Shared/Jenkins/Library/Keychains文件夹下面。
注意:Mac OS 10.12以下的没有login.keychain-db这个文件,只需要拷login.keychain文件。
1.1.3 放开开发证书与发布证书访问权限
设置开发证书与发布证书的访问控制权限;
1.1.4 上传login.keychain与ProvisioningProfile
2、在全局Keychains一项中upload刚刚拷贝的login.keychain与****Provisioning Profiles
iPhone Developer: ****(****)
iPhone Distribution: China **** Co.,Ltd.
1.2 keychain证书设置
在Mac OS上,证书其实是跟登陆账号走的,也就是添加时,如果选择“登陆”,则只会添加进该账号目录下的keychain中。针对Jenkins部署,因为其会另创建一个叫Jenkins的账户,如果发布证书是安装在当前账户时,构建会报错说找不到provisioning profile对应的证书,而当前帐号下的“钥匙串”中明明有这个证书。
此问题需要登出当前Mac帐户,然后登录Jenkins帐号,然后再次添加证书,选择“登录”类型,这样证书才会真正安装到jenkins帐号下,构建才能找到该证书。
1.2.1 CodeSigning Error: Provisioning profile "HJ_Dis" doesn't includesigning certificate "iPhone Distribution: China Dev Co., Ltd.".
构建报错:
Code Signing Error: Provisioningprofile "HJ_Dis" doesn't include signing certificate"iPhone Distribution: China Dev Co., Ltd.".
原因分析:
原因在于Provisioning profile与签名证书没对应上,钥匙串中存在两个同名证书,应该只保留真正用到的那一个。
另外,还有一个原因是Mac OS账号jenkins名下其实并没有安装该证书,只是系统登录账号下安装了,而jenkins构建时是使用Jenkins帐号进行的,其名下找不到证书自然就报错了。
2 工程NewItemForIOS配置
2.1 构建环境配置
2.1.1 设置工程SVN路径与账户
2.1.2 指定Keychain与CodeSign
在“源码管理”设置为None时,此处设置无效,需要在xcode工程中设置证书与provisioning pfrofile
2.1.3 编写shell打包脚本
Xcode9以后只能通过shell脚本打包,而不能通过Jenkins的xcode集成控件打包。
2.2 自动构建脚本格式
其中打包类型是adhoc、dev或者app-store,是在脚本中plist文件中指定的,与工程中设置无关。Provisioning profile也是在Jenkins中指定的,与工程设置无关。
打包主要是xcodebuild命令,分为编译archive文件与导出ipa文件两步。编译archive时可以设置不同scheme、target、configuration。
目前本人工作中将一个WorkSpace下的工程规划了7类target对应编译不同环境App,包括:
三个企业环境包HJ_EntDev、HJ_EntPre、HJ_EntDis;三个App调试环境包HJ_Dev、HJ_Pre、HJ_AppStore;一个Adhoc预发布包HJ_AdhocDis。
打包机器上脚本(注意要有\换行连接符,不然会报CodeSign错误):
如果是命令行测试,则要先进入其工程目录:
cd /Users/Shared/Jenkins/Home/workspace/IOS_Adhoc
Xcode9 xcodebuild export plist 配置
http://blog.csdn.net/andanlan/article/details/78113330?locationNum=9&fps=1
2.2.1 Ent_Dev企业测试包脚本
打包脚本:
IPANAME="HJ_EntDev"
security set-key-partition-list -Sapple-tool:,apple:,codesign: -s -k hjdev ~/Library/Keychains/login.keychain-db
xcodebuild -archivePath"./build/${IPANAME}-iphoneos/hjdev.xcarchive" \
-workspace "hjdev.xcworkspace" -sdk iphoneos-scheme "${IPANAME}" \
-configuration "Release" archive
xcodebuild -exportArchive -archivePath"./build/${IPANAME}-iphoneos/hjdev.xcarchive" \
-exportPath "./build/${IPANAME}" -exportOptionsPlist "../hjEntDisExportOptions.plist"\
-allowProvisioningUpdates
上传蒲公英脚本:
IPANAME="HJ_EntDev"
curl -F "file=@./build/${IPANAME}/${IPANAME}.ipa" -F "uKey=05cac7a8d17b3265d0fb3fda30b66751" -F "_api_key=d25e34087622e5c01d8810c328c125ee" http://www.pgyer.com/apiv1/app/upload
2.2.2 adhoc包脚本
打包脚本:
IPANAME="HJ_AdhocDis"
securityset-key-partition-list -S apple-tool:,apple:,codesign: -s -k hjdev ~/Library/Keychains/login.keychain-db
xcodebuild-archivePath "./build/${IPANAME}-iphoneos/hjdev.xcarchive" \
-workspace"hjdev.xcworkspace" -sdk iphoneos -scheme "${IPANAME}" \
-configuration"Release" archive
xcodebuild-exportArchive -archivePath"./build/${IPANAME}-iphoneos/hjdev.xcarchive" \
-exportPath"./build/${IPANAME}" \
-exportOptionsPlist"../HJAdhocDisExportOptions.plist" \
-allowProvisioningUpdates
上传蒲公英脚本:
IPANAME="HJ_AdhocDis"
curl -F "file=@./build/${IPANAME}/${IPANAME}.ipa" \
-F"uKey=05cac7a8d9865f0bd0fb3fda30b66751" -F "_api_key=d25e3403921985c01d8810c328c125ee" http://www.pgyer.com/apiv1/app/upload
2.2.6 全自动参数化打包脚本
打包脚本:
securityset-key-partition-list -S apple-tool:,apple:,codesign: -s -k hjdev ~/Library/Keychains/login.keychain-db
xcodebuild-archivePath "./build/${BuildType}-iphoneos/hjdev.xcarchive" \
-workspace"hjdev.xcworkspace" -sdk iphoneos -scheme "${BuildType}" \
-configuration"Release" archive
xcodebuild-exportArchive -archivePath"./build/${BuildType}-iphoneos/hjdev.xcarchive" \
-exportPath"./build/${BuildType}" \
-exportOptionsPlist"../${BuildType}ExportOptions.plist" \
-allowProvisioningUpdates
上报蒲公英脚本:
curl -F "file=@./build/${BuildType}/${BuildType}.ipa" \
-F "uKey=05cac7a812375f0bd0fb3fda30b66751" -F \ "_api_key=d25e340391b2e59742810c328c125ee" http://www.pgyer.com/apiv1/app/upload
2.3 设置任务超时
jenkins设置任务超时 超过限定时间停止任务
http://blog.csdn.net/dengruijin/article/details/52847860
jenkins的”build timeout plugin”插件可以帮我们完成该任务。我使用的是jenkins-2.7.1, 默认就已经安装了该插件,如果默认没有安装可在插件管理中搜索进行安装。
任务超时配置如下图:
2.4 权限修改
2.4.1递归修改所有权限
命令 : sudo chmod -R 777 tools_command/
解释 : -R 为递归遍历tools_command文件夹, chmod 755修改权限
2.5 Jenkins配置远程节点(解决Linux上iOS打包)
iOS打包无法在Linux上进行,因为Jenkins的Xcode插件需要调用Xcode,Xcode只能在OSX系统下安装。
2.5.1 登录Jenkins,添加MacOSX节点
系统管理☞管理节点☞新建节点
当前master为Linux系统
2.5.2 输入节点名称,勾选PermanentAgent
2.5.3 开启要绑定OSX系统电脑的远程登录
系统偏好设置☞共享☞勾选☞远程登录
获取远程登录的用户名和IP
2.5.4 配置节点
若没有Launch slave agents on Unix machines via SSH选项,需要安装SSH Slaves plugin插件
若没有Keychains and Provisioning Profiles Management选项,需要安装kpp-management-plugin插件
2.5.5 节点创建完成
节点创建完成后会自动连接
2.5.6 选择MacOSX节点
General☞勾选☞Restrict where this project can be run☞输入☞MacOSX
2.5.7 正在MacOSX上构建
2.6 自动上传蒲公英
jenkins+xcode+蒲公英实现ipa自动化打包
http://www.cocoachina.com/ios/20170811/20218.html
Jenkins持续集成打包+上传蒲公英
http://blog.csdn.net/yaoliangjun306/article/details/72471429
使用Jenkins实现持续集成蒲公英(iOS)
https://www.pgyer.com/doc/view/jenkins_ios
实现脚本代码:
curl -F "file=@/Users/Shared/Jenkins/Home/workspace/IOS_Ent_Dis/build/HJ_EntDis/HJ_EntDis.ipa"\
-F "uKey=05cac765327b5f0bd0fb3fda30b66751" -F "_api_key=d25e398641b2e5c01d8810c328c125ee" http://www.pgyer.com/apiv1/app/upload
3 常见问题
3.1 配置问题
3.1.1 构建报错:jenkins xcodebuild: error: The directorydoes not contain an Xcode project or workspace
原因:
其实在于keychain跟provisionfile没配置好
3.1.2 xcodebuild: error: The flag -scheme is required when specifying-archivePath but not -exportArchive.
此问题一是由于工程的scheme文件没有设置shared:
二是由于工程配置中没指定对scheme文件名:
3.1.3 FATAL: Unable to delete '/Users/Shared/Jenkins/Home/Package/.DS_Store'
此为权限问题,是因为Jackins账号对新建的Package目录没有写权限导致,添加Jackins读写权限即可。
3.1.4 code sign failed with exit code 1
此问题为项目工程中证书设置问题,需要设置为发布证书来打包。
3.1.5 error: exportArchive:
"hjdev.app" requires a provisioning profile with the Push Notifications and Associated Domains features
注意:升级 Xcode 9 之后,编译完成之后打包会一直报如下所示的错误:
error: exportArchive:"APPNAME.app" requires a provisioning profile with the PushNotifications feature.
ErrorDomain=IDEProvisioningErrorDomain Code=9 ""APPNAME.app" requiresa provisioning profile with the Push Notifications feature."UserInfo={NSLocalizedDescription="APPNAME.app" requires aprovisioning profile with the Push Notifications feature.,NSLocalizedRecoverySuggestion=Add a profile to the"provisioningProfiles" dictionary in your Export Options propertylist.}
** EXPORT FAILED **
Failed to build/Users/Tolecen/.jenkins/workspace/APPNAME/build/APPNAME_release.ipa
Build step 'Xcode' marked build asfailure
Finished: FAILURE
因为 Xcode 9 默认不允许访问钥匙串的内容,必须要设置allowProvisioningUpdates 才会允许,但是由于 Xcode integration 插件封闭,并不能对其进行修改加上这个属性,所以决定使用 Shell 脚本代替插件。
解决方案
将 Jenkins 项目里的 Xcode 构建步骤去掉,使用下面所示的命令:
xcodebuild -archivePath "/Users/USERNAME/.jenkins/workspace/APPNAME/build/Debug-iphoneos/APPNAME.xcarchive" -project APPNAME.xcodeproj -sdk iphoneos -scheme "SCHEMENAME" -configuration "Debug" archive
xcodebuild -exportArchive -archivePath "/Users/USERNAME/.jenkins/workspace/APPNAME/build/Debug-iphoneos/BasketballLeague.xcarchive" -exportPath "/Users/USERNAME/.jenkins/workspace/APPNAME/build/APPNAME_debug" -exportOptionsPlist '/Users/USERNAME/.jenkins/workspace/APPNAME/build/ExportOptions.plist' -allowProvisioningUpdates
如果是 workspace 的项目,那就将上面第一段的命令中 -project APPNAME.xcodeproj 修改为 -workspace APPNAME.xcworkspace 即可。
3.1.6 scheme错误
打开Xcode->manageSchema,把share勾上
3.1.7 error: Couldn't load -exportOptionsPlist: The file “ad-hocExport.plist” couldn’t be opened because there is no such file.
其原因在于自动打包脚本中设置的文件路径不对,导致plist文件找不到。
3.1.8 安装了jenkins之后:8080却访问不了
此原因在于java SDK版本不对,需要安装java 8
3.1.9 CodeSign error: code signing is required for product type Application in SDK
Jenkins打包如如题错误时,有可能是provisioning profile文件不是最新版本,导致引用的与工程指定的不一致。
3.1.10 打包报错unknown error-1=ffffffffffffffff
此问题为证书签名问题,但是可能的原因有两个:
1. jekins用户访问login.keychain的权限问题;
2. shell脚本放在一行,字符串超长问题;
3.1.10.1 问题一解决方案一unlockkeychain文件
1、采用脚本unlock;
security list-keychains
然后会输出
/Users/caijin/Library/Keychains/login.keychain-db
/Library/Keychains/System.keychain
然后执行
security unlock-keychain -p "password" /Users/hjdev/Library/Keychains/login.keychain-db
security unlock-keychain -p "hjdev" /Users/Shared/Jenkins/Library/Keychains/login.keychain-db
security unlock-keychain -p "hjdev" /Users/Shared/Jenkins/Home/workspace/IOS_Ent_Pre/login.keychain
// 路径要填写你自己login.keychin-db的这个路径 "password"就是你自己电脑钥匙串的密码
3.1.10.2 问题一解决方案二忽略授权提示框
然后还可以执行:
security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k password ${KEYCHAIN}
正式命令:
sudo security set-key-partition-list -Sapple-tool:,apple:,codesign: -s -k hjdev /Users/Shared/Jenkins/Library/Keychains/login.keychain-db
sudo security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k hjdev /Users/hjdev/Library/Keychains/login.keychain-db
sudo security set-keychain-settings~/Library/Keychains/login.keychain
sudo security set-keychain-settings /Users/hjdev/Library/Keychains/login.keychain
问题原因:
unlock keychain,这是个坑,当你在自己的命令行里直接执行xcodebuild的时候,就像没我们第一次使用xcode签名一样,会迸出keychain的提示,问你是否允许xcode使用keychain里的证书来签名,点了一次始终允许以后下次便不会再提示,直接在命令行使用xcodebuild也一样,但是放在编译脚本不管你点没点过“始终允许”都会报“unknown error -1=ffffffffffffffff Command
/usr/bin/codesign failed with exit code 1” 的奇怪错误,解决方法是:
securityset-key-partition-list -S apple-tool:,apple:,codesign: -s -k “YOUR_PASSWORD“ /Users/Shared/Jenkins/Library/Keychains/login.keychain-db
3.1.10.3 问题一解决方案三加入admin组
将jekins用户加入admin用户组,获取最高权限。然后重启Jenkins。
3.1.10.4 问题一解决方案四清理缓存
清理缓存文件:
cd /Users/Shared/Jenkins/Library/Developer/Xcode/DerivedData
xattr –rc *
cd /Users/hjdev/Library/Developer/Xcode/DerivedData
xattr –rc *
3.1.10.5 问题一解决方案五补齐ExportOptions.plist文件
也有可能是导出用的plist文件缺失,因为里面包含了provisioning profile的关联关系。
HJEntDisExportOptions.plist
3.1.10.6 问题二解决方案
将shell脚本加入换行连接符、分行输入,例如:
xcodebuild -archivePath "/Users/Shared/Jenkins/Home/workspace/IOS_Adhoc/build/EntDis-iphoneos/hjdev.xcarchive"\
-workspace "/Users/Shared/Jenkins/Home/workspace/IOS_Adhoc/hjdev.xcworkspace" -sdkiphoneos -scheme "hjdev" -configuration "Release" archive
3.1.11 Code Signing Error: No profile for team'G3D7634K6P' matching 'adhoc_dis' found: Xcode couldn't find any provisioning profiles matching'G3D7634K6P/adhoc_dis'
构建时报错:
Code Signing Error: No profile for team 'G3D7634K6P' matching 'adhoc_dis' found: Xcodecouldn't find any provisioning profiles matching 'G3D7634K6P/adhoc_dis'
原因:
没有将管理员账号下的provisioning profile文件拷贝至Jenkins用户目录下去。
3.1.12 Code Signing Error: Provisioning profile"HJ_Ent_Dis" doesn't include signing certificate "iPhoneDistribution: China dev Co., Ltd.".
构建报错:
Code Signing Error: Provisioning profile "HJ_Ent_Dis" doesn't include signing certificate"iPhone Distribution: China dev Co., Ltd.".
原因分析:
原因在于Provisioning profile与签名证书没对应上,钥匙串中存在两个同名证书,应该只保留真正使用的那个。
另外,还有一个原因是Mac OS账号jenkins名下其实并没有安装该证书,只是系统登录账号下安装了,而jenkins构建时是使用Jenkins帐号进行的,其名下找不到证书自然就报错了。
3.1.13 error: Couldn't load -exportOptionsPlist: Thefile “${BuildType}ExportOptions.plist” couldn’t be opened because there is nosuch file.
参数化构建时报错:
+ xcodebuild -exportArchive-archivePath ./build/HJ_EntPre-iphoneos/hjdev.xcarchive -exportPath./build/HJ_EntPre -exportOptionsPlist '../${BuildType}ExportOptions.plist'-allowProvisioningUpdates
error: Couldn't load-exportOptionsPlist: The file “${BuildType}ExportOptions.plist” couldn’t beopened because there is no such file.
原因:
对于带参数的命令,参数不能用在单引号(‘)字符串中,只能用在双引号(“)字符串中,一定要注意!!!
4 参考链接
(Very Good)最全Jenkins+SVN+iOS+cocoapods环境搭建及其错误汇总
https://www.cnblogs.com/weiming4219/p/7778699.html
详解Shell脚本实现iOS自动化编译打包提交
https://www.jianshu.com/p/bd4c22952e01
Jenkins配置节点(解决Linux上iOS打包)
https://www.jianshu.com/p/f445983512b7
(Good) IOS使用Jenkins持续集成
http://www.cnblogs.com/bhlsheji/p/5032723.html
iOS 中使用Jenkins进行持续集成
http://www.cocoachina.com/ios/20170607/19464.html
手把手教你利用Jenkins持续集成iOS项目
http://www.jianshu.com/p/41ecb06ae95f
搭建iOS自动化打包平台(利用Jenkins持续集成iOS项目)
http://blog.csdn.net/u013602835/article/details/54632843
Jenkins整合XCode详解
http://blog.csdn.net/youtk21ai/article/details/48719807
(Good)iOS 通过Jenkins 自动构建ipa
http://www.jianshu.com/p/ce36997919b4
(Good)jenkins xcodebuild命令行打包iOS项目问题汇总
http://blog.csdn.net/offbye/article/details/51506256
Jenkins构建ios包常见问题解决
https://www.jianshu.com/p/b6433cad6ad1
Xcode 9 在 Jenkins 自动打包脚本 中使用 Xcode integration 插件打包失败的原因
http://blog.csdn.net/hou_manager/article/details/78201221?locationNum=10&fps=1
jenkins打包一直报unknown error -1=ffffffffffffffff解决 (注意 别忘了重启电脑)
https://www.jianshu.com/p/cda327047524
【Mac】解决jenkins执行shell脚本等场景中遇见的权限不足问题
http://blog.csdn.net/hszxd479946/article/details/78831909
iOS 通过Jenkins 自动构建ipa
https://www.jianshu.com/p/ce36997919b4
XCode8.2 Jenkins 集成遇到的问题No profile matching,/codesign failed withexit code 1
https://www.jianshu.com/p/5591fe0c6770
MAC Jenkins搭建过程和遇到的问题!
http://blog.csdn.net/goodai007/article/details/51684303
Execute shell failure
http://jenkins-ci.361315.n4.nabble.com/Execute-shell-failure-td4645353.html
Jenkins加Shell实现最简单的持续部署
http://blog.csdn.net/neutrojan/article/details/41854883
Codesign returned unknown error
-1=ffffffffffffffff
https://stackoverflow.com/questions/44173831/codesign-returned-unknown-error-1-ffffffffffffffff
xcodebuild命令行编译问题汇总
http://blog.csdn.net/dongwuming/article/details/77061885
jenkins打包一直报unknownerror -1=ffffffffffffffff解决 (注意 别忘了重启电脑)
https://www.jianshu.com/p/cda327047524
Jenkins Xcode build works but aichive
failed with Command /usr/bin/codesign failed with exit code 1
codesigning fails with
"unknown error -1=ffffffffffffffff" #8797
https://github.com/fastlane/fastlane/issues/8797
【Jenkins常见问题解决】01. Mac上使用Jenkins持续集成报错Can’t connect to window server – not enoughpermissions.
http://blog.csdn.net/wirelessqa/article/details/8647771
8 can't archive “Command /usr/bin/codesign failed with exit code 1”
xcodebuild命令官方说明
https://www.jianshu.com/p/4f4d16326152
returned: -25308
https://stackoverflow.com/questions/41451502/xcodebuild-error-seckey-api-returned-25308
security / codesign in Sierra:
Keychain ignores access control settings and UI-prompts for permission