ios jenkins配置_Jenkins一:iOS自动打包完整实践

本文详述了在Mac上配置Jenkins进行iOS应用自动打包的全过程,包括使用Homebrew安装Jenkins、解决权限问题、配置Keychain与Provisioning Profiles等,并分享了遇到的各种问题及解决方案,旨在帮助开发者建立稳定的iOS自动化打包流程。
摘要由CSDN通过智能技术生成

后续文章:Jenkins二:参数化构建iOS自动打包

快捷记录:如果jenkins是用dmg安装,因为权限问题不能访问keychain时,每次新添加一个p12文件都要如此,

/Users/管理员用户名/Library/keychains/login.keychain-db

将login.keychain-db复制一份并命名为login.keyain复制到

/Users/Shared/Jenkins/Library/Keychains/login.keychain

同时要在

前言 :

因团队发展涉及到需要把打包工作配置好自动打包后移交给测试团队,网上资料很多,找了几篇文章在我自己的MacBook Pro上跟着一步步安装下来,虽然也遇到几个问题,但很快就找到了解决方案最后成功自动打包成功,于是就在一台专门的打包电脑Mac mini上安装环境,因为都是随机在网上找的资料,结果两次安装环境步骤稍微不一样,第一次是使用homebrew安装的,安装在默认账户下,没遇到什么权限问题,第二次在mac mini上安装使用的是安装包的方式,遇到一系列问题,大部分问题跟权限有关。陆陆续续查找解决构建了200多次,持续了2个周

参考资料:

强烈建议使用homedrew安装会省却很多权限问题,如果用pkg安装包安装,会被权限问题折腾掉半条命

强烈建议二:通过在做Master-Slave配置节点打包时发现使用Tomcat里安装war包的方式安装Jenkins的方式更方便快捷

一、安装jenkins

前提条件:已经安装homedrew、Java

如何在mac上安装java1.8

通过homedrew安装jenkins命令

brew install jenkins

通过homedrew安装后jenkins安装好后所在的位置:

实际安装位置:/usr/local/Cellar/jenkins/

配置文件所在位置:/usr/local/opt/jenkins/

工作空间位置:/Users/用户/.jenkins

进入工作空间位置:cd ~/.jenkins

二、设置开机自启动:

方式一、将启动plist在LaunchAgents创建一个链接镜像(ln是创建一个link的意思)

1.1,创建一个链接到开机启动文件家里

ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents

1.2:手动启动jenkins

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

1.3 手动关闭jenkins

launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.jenkins.plist

1.4 根据需求修改jenkins的启动端口,修改/usr/local/Cellar/jenkins/2.149/homebrew.mxcl.jenkins.plist即可

修改后重新启动可能会报如下错误:

/usr/local/Cellar/jenkins/2.149/homebrew.mxcl.jenkins.plist: Path had bad ownership/permissions

执行以下的两个命令行:

sudo chown root /usr/local/Cellar/jenkins/2.149/homebrew.mxcl.jenkins.plist

sudo chgrp wheel /usr/local/Cellar/jenkins/2.149/homebrew.mxcl.jenkins.plist

方式二(缺点:执行shell的termenal一直在前台运行,不小心关掉了就会停止,有强迫症爱干净的人也不喜欢多一个不能关掉的termenal窗口)

添加一个启动执行的shell文件

2.1:在/usr/local/opt/jenkins创建一个jenkinsBoot.sh文件,内容如下

#!/bin/sh

#默认是8080端口,这里指定为8888端口启动

jenkins --httpPort=8888

2.2:打开系统偏好设置->用户与群组->当前管理员->登录项->+将/usr/local/opt/jenkins/jenkinsBoot.sh加入到这里来

常用默认参数:${WORKSPACE}、${HOME}

查找正在运行的jenkins并关闭:

#查找正在运行的jenkins服务,查看jenkins.war那一行的端口号

ps -ef | grep jenkins

501 82363 22132 0 12:33PM ttys000 0:00.00 grep jenkins

