Jenkins(二)自动化打包(iOS)

前言

从前文Jenkins(一)初步认识我们已经初步认识了Jenkins。接下来我们将通过一些配置来实现利用Jenkins自动化打包的目的。

摘要
一、进入Jenkins页面
二、创建自由风格的项目并配置源码管理
三、安装自动化打包构建时候所需的插件
四、上传构建过程所需的文件
五、配置构建方式(这里我们选择Xcode构建方式)
六、构建过程中的其他问题
附:直接跳过本篇文章,查看下篇文章:Jenkins(三)其他错误

其他文章
Jenkins(一)初步认识
Jenkins(二)自动化打包(iOS)
Jenkins(三)自动化打包其他错误(iOS)
Jenkins(四)自动化打包帮助(iOS)
iOS 再谈打包(证书、自动化、持续集成等)从开始到结束(精简)

一、进入Jenkins页面

双击jenkins.war,启动jenkins

《Jenkins(二)自动化打包(iOS)》 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”安装管理签名证书的插件。

《Jenkins(二)自动化打包(iOS)》 选择安装管理签名证书的插件.png

安装完之后,刷新界面在构建环境中,会且才会有如下选项

《Jenkins(二)自动化打包(iOS)》 860EC768-234E-4856-BF84-AFE5EE16B1E3.png

这两个选项需要填写的东西如下:

《Jenkins(二)自动化打包(iOS)》 image.png

上图中的这些选项是iOS打包需要的签名文件和证书。如果没有的话,需要进入Keychains and Provisioning Profiles Management页面添加。怎么添加下面会介绍。

2、安装构建方式所选的插件

下载Xcode integration,并安装后,构建选项中才会有Xcode方式。

构建的方式有编写脚本和Xcode两种常用方式。

《Jenkins(二)自动化打包(iOS)》 Xcode构建方式.png

两者构建方式相比,编写脚本的话会更加灵活,但是脚本写起来比较麻烦。这里我选择用Xcode的方式进行构建。 所以需要选择系统管理->管理插件,在“可选插件”中选中“Xcode integration”安装。

《Jenkins(二)自动化打包(iOS)》 安装构建方式所选的插件.png

安装完后,构建配置页面如下:

《Jenkins(二)自动化打包(iOS)》 image.png

如果未设置
编译输出目录Build output directory,其默认会在$WORKSPACE中对应项目里的bulids文件夹。

四、上传构建过程所需的文件

1、将我们的”发布证书及相关签名文件”利用该插件上传,这些文件之后在构建的时候需要使用。

①、上传工具在哪?

《Jenkins(二)自动化打包(iOS)》 image.png

《Jenkins(二)自动化打包(iOS)》 82E49797-9B62-40DD-8D69-EA65C1043C7E.png

②、要上传的文件在哪、应该放哪?

常识补充:我们要明白mac系统的弹出框无法显示隐藏的文件,所以如果要上传文件的话,必须将那些隐藏的文件复制一份到另外一个可见的文件夹下。

回归正题:要上传的”发布证书及相关签名文件”位于/Users/用户名/Library下的keychains文件夹MobileDevice文件夹,该路径为隐藏不可见的路径。所以这里我们需要将放在隐藏不可见路径/Users/用户名/Library下的keychains文件夹MobileDevice文件夹,如图

《Jenkins(二)自动化打包(iOS)》 354C8FC4-0697-4238-ADAE-08835D1F8D3D.png

分别复制一份拷贝到另外一个可见的文件夹(如/Users/Shared/Jenkins/Library/)下,以确保可以显示在上传弹出框中,以用来上传。拷贝后的结构,如图:

《Jenkins(二)自动化打包(iOS)》 71EAB25A-689E-4F8D-BD09-F060C6EFD185.png

③、了解文件上传后,会被放到什么位置。答:上传的文件将会被放到/Users/Shared/Jenkins/Home/kpp_upload下。

举例
如上传前:

《Jenkins(二)自动化打包(iOS)》 上传前.png

点击“选取文件”按钮,弹出上传文件框,分别选取自己的keychain和证书。点击upload进行上传。

《Jenkins(二)自动化打包(iOS)》 image.png

上传后:

《Jenkins(二)自动化打包(iOS)》 上传后.png

④、开始正式上传钥匙串login.keychain(是因为钥匙串中包含签名的证书?),上传过程中需正确设置它的Code Signing Identity填写

《Jenkins(二)自动化打包(iOS)》 616DA338-53DE-4D89-A5A6-4EC00B80C51D.png

这里添加login.keychain的时候要填写的Code Signing Identity是什么呢,它的值又是从哪来呢?答如下图:

《Jenkins(二)自动化打包(iOS)》 Code Signing Identity的值从这来.png

⑤、正式上传描述文件Provisioning Profiles,上传过程中需正确设置它的Provisioning Profiles Directory Path。

