前言
开发一段时间,每次在测试上线阶段,你会发现有一种酸楚感,因为你即将开始一项没有任何技术含量的build,archive,export的过程,这时候是最累的时候,如果你们的测试很敬业,给你一点点的提bug,那么你将面临的一次接一次的build,archive,export的过程,还有上传第三方分发平台,这个酸爽感😁。。。。有人说不用啊,直接插我电脑上给装一下就行了,而且现在Xcode还有无线调试了,都不用到我跟前来了,直接给安装了。当然小团队开发这种模式肯定是没任何毛病的,但当你公司有好几个测试,一个个让你给安装最新版本,是不是还是挺烦的!而且你可能还有这样一个困窘,当测试给你提多个bug 的时候,你改着改着等你上线的时候,你还担心这个提交的包到底是不是最新的版本打的包,心里多少有点害怕出错,这时候这篇文章可以解决你所有的担心以及减轻你所有的工作量,如果你说这个情况也不存在,那你可以关闭这个网页寻找你感兴趣的文章了。
正文
要彻底明白这个打包的过程我们还需要了解以下几个概念
官方文档中对这个有明确的解释
Xcode Workspace:一个工作空间包括多个projects
A workspace is an Xcode document that groups projects and other documents so you can work on them together.
A workspace can contain any number of Xcode projects, plus any other files you want to include.
In addition to organizing all the files in each Xcode project, a workspace provides implicit and explicit relationships among the included projects and their targets.
Xcode Target:多个Target可以组成一个project,说白了就是一个依赖
A target specifies a product to build and contains the instructions for building the product from a set of files in a project or workspace.
A target defines a single product; it organizes the inputs into the build system—the source files and instructions for processing those source files—required to build that product.
Projects can contain one or more targets, each of which produces one product.
Xcode Project:一个project就是一个项目,可以包含多个targets,而通过 build settings来定义如何build.
An Xcode project is a repository for all the files, resources, and information required to build one or more software products.
A project contains all the elements used to build your products and maintains the relationships between those elements.
It contains one or more targets, which specify how to build products.
A project defines default build settings for all the targets in the project (each target can also specify its own build settings, which override the project build settings).
Xcode Scheme:scheme是来定义一系列targets来build
一个scheme只能应用于一个workspace。
An Xcode scheme defines a collection of targets to build, a configuration to use when building, and a collection of tests to execute.
You can have as many schemes as you want, but only one can be active at a time.
You can specify whether a scheme should be stored in a project—in which case it’s available in every workspace that includes that project, or in the workspace—in which case it’s available only in that workspace.
When you select an active scheme, you also select a run destination (that is, the architecture of the hardware for which the products are built).
Workspace:简单来说,Workspace就是一个容器,在该容器中可以存放多个你创建的Xcode Project, 以及其他的项目中需要使用到的文件。使用Workspace的好处有,1),扩展项目的可视域,即可以在多个项目之间跳转,重构,一个项目可以使用另一个项目的输出。Workspace会负责各个Project之间提供各种相互依赖的关系;2),多个项目之间共享Build目录。
Project:指一个项目,该项目会负责管理生成一个或者多个软件产品的全部文件和配置,一个Project可以包含多个Target。
Target:一个Target是指在一个Project中构建的一个产品,它包含了构建该产品的所有文件,以及如何构建该产品的配置。
Scheme:一个定义好构建过程的Target成为一个Scheme。可在Scheme中定义的Target的构建过程有 Build/Run/Test/Profile/Analyze/Archive
BuildSetting:配置产品的Build设置,比方说,使用哪个Architectures?使用哪个版本的SDK?。在Xcode Project中,有Project级别的Build Setting,也有Target级别的Build Setting。Build一个产品时一定是针对某个Target的,因此,XCode中总是优先选择Target的Build Setting,如果Target没有配置,则会使用Project的Build Setting。
2.build -> archive -> export 到底干了什么
平时开发中我们很轻易的点击了 command + B 执行了一次build的过程 ,其实对Xcode 来发你给他下发了一条指令,我们可以将编译过后的右红变黑的 项目名.app
点击
Show in Finder 会发现build 文件夹下产生的一系列的文件,你会发现多个tagets 被加载进来,并生成了一个 项目名.app
的包,这转换为为指令如下:
xcodebuild
我们 可以在终端执行该条命令对项目进行build,该指令还可以生成项目名.xcarchive
文件,对应为我们执行选择真机点击archive过程,对应指令如下
WORKSPACENAME :工作区名字
SCHEMENAME : scheme名字
CONFIGURATION : release 或者 Debug
ARCHIVEPATH :文件输入路径, 一般为cd 路径下拼接地址
\ : 拼接符号
- archive
xcodebuild archive \
-workspace ${WORKSPACENAME}.xcworkspace \
-scheme ${SCHEMENAME} \
-configuration ${CONFIGURATION} \
-archivePath ${ARCHIVEPATH}
看到以上命令我们应该就豁然了,例如给应用商店上传我们指定Release,在Xcode 8以前还需要指定描述文件以及开发者,也就是发布的描述文件,8以后都自动管理了,所以会自己去读取,不需要我们去指定了.
最后一步便是生成 export
看到这个界面大家更应该明白了export,对应指令如下:
xcodebuild -exportArchive \
-archivePath ${ARCHIVEPATH}.xcarchive \
-exportPath ${IPAPATH} \
-exportOptionsPlist ExportOptions.plist \
需要明确以下几点:
1.Xcode 8 以后使用以上新命令,xcrun指令被废弃了!
2.这里ARCHIVEPATH 对应的.xcarchive
文件的输出路径,IPAPATH是ipa 输出地址
3.ExportOptions.plist对应的已怎样的方式输出,相当于一个配置文件,我们需要以什么样的方式输出.ipa
。
对应的是以下我们手动打包的方式:
以上生成.ipa
的流程我们应该明了于心了,接下来我们用shell脚本将整个流程自动化。
shell 脚本
#!/bin/bash
#workspaceName
WORKSPACENAME='xxx'
#schemeName 可以在工程根目录下使用 xcodebuild -list 命令查看schemes
SCHEMENAME= 'xxxx'
#(Release or Debug)
CONFIGURATION='xxxxxx '
#获取时间,这个格式可以自己定义
DATE=`date +%Y%m%d_%H%M`
#源工程的地址,默认获取cd 路径下的地址
SOURCEPATH=$( cd "$( dirname $0 )" && pwd)
#archieve 输出地址,这个路径可以你自己定义
ARCHIVEPATH=${SOURCEPATH}/AutoBuildIPA/${BRANCHNAME}/${DATE}
#ipa 包输出地址,这个路径也可以你自己定义
IPAPATH=${SOURCEPATH}/AutoBuildIPA/${BRANCHNAME}/${SCHEMENAME}_${DATE}
#ipa 包名
IPANAME=${SCHEMENAME}.ipa
echo "~~~~~~~~~~~~~~~~开始清理~~~~~~~~~~~~~~~~~~~"
# 清理 避免出现一些莫名的错误
xcodebuild clean \
-workspace ${WORKSPACENAME}.xcworkspace \
-configuration ${CONFIGURATION} \
-scheme ${SCHEMENAME}
echo "~~~~~~~~~~~~~~~~开始构建archive~~~~~~~~~~~~~~~~~~~"
# build xxx
xcodebuild archive \
-workspace ${WORKSPACENAME}.xcworkspace \
-scheme ${SCHEMENAME} \
-configuration ${CONFIGURATION} \
-archivePath ${ARCHIVEPATH}
#判断 'xx.xcarchive' 文件存在,即 build 成功
if [ -e ${ARCHIVEPATH}.xcarchive ]; then
echo "xcodebuild Successful"
else
echo "erro:Build failed!!"
exit 1 #退出命令执行
fi
echo "~~~~~~~~~~~~~~~~开始输出ipa~~~~~~~~~~~~~~~~~~~"
# xcrun xxx
xcodebuild -exportArchive \
-archivePath ${ARCHIVEPATH}.xcarchive \
-exportPath ${IPAPATH} \
-exportOptionsPlist ExportOptions.plist \
# 如果 xx.ipa 存在则输出成功
if [ -e ${IPAPATH}/${IPANAME} ]; then
echo "\n-------------------------\n\n\n"
echo "Configurations! Build Successful!"
echo "\n\n\n-------------------------\n\n"
else
echo "\n---------------------------------------------------------------\n"
echo "erro:Create IPA failed!!"
echo "\nPlease check the case of failure and contact developers,thanks!"
echo "Export Error Path : ${IPAPATH}/${IPANAME}"
echo "\n---------------------------------------------------------------\n"
exit 1
fi
以上是便是脚本文件,直接将脚本放在项目工程同级目录下,在终端执行 sh xxxx.sh(注:xxxx为脚本文件名)
,和python 脚本执行是一样的,接下来等待即可输出ipa包。(注:大多出错就是路径定义有问题,检查路径正确性即可排除问题)
接下来我们需要上传蒲公英,我们可以查看官网文档,发现很简单的执行步骤
我们可以在上述shell脚本中将这条命令添加上去
# 是否上传蒲公英
UPLOADPGYER=false
#上传ipa到蒲公英
if [ $UPLOADPGYER = true ]
then
echo "~~~~~~~~~~~~~~~~上传ipa到蒲公英~~~~~~~~~~~~~~~~~~~"
#installType 是安装类型
#password 是你设置的安装密码
# 上面两个新增字段可以具体查看官方文档
curl -F "file=@${IPAPATH}/${IPANAME}" \
-F "uKey=xxxx" \
-F "_api_key=xxxx" \
-F "installType=2" \
-F "password=1" \
https://www.pgyer.com/apiv1/app/upload --verbose
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~上传蒲公英成功~~~~~~~~~~~~~~~~~~~"
else
echo "~~~~~~~~~~~~~~~~上传蒲公英失败~~~~~~~~~~~~~~~~~~~"
echo "${IPAPATH}/${IPANAME}"
fi
fi
fi
那么上传 Appstore 也是相应的套路,苹果官方提供了我们类似的方法,我们需要利用终端安装
//安装 xctool
brew install xctool
//查看版本
xctool -version
同样我们可以将上传Appstore 添加到对应的shell 脚本中
# 是否上传到APPStore
UPLOADAPPStore=false
#对应appid
AppleID='xxx'
#pwd
AppleIDPWD='xxx'
# 上传AppStore
#首先是验证过程,看你appstore 对应的信息是否正确
if [ $UPLOADAPPStore = true ]
then
altoolPath="/Applications/Xcode.app/Contents/Applications/Application\ Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/altool"
${altoolPath} --validate-app \
-f ${IPAPATH}/${IPANAME} \
-u ${AppleID} \
-p ${AppleIDPWD} \
-t ios --output-format xml
#验证成功后直接上传
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~验证ipa成功~~~~~~~~~~~~~~~~~~~"
${altoolPath} --upload-app \
-f ${IPAPATH}/${IPANAME} \
-u ${AppleID} \
-p ${AppleIDPWD} \
-t ios --output-format xml
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~"
else
echo "~~~~~~~~~~~~~~~~提交AppStore失败~~~~~~~~~~~~~~~~~~~"
fi
else
echo "~~~~~~~~~~~~~~~~验证ipa失败~~~~~~~~~~~~~~~~~~~"
fi
以上整个自动化过程已经完成了,接下来我们看本地jenkins 搭建,首先安装
brew install jenkins
安装完成等待 install,可以在终端使用
jenkins
来启动jenkins,然后在浏览器输入框输入
http://localhost:8080
打开Jenkins,我们然后新建项目(注:以上详细安装过程,以及plugin缺失问题,都可以通过百度,google方式解决,我们说具体操作)
第一步:新建项目
第二步:设置相关的配置
2.1 填写项目相关信息
2.2仓库地址需要填写到项目的根路径那一级为止
svn 和 git 是一样的设置。
2.3 在增加构建步骤中选择Xcode
2.4签名设置,填写钥匙串的路径,通过该路径Jenkins可以找到打包证书
2.5高级设置,Scheme同shell脚本填写是一致的
2.6上传蒲公英或者App Store
App Store 参照脚本命令执行。
附:当提交新代码时候设置自动打包
完成以上配置,点击保存后,点击立即构建则会输出同shell 脚本同样的结果。
参照Jenkins 文章:
[0]http://blog.csdn.net/yaoliangjun306/article/details/72471429
相应配置文件的github地址
https://github.com/markdashi/shellIPA
将 package.sh 和 ExportOptions.plist 导入同级目录下,设置好相应参数,执行脚本即可。
2020-8-27 更新
Xcode更新11之后,不再包含Application Loader。为了更好的支持ipadOS、macOS、iOS统一管理。
所以上传AppStore的命令发生了变化
如果账号没有开启双步验证,可以通过
-u -p
账号密码上传验证,如果开启了,需要采取密钥上传
# 上传AppStore
#首先是验证过程,看你appstore 对应的信息是否正确
if [ $UPLOADAPPStore = true ]
then
xcrun altool --validate-app \
-f ${IPAPATH}/${IPANAME} \
-apiKey ${apiKey} \
-apiIssuer ${apiIssuer} \
-t ios --output-format xml --verbose
fi
#验证成功后直接上传
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~验证ipa成功~~~~~~~~~~~~~~~~~~~"
xcrun altool --upload-app \
-f ${IPAPATH}/${IPANAME} \
-apiKey ${apiKey} \
-apiIssuer ${apiIssuer} \
-t ios --output-format xml --verbose
if [ $? = 0 ]
then
echo "~~~~~~~~~~~~~~~~提交AppStore成功~~~~~~~~~~~~~~~~~~~"
else
echo "~~~~~~~~~~~~~~~~提交AppStore失败~~~~~~~~~~~~~~~~~~~"
fi
else
echo "~~~~~~~~~~~~~~~~验证ipa失败~~~~~~~~~~~~~~~~~~~"
fi
apiKey apiIssuer 的获取方式可以参照