501 926 855 0 Fri06PM ttys002 0:00.00 /bin/sh /usr/local/Cellar/jenkins/2.149/jenkinsBoot.sh

501 xxxx 926 0 Fri06PM ttys002 6:58.53 /usr/bin/java -jar /usr/local/Cellar/jenkins/2.149/libexec/jenkins.war

#关闭jenkins.war那一行的端口号对应的服务

kill -int xxxx

应注意一个读者在配置jenkins环境时,配置keychain时的问题

说明:要jenkins打包iOS的ipa需要苹果系统支持,也就是说安装jenkins的机器是苹果系统或能用jenkins配置一台能访问的苹果系统的电脑作为master机器(本文以默认jenkins所在的机器就是苹果系统)

1、下载发布证书或从开发人员那里拿到导出的发布证书p12

一个苹果证书怎么多次使用——导出p12文件

双击安装证书后,jenkins所在的机器就有发布证书了

login.keychain位置:

/Users/管理员用户名/Library/keychains/login.keychain-db

将login.keychain-db复制一份并命名为login.keyain

描述文件位置:

/Users/管理员用户名/Library/MobileDevice/Provisioning Profiles

(不建议从这里找,因为上传这里的描述文件之后看到的标题也是UUID格式,所以最好单独上传从苹果开发网站下载的描述文件,或者把下面的描述证书拷贝出来改个名再上传)

2、将证书上传到jenkins里

将1中复制的login.keychain上传到这里,如下图所示,

identities:找keychain里这个发布证书的内容

image.png

image.png

#1、切换到jenkins用户下

#[mac终端切换用户](https://blog.csdn.net/doudou19930614/article/details/81410823)

su - Jenkins

#2、创建一个文件夹

mkdir xxx

#3、clone对应的git

git clone xxxxxx

#4、为了不用在每次push到GitHub上时都输入用户名密码

#[mac下git push避免每次都输入用户名和密码的配置](https://www.cnblogs.com/zhaoshunjie/p/6306927.html)

#5、如果有提示需要输入全局的账号和邮箱

# 设置提交代码时的用户信息

git config --global user.name "[name]"

git config --global user.email "[email address]"

#后续其他以jenkins账号操作都正常了

一、使用Jenkins自动打iOS安装包前提条件

1、Mac OS系统(我所使用的是MacBook Pro 和Mac mini)

2、Xcode

3、cocoapods(非必须,如果使用cocoapod管理第三方库才需要)

4、Java

5、sourcetree(git管理工具非必须,我主要用来看代码有没有问题)

6、cornerstone(svn管理工具非必须,我主要用来讲打包的ipa文件上传到SVN上,而不是通常的放到第三方服务器)

7、Jenkins(homebrew安装方式和安装包安装方式两种)

二、使用Jenkins安装包安装方式遇到的问题

1、提示

Failed to connect to repository : Command "git -c core.askpass=true ls-remote -h git@XXXXX:XXXX/XXXX.git HEAD" returned status code 128:

image.png

原因:

由于使用Jenkins安装包安装,不能直接使用http的方式为git地址(why?),需要切换成ssh地址,ssh地址需要配置秘钥

解决办法:

2、提示

Code Signing Error: No certificate for team 'xxxxx' matching 'iPhone Distribution: xxxxx.' found: Select a different signing certificate for CODE_SIGN_IDENTITY, a team that matches your selected certificate, or switch to automatic provisioning.

原因:

由于使用Jenkins安装包安装,在安装时创建了一个新的用户,默认放在钥匙串里的证书Jenkins这个用户访问不了

解决办法:

将钥匙串下的 登录里的相关证书拷贝到 钥匙串下的 系统里面

3、提示

Run custom shell script '[cp] embed pods frameworks ..... errSecInternalComponent.

/usr/bin/codesign --force --sign DC8791E5F036D9BAAFEC8E347093A20EB435BF0F --preserve-metadata=identifier,entitlements '/Users/Shared/Jenkins/Home/workspace/iOSDev/Release-iphoneos/xxx.app/Frameworks/AFNetworking.framework'

