前言
从前文Jenkins(一)初步认识我们已经初步认识了Jenkins。接下来我们将通过一些配置来实现利用Jenkins自动化打包的目的。
摘要
一、进入Jenkins页面
二、创建自由风格的项目并配置源码管理
三、安装自动化打包构建时候所需的插件
四、上传构建过程所需的文件
五、配置构建方式(这里我们选择Xcode构建方式)
六、构建过程中的其他问题
附:直接跳过本篇文章,查看下篇文章:Jenkins(三)其他错误
其他文章
Jenkins(一)初步认识
Jenkins(二)自动化打包(iOS)
Jenkins(三)自动化打包其他错误(iOS)
Jenkins(四)自动化打包帮助(iOS)
iOS 再谈打包(证书、自动化、持续集成等)从开始到结束(精简)
一、进入Jenkins页面
双击jenkins.war,启动jenkins
随后输入完整地址http://localhost:8080即可进入Jenkins这个就不用重复提了。
二、创建自由风格的项目并配置源码管理
配置完源码管理后,点击“立即构建”,所构建的项目的源码会从所选择的SVN或Git上默认被下载到/Users/Shared/Jenkins/Home/workspace/里。
如果你发现代码一直没下载下来,那原因可能是你本身并没有装Git工具,安装后,重新点击“立即构建”即可下载Git上的代码到/Users/Shared/Jenkins/Home/workspace/里。
详细的请参见Jenkins(一)初步认识中的《二、创建项目并配置源码管理》部分。
三、安装自动化打包构建时候所需的插件
- 1、安装管理发布证书及相关签名文件的插件。安装完该插件后,才可以将我们的"发布证书及相关签名文件"利用该插件上传,并将它们配置在我们的构建环境中。
- 2、安装构建方式所选的插件
下面会依次说明。如已安装请跳过此步。
1、安装管理发布证书及相关签名文件的插件。安装完该插件后,才可以将我们的"发布证书及相关签名文件"利用该插件上传,并将它们配置在我们的构建环境中。
打包内测版时,需要发布证书及相关签名文件,而这些发布证书及相关签名文件的管理需要通过“Keychains and Provisioning Profiles Management”插件管理。
所以我们在系统管理->管理插件,在“可选插件”中选中“Credentials Plugin”和“Keychains and Provisioning Profiles Management”安装管理签名证书的插件。
安装完之后,刷新界面在构建环境中,会且才会有如下选项
这两个选项需要填写的东西如下:
上图中的这些选项是iOS打包需要的签名文件和证书。如果没有的话,需要进入Keychains and Provisioning Profiles Management页面添加。怎么添加下面会介绍。
2、安装构建方式所选的插件
下载Xcode integration,并安装后,构建选项中才会有Xcode方式。
构建的方式有编写脚本和Xcode两种常用方式。
两者构建方式相比,编写脚本的话会更加灵活,但是脚本写起来比较麻烦。这里我选择用Xcode的方式进行构建。 所以需要选择系统管理->管理插件,在“可选插件”中选中“Xcode integration”安装。
安装完后,构建配置页面如下:
如果未设置编译输出目录Build output directory
,其默认会在$WORKSPACE中对应项目里的bulids文件夹。
四、上传构建过程所需的文件
1、将我们的"发布证书及相关签名文件"利用该插件上传,这些文件之后在构建的时候需要使用。
①、上传工具在哪?
②、要上传的文件在哪、应该放哪?
常识补充:我们要明白mac系统的弹出框无法显示隐藏的文件,所以如果要上传文件的话,必须将那些隐藏的文件复制一份到另外一个可见的文件夹下。
回归正题:要上传的"发布证书及相关签名文件"位于
/Users/用户名/Library
下的keychains文件夹
和MobileDevice文件夹
,该路径为隐藏不可见的路径。所以这里我们需要将放在隐藏不可见路径/Users/用户名/Library
下的keychains文件夹
和MobileDevice文件夹
,如图
分别复制一份拷贝到另外一个可见的文件夹(如
/Users/Shared/Jenkins/Library/
)下,以确保可以显示在上传弹出框中,以用来上传。拷贝后的结构,如图:
③、了解文件上传后,会被放到什么位置。答:上传的文件将会被放到/Users/Shared/Jenkins/Home/kpp_upload下。
举例
如上传前:
点击“选取文件”按钮,弹出上传文件框,分别选取自己的keychain和证书。点击upload进行上传。
上传后:
④、开始正式上传钥匙串login.keychain(是因为钥匙串中包含签名的证书?),上传过程中需正确设置它的Code Signing Identity填写
这里添加login.keychain的时候要填写的Code Signing Identity是什么呢,它的值又是从哪来呢?答如下图:
⑤、正式上传描述文件Provisioning Profiles,上传过程中需正确设置它的Provisioning Profiles Directory Path。
说明:在项目中配置.mobileprovision
文件后,执行构建,其会从我们这里填写的路径里找以该文件的UUID为文件名的.mobileprovision
文件。所以该路径的作用是让构建的时候来查找的。
所以,这里我们填写上面系统描述文件被复制到的路径,即
/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles
附:如果未填写会出现如下错误:
FATAL: The path to store mobile provisioning profile files on the master is not configured. Go the plugin main configuration page and give the path.
所以,我们必须得确保我们填的那个目录下有以该文件的UUID为文件名的
.mobileprovision
文件。要不然会出现如下错误
FATAL: Failed to copy /Users/Shared/Jenkins/Home/kpp_upload/com.dvlproad.CJUIKitDemo.mobileprovision to /Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles/9265146f-df67-4c87-9136-22b09dbfa47b.mobileprovision java.nio.file.AccessDeniedException: /Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles/9265146f-df67-4c87-9136-22b09dbfa47b.mobileprovision
这里虽然提示我们是copy失败,但是实际上/Users/Shared/Jenkins/Home/kpp_upload
下的文件只是用于配置的时候选择使用,并不会真的执行Copy使其到我们填的那个目录里。所以,还是那句话,必须得确保我们填的那个目录下有以该文件的UUID为文件名的.mobileprovision
文件。否则会出现错误。
五、配置构建方式(这里我们选择Xcode构建方式)
所需进行的配置项有
1、配置构建方式之General build settings
选项
①、了解 General build settings 选项需要配置的大概内容,结论是:这里我们需要配置Development Team ID,如果是xcworkspace,还必须在此设置Xcode Schema File。
该选项需要配置的大概内容,如图:
②、如何获取 Development Team ID ,以用来配置 Code signing & OS X keychain options 选项。
Development Team ID如何获取的方式为可在Keychain找到开发者证书iPhone Distribution: **** (329***)
,括号内的就是Team ID。举例如下图:
③、为 Code signing & OS X keychain options 选项配置Development Team ID。
即在 构建->Code signing & OS X keychain options,中的Development Team ID输入Development Team ID。如下图:
如果未配置则会在构建的时候出现
FATAL: No global development team or local team ID was configured.
问题,如图
④、获取mobileprovision文件的UUID
在Terminal下输入下面的命令并回车::
curl https://raw.githubusercontent.com/0xc010d/mobileprovision-read/master/main.m | clang -framework Foundation -framework Security -o /usr/local/bin/mobileprovision-read -x objective-c -
这条命令的作用是下载mobileprovision-read的源码,然后编译,最后把生成的二进制文件mobileprovision-read放入到/usr/local/bin/路径下。
查看UUID的命令是:
mobileprovision-read -f test.mobileprovision-o UUID
测试可用。
详情查看:命令行获取mobileprovision文件的UUID
从apple网下载的描述文件通过本命令可查看到该UUID,通过进入描述文件的系统存放路径/Users/lichaoqian/Library/MobileDevice/Provisioning Profiles
可以检验该UUID的描述文件有没有被添加进来。
2、配置构建方式之Code signing & OS X keychain options
选项
如果为Unlock Keychain,则会出现如下错误
......
.....(省略号代表省略很多)
/Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app: errSecInternalComponent
Command /usr/bin/codesign failed with exit code 1** BUILD FAILED **
The following build commands failed:
CodeSign /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app
(1 failure)
Build step 'Xcode' marked build as failure
Finished: FAILURE
3、配置构建方式之Advanced Xcode build options
选项
Jenkins Xcode新版本
以下是旧版本的
需要设置的选项有如下图两处,如果未设置,或者设置成下图这样子会造成错误
所以,配置`Advanced Xcode build options`我们需要
①、配置项目文件`Xcode Workspace File`(必须)
②、配置`Xcode Schema File`(必须)
③、配置`Build output directory`(可填默认的 `${WORKSPACE}/build`)
①、配置项目文件Xcode Workspace File
上图的错误1:使用用cocoapods时候,Workspace File因多填写了个后缀名而造成了找不到文件的错误
Xcode Workspace File的正确填写
这里Xcode Workspace File 填写就不多说了,填的是xcworkspace文件所在的目录,所以这里去掉后缀名即可,
即最后为$WORKSPACE/CJUIKitDemo/CJUIKit
。
②、配置Xcode Schema File
上图的错误2:使用用cocoapods时候,Schema File未填写而造成的错误
Xcode Schema File的正确填写
而Xcode Schema File
的填写一般也为项目名,具体可自己查看Schema。
Xcode Schema File 填写了,但填写错误的常见情况
如果发现补充填写完后,还是有问题,如发现有如下问题,如图:
即错误为xcodebuild: error: The workspace named "CJUIKitDemo" does not contain a scheme named "CJUIKitDemo".
这是因为没找到指定scheme引起。工程代码提交时,未将.xcodeproj中的xcschemes提交。解决办法:将Manage Scheme后面工程的分享框勾上即可。
勾选Shared后,在.xcodeproj中就会产生xcshareddata目录
随后,将xcshareddata目录提交到SVN/Git上,重新构建即可。(补充:.xcodeproj中的xcuserdata目录可不提交到SVN/Git上,因为这个目录是临时生成的,没什么用。)
③、配置Build output directory
(可填默认的 ${WORKSPACE}/build
)
=== BUILD TARGET MBProgressHUD OF PROJECT Pods WITH CONFIGURATION Release ===
Check dependencies
CreateUniversalBinary /Users/lichaoqian/Project/jenkinsWorkspace/Release-iphoneos/MBProgressHUD/libMBProgressHUD.a normal armv7\ arm64
cd /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/CJUIKitDemo/Pods
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool -static /Users/Shared/Jenkins/Library/Developer/Xcode/DerivedData/CJUIKitDemo-gqrgqeoigrvayahkawwllwksjemk/Build/Intermediates.noindex/Pods.build/Release-iphoneos/MBProgressHUD.build/Objects-normal/armv7/libMBProgressHUD.a /Users/Shared/Jenkins/Library/Developer/Xcode/DerivedData/CJUIKitDemo-gqrgqeoigrvayahkawwllwksjemk/Build/Intermediates.noindex/Pods.build/Release-iphoneos/MBProgressHUD.build/Objects-normal/arm64/libMBProgressHUD.a -o /Users/lichaoqian/Project/jenkinsWorkspace/Release-iphoneos/MBProgressHUD/libMBProgressHUD.a
error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't create output file: /Users/lichaoqian/Project/jenkinsWorkspace/Release-iphoneos/MBProgressHUD/libMBProgressHUD.a (No such file or directory)=== BUILD TARGET CJFile OF PROJECT Pods WITH CONFIGURATION Release ===
Check dependencies
.......
(以下省略,直接跳到结果)
.......
** BUILD FAILED **The following build commands failed:
CreateUniversalBinary /Users/lichaoqian/Project/jenkinsWorkspace/Release-iphoneos/MBProgressHUD/libMBProgressHUD.a normal armv7\ arm64
CreateUniversalBinary /Users/lichaoqian/Project/jenkinsWorkspace/Release-iphoneos/CJFile/libCJFile.a normal armv7\ arm64
(2 failures)
Build step 'Xcode' marked build as failure
Finished: FAILURE
从描述中的error:
可知是我们在Build output directory
中填写/Users/lichaoqian/Project/jenkinsWorkspace 错了。将其改为默认的 ${WORKSPACE}/build
重新构建即可解决本错误。
附:此操作会在该项目中创建一个build目录存放编译的输出内容,如图:
如此,基本大部分的问题都已解决了。
构建成功的样子为
Check dependencies
=== BUILD TARGET Pods-CJUIKitDemo OF PROJECT Pods WITH CONFIGURATION Release ===
Check dependencies
=== BUILD TARGET CJUIKitDemo OF PROJECT CJUIKitDemo WITH CONFIGURATION Release ===
Check dependencies
Validate /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app
cd /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/CJUIKitDemo
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
export PRODUCT_TYPE=com.apple.product-type.application
builtin-validationUtility /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app** BUILD SUCCEEDED **
Finished: SUCCESS
此时你去上面的路径/Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app中即可看到有.app生成了。
六、ipa的输出
上面只是BUILD SUCCEEDED,要输出ipa还要打开Pack application, build and sign .ipa?,该选项按默认即可。
但是如果只是单纯的打开,就去构建会出现如下错误:
Touch /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app.dSYM
cd /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/CJUIKitDemo
export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/usr/bin/touch -c /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/Release-iphoneos/CJUIKitDemo.app.dSYM** ARCHIVE SUCCEEDED **
Cleaning up previously generated .ipa files
Cleaning up previously generated .dSYM.zip files
Packaging IPA
[CJUIKitDemo] /usr/libexec/PlistBuddy -c "Print :ApplicationProperties:CFBundleShortVersionString" /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/CJUIKitDemo.xcarchive/Info.plist
Packaging CJUIKitDemo.xcarchive => /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/CJUIKitDemo-1.0-1.ipa
[CJUIKitDemo] $ /usr/bin/xcodebuild -exportArchive -archivePath /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/CJUIKitDemo.xcarchive -exportPath /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build -exportOptionsPlist /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/ad-hocFZ5YDHE5JZExportOptions.plist -allowProvisioningUpdates
2018-06-21 02:14:51.320 xcodebuild[7671:202008] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/4j/wvf5xqh93631jch00c4qwkrw00008b/T/CJUIKitDemo_2018-06-21_02-14-51.316.xcdistributionlogs'.
2018-06-21 02:14:51.863 xcodebuild[7671:202008] [MT] IDEDistribution: Step failed: <IDEDistributionSigningAssetsStep: 0x7f879484e5d0>: Error Domain=IDEDistributionSigningAssetStepErrorDomain Code=0 "Locating signing assets failed." UserInfo={NSLocalizedDescription=Locating signing assets failed., IDEDistributionSigningAssetStepUnderlyingErrors=(
"Error Domain=IDEProvisioningErrorDomain Code=9 ""CJUIKitDemo.app" requires a provisioning profile." UserInfo={NSLocalizedDescription="CJUIKitDemo.app" requires a provisioning profile., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}"
)}
error: exportArchive: "CJUIKitDemo.app" requires a provisioning profile.Error Domain=IDEProvisioningErrorDomain Code=9 ""CJUIKitDemo.app" requires a provisioning profile." UserInfo={NSLocalizedDescription="CJUIKitDemo.app" requires a provisioning profile., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}
** EXPORT FAILED **
Failed to build /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/CJUIKitDemo-1.0-1.ipa
Build step 'Xcode' marked build as failure
Finished: FAILURE
六、构建过程中的其他问题
No profiles for 'com.dvlproad.CJUIKitDemo' were found: Xcode couldn't find a provisioning profile matching 'com.dvlproad.CJUIKitDemo'. Code signing is required for product type 'Application' in SDK 'iOS 10.3'
其他参考:[iOS 通过Jenkins 自动构建ipa]
搭建iOS自动化打包平台(利用Jenkins持续集成iOS项目)
学会使用 Jenkins 搭建 iOS 持续集成环境
Jenkins