说明:在项目中配置.mobileprovision文件后,执行构建,其会从我们这里填写的路径里找以该文件的UUID为文件名的.mobileprovision文件。所以该路径的作用是让构建的时候来查找的。

所以,这里我们填写上面系统描述文件被复制到的路径,即/Users/Shared/Jenkins/Library/MobileDevice/Provisioning Profiles

《Jenkins(二)自动化打包(iOS)》 完善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.

《Jenkins(二)自动化打包(iOS)》 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

《Jenkins(二)自动化打包(iOS)》 60A2C9FB-6C78-45D0-844D-5CE4FD9CEC4F.png

这里虽然提示我们是copy失败,但是实际上
/Users/Shared/Jenkins/Home/kpp_upload下的文件只是用于配置的时候选择使用,并不会真的执行Copy使其到我们填的那个目录里。所以,还是那句话,必须得确保我们填的那个目录下有以该文件的UUID为文件名的
.mobileprovision文件。否则会出现错误。

五、配置构建方式(这里我们选择Xcode构建方式)

所需进行的配置项有

《Jenkins(二)自动化打包(iOS)》 配置构建方式所需进行的配置项.png

1、配置构建方式之General build settings选项

①、了解 General build settings 选项需要配置的大概内容,结论是:这里我们需要配置Development Team ID,如果是xcworkspace,还必须在此设置Xcode Schema File。

该选项需要配置的大概内容,如图:

《Jenkins(二)自动化打包(iOS)》 image.png

②、如何获取 Development Team ID ,以用来配置 Code signing & OS X keychain options 选项。

Development Team ID如何获取的方式为可在Keychain找到开发者证书iPhone Distribution: **** (329***),括号内的就是Team ID。举例如下图:

《Jenkins(二)自动化打包(iOS)》 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。如下图:

《Jenkins(二)自动化打包(iOS)》 输入Development Team ID.png

如果未配置则会在构建的时候出现
FATAL: No global development team or local team ID was configured.问题,如图

《Jenkins(二)自动化打包(iOS)》 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选项

《Jenkins(二)自动化打包(iOS)》 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新版本

《Jenkins(二)自动化打包(iOS)》 ia

以下是旧版本的
需要设置的选项有如下图两处,如果未设置,或者设置成下图这样子会造成错误

《Jenkins(二)自动化打包(iOS)》 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因多填写了个后缀名而造成了找不到文件的错误

《Jenkins(二)自动化打包(iOS)》 使用用cocoapods时候,Workspace File因多填写了个后缀名而造成了找不到文件的错误.png

Xcode Workspace File的正确填写
这里Xcode Workspace File 填写就不多说了,填的是xcworkspace文件所在的目录,所以这里去掉后缀名即可,
即最后为$WORKSPACE/CJUIKitDemo/CJUIKit

②、配置Xcode Schema File

上图的错误2:使用用cocoapods时候,Schema File未填写而造成的错误

《Jenkins(二)自动化打包(iOS)》 使用用cocoapods时候,Schema File未填写而造成的错误.png

Xcode Schema File的正确填写
Xcode Schema File的填写一般也为项目名,具体可自己查看Schema。

Xcode Schema File 填写了,但填写错误的常见情况
如果发现补充填写完后,还是有问题,如发现有如下问题,如图:

《Jenkins(二)自动化打包(iOS)》 40348F8F-C546-46F8-90C5-6CB8F069B2F6.png

即错误为
xcodebuild: error: The workspace named "CJUIKitDemo" does not contain a scheme named "CJUIKitDemo".这是因为没找到指定scheme引起。工程代码提交时,未将.xcodeproj中的xcschemes提交。

解决办法:将Manage Scheme后面工程的分享框勾上即可。

《Jenkins(二)自动化打包(iOS)》 5209490F-E95E-403B-AFCE-2C47420C28D3.png

勾选Shared后,在.xcodeproj中就会产生xcshareddata目录

《Jenkins(二)自动化打包(iOS)》 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目录存放编译的输出内容,如图:

《Jenkins(二)自动化打包(iOS)》 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?,该选项按默认即可。

《Jenkins(二)自动化打包(iOS)》 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] 《Jenkins(二)自动化打包(iOS)》 /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'

《Jenkins(二)自动化打包(iOS)》 0CB98B45-021E-45CF-B692-40E479BE6331.png

其他参考:[iOS 通过Jenkins 自动构建ipa]
搭建iOS自动化打包平台(利用Jenkins持续集成iOS项目)
学会使用 Jenkins 搭建 iOS 持续集成环境
Jenkins

七、常见问题参考

Jenkins整合XCode详解
Jenkins问题

    原文作者:dvlproad
    原文地址: https://www.jianshu.com/p/70e4335b0bd6
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