/Users/Shared/Jenkins/Home/workspace/iOSDev/Release-iphoneos/xxx.app/Frameworks/AFNetworking.framework: errSecInternalComponent

Command /bin/sh failed with exit code 1

** BUILD FAILED **

The following build commands failed:

PhaseScriptExecution [CP]\ Embed\ Pods\ Frameworks /Users/Shared/Jenkins/Library/Developer/Xcode/DerivedData/Lottery-dubolgbhbwxukkfsjmthrywdixge/Build/Intermediates.noindex/Lottery.build/Release-iphoneos/xxx.build/Script-79402CD10148DF169F37FF35.sh

(1 failure)

Build step '执行 shell' marked build as failure

[OS X] restore keychains as defined in global configuration

[iOSDev] $ /usr/bin/security list-keychains -s /Users/Shared/Jenkins/Library/Keychains/login.keychain

Finished: FAILURE

image.png

原因一:

解决办法:

看到--force --sign的字样猜测还是权限的问题,于是我把拷贝到钥匙串->系统 下的那个证书设置为 始终信任,顺利解决问题

如果还不可以则:

在xcodebuild -workspace .....前添加一行解锁login.keychain的命令

security unlock-keychain -p 个人的账号登录密码 /Users/Shared/Jenkins/Library/Keychains/login.keychain

原因二:

在要用一个新appleID开发者账号创建一个新target时,电脑的login.kechain-db已经重新生成或者说修改了,但之前配置在Jenkins里的还是旧的,所以需要重新将login.keychain-db复制一份并重命名为login.kehchain上传到Jenkins里忘了在Jenkins配置时Keychains and Provisioning Profiles Management->Keychains

,同时将login.keychain-db、login.keychain拷贝到Jenkins的对应目录下,我的目录为:/Users/xxxx/Library/Keychains -> /Users/Shared/Jenkins/Library/Keychains

4、提示

xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH

原因:

新版的Xcode里没有想过的工具库

解决办法:

参考:xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH

顺便由于提示warning: PackageApplication is deprecated, use ``xcodebuild -exportArchive`` instead.,这个根据提示替换修改下就好了

5、提示

Build step '执行 shell' marked build as failure

[OS X] restore keychains as defined in global configuration

原因:

Jenkins用户权限比较低,不能使用login.keychain

解决办法:

在xcodebuild -workspace .....前添加一行解锁login.keychain的命令

security unlock-keychain -p 个人的账号登录密码 /Users/Shared/Jenkins/Library/Keychains/login.keychain

6、提示

=== BUILD TARGET xxxx OF PROJECT Lottery WITH CONFIGURATION Release ===

Check dependencies

Code Signing Error: "xxxx" requires a provisioning profile with the Push Notifications feature. Select a provisioning profile for the "Release" build configuration in the project editor.

Code Signing Error: Code signing is required for product type 'Application' in SDK 'iOS 11.4'

** BUILD FAILED **

原因一:

该target的build setting配置不正确,之前是将Code Signing Identity统一配置成iOS Distribution了,这种方式在xcode里手动点击archive打包时没问题,但使用Jenkins自动打包就出报上面的错

image.png

解决办法:

将报错的这个target的build setting设置为精确的描述证书,比如iPhone Distribution: xxxxx,如下图:

image.png

7、提示

error: Unable to create '/Users/admin/Documents/svn/docs/xxxx.ipa'

原因:

这个路径是为了设置将打包出来的ipa安装包自动放到SVN路径下然后自动上传到SVN服务器,但还是由于打包Jenkins用的是一个独立的用户导致的权限问题

解决办法:

将/Users/admin/Documents/svn/docs/这个路径的每一个文件夹都设置为所有用户有读写权限

花了两个周构建几百次的血的教训,建议还是都用homebrew的方式安装少些权限问题

end

配置的参数:

多个scheme的配置

