Jenkins(二)自动化打包
前言
从前文Jenkins(一)初步认识我们已经初步认识了Jenkins。接下来我们将通过一些配置来实现利用Jenkins自动化打包的目的。
摘要
一、进入Jenkins页面
二、创建自由风格的项目并配置源码管理
三、安装自动化打包构建时候所需的插件
四、上传构建过程所需的文件
五、配置构建方式(这里我们选择Xcode构建方式)
六、构建过程中的其他问题
附:直接跳过本篇文章,查看下篇文章:Jenkins(三)其他错误
其他文章
Jenkins(一)初步认识
Jenkins(二)自动化打包
Jenkins(三)其他错误
Jenkins(四)帮助
一、进入Jenkins页面
双击jenkins.war,启动jenkins
image.png
随后输入完整地址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”安装管理签名证书的插件。
选择安装管理签名证书的插件.png
安装完之后,刷新界面在构建环境中,会且才会有如下选项
860EC768-234E-4856-BF84-AFE5EE16B1E3.png
这两个选项需要填写的东西如下:
image.png
上图中的这些选项是iOS打包需要的签名文件和证书。如果没有的话,需要进入Keychains and Provisioning Profiles Management页面添加。怎么添加下面会介绍。
2、安装构建方式所选的插件
下载Xcode integration,并安装后,构建选项中才会有Xcode方式。
构建的方式有编写脚本和Xcode两种常用方式。
Xcode构建方式.png
两者构建方式相比,编写脚本的话会更加灵活,但是脚本写起来比较麻烦。这里我选择用Xcode的方式进行构建。 所以需要选择系统管理->管理插件,在“可选插件”中选中“Xcode integration”安装。
安装构建方式所选的插件.png
安装完后,构建配置页面如下:
image.png
如果未设置编译输出目录Build output directory
,其默认会在$WORKSPACE中对应项目里的bulids文件夹。
四、上传构建过程所需的文件
1、将我们的"发布证书及相关签名文件"利用该插件上传,这些文件之后在构建的时候需要使用。
①、上传工具在哪?
image.png
82E49797-9B62-40DD-8D69-EA65C1043C7E.png
②、要上传的文件在哪、应该放哪?
常识补充:我们要明白mac系统的弹出框无法显示隐藏的文件,所以如果要上传文件的话,必须将那些隐藏的文件复制一份到另外一个可见的文件夹下。
回归正题:要上传的"发布证书及相关签名文件"位于
/Users/用户名/Library
下的keychains文件夹
和MobileDevice文件夹
,该路径为隐藏不可见的路径。所以这里我们需要将放在隐藏不可见路径/Users/用户名/Library
下的keychains文件夹
和MobileDevice文件夹
,如图
354C8FC4-0697-4238-ADAE-08835D1F8D3D.png
分别复制一份拷贝到另外一个可见的文件夹(如
/Users/Shared/Jenkins/Library/
)下,以确保可以显示在上传弹出框中,以用来上传。拷贝后的结构,如图:
71EAB25A-689E-4F8D-BD09-F060C6EFD185.png
③、了解文件上传后,会被放到什么位置。答:上传的文件将会被放到/Users/Shared/Jenkins/Home/kpp_upload下。
举例
如上传前:
上传前.png
点击“选取文件”按钮,弹出上传文件框,分别选取自己的keychain和证书。点击upload进行上传。
image.png
上传后:
上传后.png
④、开始正式上传钥匙串login.keychain(是因为钥匙串中包含签名的证书?),上传过程中需正确设置它的Code Signing Identity填写
616DA338-53DE-4D89-A5A6-4EC00B80C51D.png
这里添加login.keychain的时候要填写的Code Signing Identity是什么呢,它的值又是从哪来呢?答如下图:
Code Signing Identity的值从这来.png
⑤、正式上传描述文件Provisioning Profiles,上传过程中需正确设置它的Provisioning Profiles Directory Path。
说明:在项目中配置.mobileprovision
文件后,执行构建,其会从我们这里填写的路径里找以该文件的UUID为文件名的.mobileprovision
文件。所以该路径的作用是让构建的时候来查找的。
所以,这里我们填写上面系统描述文件被复制到的路径,即
/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles
完善Provisioning Profiles的Provisioning Profiles Directory Path的填写.png
附:如果未填写会出现如下错误:
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.
Provisioning Profiles的Provisioning Profiles Directory Path未填写而导致的错误.png
所以,我们必须得确保我们填的那个目录下有以该文件的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
60A2C9FB-6C78-45D0-844D-5CE4FD9CEC4F.png
这里虽然提示我们是copy失败,但是实际上/Users/Shared/Jenkins/Home/kpp_upload
下的文件只是用于配置的时候选择使用,并不会真的执行Copy使其到我们填的那个目录里。所以,还是那句话,必须得确保我们填的那个目录下有以该文件的UUID为文件名的.mobileprovision
文件。否则会出现错误。
五、配置构建方式(这里我们选择Xcode构建方式)
所需进行的配置项有
配置构建方式所需进行的配置项.png
1、配置构建方式之General build settings
选项
①、了解 General build settings 选项需要配置的大概内容,结论是:这里我们需要配置Development Team ID,如果是xcworkspace,还必须在此设置Xcode Schema File。
该选项需要配置的大概内容,如图:
image.png
②、如何获取 Development Team ID ,以用来配置 Code signing & OS X keychain options 选项。
Development Team ID如何获取的方式为可在Keychain找到开发者证书iPhone Distribution: **** (329***)
,括号内的就是Team ID。举例如下图:
Development Team ID的获取.png
③、为 Code signing & OS X keychain options 选项配置Development Team ID。
即在 构建->Code signing & OS X keychain options,中的Development Team ID输入Development Team ID。如下图:
输入Development Team ID.png
如果未配置则会在构建的时候出现
FATAL: No global development team or local team ID was configured.
问题,如图
448A351B-9543-4A0A-9CCD-5EFF1EA7C252.png
④、获取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
选项
image.png
如果为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新版本
ia
以下是旧版本的
需要设置的选项有如下图两处,如果未设置,或者设置成下图这样子会造成错误
Advanced Xcode build options设置错误.png
所以,配置`Advanced Xcode build options`我们需要
①、配置项目文件`Xcode Workspace File`(必须)
②、配置`Xcode Schema File`(必须)
③、配置`Build output directory`(可填默认的 `${WORKSPACE}/build`)
①、配置项目文件Xcode Workspace File
上图的错误1:使用用cocoapods时候,Workspace File因多填写了个后缀名而造成了找不到文件的错误
使用用cocoapods时候,Workspace File因多填写了个后缀名而造成了找不到文件的错误.png
Xcode Workspace File的正确填写
这里Xcode Workspace File 填写就不多说了,填的是xcworkspace文件所在的目录,所以这里去掉后缀名即可,
即最后为$WORKSPACE/CJUIKitDemo/CJUIKit
。
②、配置Xcode Schema File
上图的错误2:使用用cocoapods时候,Schema File未填写而造成的错误
使用用cocoapods时候,Schema File未填写而造成的错误.png
Xcode Schema File的正确填写
而Xcode Schema File
的填写一般也为项目名,具体可自己查看Schema。
Xcode Schema File 填写了,但填写错误的常见情况
如果发现补充填写完后,还是有问题,如发现有如下问题,如图:
40348F8F-C546-46F8-90C5-6CB8F069B2F6.png
即错误为xcodebuild: error: The workspace named "CJUIKitDemo" does not contain a scheme named "CJUIKitDemo".
这是因为没找到指定scheme引起。工程代码提交时,未将.xcodeproj中的xcschemes提交。解决办法:将Manage Scheme后面工程的分享框勾上即可。
5209490F-E95E-403B-AFCE-2C47420C28D3.png
勾选Shared后,在.xcodeproj中就会产生xcshareddata目录
A2B8198C-F2FE-48B5-BC21-2BAE195F5683.png
随后,将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目录存放编译的输出内容,如图:
image.png
如此,基本大部分的问题都已解决了。
构建成功的样子为
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?,该选项按默认即可。
image.png
但是如果只是单纯的打开,就去构建会出现如下错误:
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:CFBundleVersion" /Users/Shared/Jenkins/Home/workspace/CJUIKitDemo/build/CJUIKitDemo.xcarchive/Info.plist
[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'
0CB98B45-021E-45CF-B692-40E479BE6331.png
其他参考:[iOS 通过Jenkins 自动构建ipa]
搭建iOS自动化打包平台(利用Jenkins持续集成iOS项目)
学会使用 Jenkins 搭建 iOS 持续集成环境
Jenkins