Debug/Release

git分支和tag选择

参数配置的使用页面

完整构建脚本:

# 工程名

APP_NAME="xxxx"

#***************动态配置部分*********************

# 不勾上自动管理证书

CODE_SIGN_DISTRIBUTION="iPhone Distribution: xxxxx"

# 代码文件夹名称,这是由于源码并不在git项目的根目录下

code_folder="xxxx"

#scheme#Info文件名称#保存ipa文件夹

platformParams=(${iOS_PLATFORM//\#/ })

# schema名称

SCHEMECA=${platformParams[0]}

#info.plist文件名称

INFO_FILENAME=${platformParams[1]}

# 输出到svn的文件夹名称

OUT_SVN_FOLDER=${platformParams[2]}

#*************************************

project_path=""

project_infoplist_path="./${code_folder}/Resource/platforms/${INFO_FILENAME}.plist"

#取版本号

bundleShortVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleShortVersionString" "${project_infoplist_path}")

#取build值

bundleVersion=$(/usr/libexec/PlistBuddy -c "print CFBundleVersion" "${project_infoplist_path}")

#取bundleId

bundleId=$(/usr/libexec/PlistBuddy -c "print CFBundleIdentifier" "${project_infoplist_path}")

DATE="$(date +%Y%m%d-%H%M%S)"

#唯一名称ipa、dsYM文件名

UNIQUE_NAME="${APP_NAME}_${SCHEMECA}_${iOS_Release}_V${bundleShortVersion}_${DATE}"

IPANAME="${UNIQUE_NAME}.ipa"

#根据需求定义输入ipa的文件夹位置

PARENT_FOLDER="$HOME/testJenkins/test/study/${OUT_SVN_FOLDER}"

if [ ! -d $PARENT_FOLDER ];then

mkdir -p $PARENT_FOLDER

else

echo dir exist

fi

#要上传的ipa文件路径

IPA_PATH="$PARENT_FOLDER/${IPANAME}"

echo ${IPA_PATH}

echo "${IPA_PATH}">> text.txt

#下面2行是没有Cocopods的用法

#echo "=================clean================="

#xcodebuild -target "${TARGET_NAME}" -configuration 'Release' clean

#

#echo "+++++++++++++++++build+++++++++++++++++"

#xcodebuild -target "${TARGET_NAME}" -sdk iphoneos -configuration 'Release' CODE_SIGN_IDENTITY="${CODE_SIGN_DISTRIBUTION}" SYMROOT='$(PWD)'

#下面2行是集成有Cocopods的用法

echo "=================clean================="

xcodebuild -workspace "./${code_folder}/${APP_NAME}.xcworkspace" -scheme ${SCHEMECA} -configuration "${iOS_Release}" clean

echo "+++++++++++++++++build+++++++++++++++++"

xcodebuild -workspace "./${code_folder}/${APP_NAME}.xcworkspace" -scheme ${SCHEMECA} -sdk iphoneos -configuration "${iOS_Release}" CODE_SIGN_IDENTITY="${CODE_SIGN_DISTRIBUTION}" SYMROOT='$(PWD)' -allowProvisioningUpdates

xcrun -sdk iphoneos PackageApplication "./${iOS_Release}-iphoneos/${SCHEMECA}.app" -o ${IPA_PATH}

#生成dsYM文件

dsymutil "./${iOS_Release}-iphoneos/${SCHEMECA}.app/${SCHEMECA}" -o "${PARENT_FOLDER}/${UNIQUE_NAME}.app.dSYM"

cd "${PARENT_FOLDER}"

if [ ! -d "${UNIQUE_NAME}.app.dSYM" ];then

echo "没有可以压缩的dsYM文件"

else

#压缩dsYM文件

zip -q -r -m -o "${UNIQUE_NAME}.app.dSYM.zip" "${UNIQUE_NAME}.app.dSYM"

#上传dsYM文件到解析平台

#curl -k "https://api.bugly.qq.com/openapi/file/upload/symbol?app_key=xxxxxx&app_id=xxxxxx" --form "api_version=1" --form "app_id=xxxxxx" --form "app_key=xxxxxx" --form "symbolType=2" --form "bundleId=${bundleId}" --form "productVersion=${bundleShortVersion}" --form "channel=xxx" --form "fileName=${UNIQUE_NAME}.app.dSYM.zip" --form "file=@${UNIQUE_NAME}.app.dSYM.zip" --verbose

fi

# 将生成的ipa上传到SVN

#cd "/Users/tony/Documents/svn/docs/svn/"

#svn upgrade

#svn add ${IPA_PATH}

#svn commit -m "add test" ${IPA_PATH}

三、使用homebrew安装方式遇到的问题

二、遇到问题

FATAL: String index out of range: 15

java.lang.StringIndexOutOfBoundsException: String index out of range: 15

at java.lang.String.substring(String.java:1963)

at com.sic.plugins.kpp.provider.KPPBaseProvisioningProfilesProvider.removeUUIDFromFileName(KPPBaseProvisioningProfilesProvider.java:171)

at com.sic.plugins.kpp.model.KPPProvisioningProfile.getProvisioningProfileFilePath(KPPProvisioningProfile.java:76)

at com.sic.plugins.kpp.KPPProvisioningProfilesBuildWrapper.copyProvisioningProfiles(KPPProvisioningProfilesBuildWrapper.java:157)

at com.sic.plugins.kpp.KPPProvisioningProfilesBuildWrapper.setUp(KPPProvisioningProfilesBuildWrapper.java:99)

at hudson.model.Build

AbstractBuildExecution.run(AbstractBuild.java:504)

at hudson.model.Run.execute(Run.java:1794)

at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:43)

at hudson.model.ResourceController.execute(ResourceController.java:97)

at hudson.model.Executor.run(Executor.java:429)

Finished: FAILURE

这是因为当时没有在Keychains and Provisioning Profiles Management里面上传配置文件导致的,

上传配置文件的方法和上传login.keychain一样,

选择那个配置文件,点击upload,

配置文件存在你电脑的

`/Users/‘电脑用户名称’/Library/MobileDevice/Provisioning Profiles`目录下。

xcrun: error: unable to find utility "PackageApplication", not a developer tool or in PATH

后面根据对比发现新版的Xcode少了这个PackageApplication

先去找个旧版的Xcode里面copy一份过来

放到下面这个目录:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/

然后执行命令

sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer/

再执行

chmod +x /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/PackageApplication

遇到问题

Undefined symbols for architecture arm64:

"_OBJC_CLASS_$_XXXX", referenced from:

objc-class-ref in XXXX.o

ld: symbol(s) not found for architecture arm64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

原因:

当前target没有把XXXX这个文件的.m文件没有勾选到Target MemberShip中

这种问题特别容易出现在一个项目有多个target的时候

如下:

tmp633006ba.png

解决办法:

将提示的文件勾选到Target MemberShip中

问题:

Warning: unable to build chain to self-signed root for signer "iPhone Distribution: "/Users/Shared/Jenkins/Home/workspace/xxx/Release-iphoneos/xxx.app/Frameworks/AFNetworking.framework: errSecInternalComponent

Command /bin/sh failed with exit code 1

** BUILD FAILED **

如果没有这个插件,先安装插件

Jenkins->Jenkins管理->插件管理->可选插件 输入:Keychains and Provisioning Profiles Management,找到这个插件,然后点击直接安装

tmp316b3fcb.png

原因:

忘记把新添加的p12证书对应的Identity添加到Jenkins->系统管理->Keychains and Provisioning Profiles Management->Add code Signing Identity里,

tmp2cbdfdaa.png

点击:选取文件->Upload->保存

依次将Jenkins所在的机器的login.keychain(/Users/管理员用户名/Library/keychains/login.keychain-db 复制一份改名成成login.keychain),

需要管理的描述文件xxx.mobileprovision上传保存

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值