4.通过shell脚本完成iOS打包并上传至蒲公英测试平台

背景:

随着公司业务的扩大,人员的增多,每次通过XCode给测试人员Run代码进行测试,已经满足不了,况且Run出来的程序不能够很好的留下“证据”,所以自动化构建项目是很必要的。
搜集了相关资料,通过OS X Server和Jenkins使用居多,然而小弟愚笨,OS X Server环境已经构建好,但是却未能成功完成目的,Jenkins也一直没有去做,而是退而求次的使用shell编写一个脚本,依靠XCode中的xcodebuild和xcrun来实现代码的打包。

简单说几个常用的xcodebuild命令

可以执行 xcodebuild -help 查看都有哪些

xcodebuild [-project <projectname>] [[-target <targetname>]...|-alltargets] [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild [-project <projectname>] -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...
xcodebuild -version [-sdk [<sdkfullpath>|<sdkname>] [<infoitem>] ]
xcodebuild -list [[-project <projectname>]|[-workspace <workspacename>]] [-json]
xcodebuild -showsdks
xcodebuild -exportArchive -archivePath <xcarchivepath> -exportPath <destinationpath> -exportOptionsPlist <plistpath>
xcodebuild -exportLocalizations -localizationPath <path> -project <projectname> [-exportLanguage <targetlanguage>...]
xcodebuild -importLocalizations -localizationPath <path> -project <projectname>

Options:
    -usage                              print brief usage
    -help                               print complete usage
    -verbose                            provide additional status output
    -license                            show the Xcode and SDK license agreements
    -checkFirstLaunchStatus             Check if any First Launch tasks need to be performed
    -project NAME                       build the project NAME
    -target NAME                        build the target NAME
    -alltargets                         build all targets
    -workspace NAME                     build the workspace NAME
    -scheme NAME                        build the scheme NAME
    -configuration NAME                 use the build configuration NAME for building each target
    -xcconfig PATH                      apply the build settings defined in the file at PATH as overrides
    -arch ARCH                          build each target for the architecture ARCH; this will override architectures defined in the project
    -sdk SDK                            use SDK as the name or path of the base SDK when building the project
    -toolchain NAME                     use the toolchain with identifier or name NAME
    -destination DESTINATIONSPECIFIER   use the destination described by DESTINATIONSPECIFIER (a comma-separated set of key=value pairs describing the destination to use)
    -destination-timeout TIMEOUT        wait for TIMEOUT seconds while searching for the destination device
    -parallelizeTargets                 build independent targets in parallel
    -jobs NUMBER                        specify the maximum number of concurrent build operations
    -dry-run                            do everything except actually running the commands
    -quiet                              do not print any output except for warnings and errors
    -hideShellScriptEnvironment         don't show shell script environment variables in build log
    -showsdks                           display a compact list of the installed SDKs
    -showBuildSettings                  display a list of build settings and values
    -list                               lists the targets and configurations in a project, or the schemes in a workspace
    -find-executable NAME               display the full path to executable NAME in the provided SDK and toolchain
    -find-library NAME                  display the full path to library NAME in the provided SDK and toolchain
    -version                            display the version of Xcode; with -sdk will display info about one or all installed SDKs
    -enableAddressSanitizer YES|NO      turn the address sanitizer on or off
    -enableThreadSanitizer YES|NO       turn the thread sanitizer on or off
    -resultBundlePath PATH              specifies the directory where a result bundle describing what occurred will be placed
    -derivedDataPath PATH               specifies the directory where build products and other derived data will go
    -archivePath PATH                   specifies the directory where any created archives will be placed, or the archive that should be exported
    -exportArchive                      specifies that an archive should be exported
    -exportOptionsPlist PATH            specifies a path to a plist file that configures archive exporting
    -enableCodeCoverage YES|NO          turn code coverage on or off when testing
    -exportPath PATH                    specifies the destination for the product exported from an archive
    -skipUnavailableActions             specifies that scheme actions that cannot be performed should be skipped instead of causing a failure
    -exportLocalizations                exports completed and outstanding project localizations
    -importLocalizations                imports localizations for a project, assuming any necessary localized resources have been created in Xcode
    -localizationPath                   specifies a path to XLIFF localization files
    -exportLanguage                     specifies multiple optional ISO 639-1 languages included in a localization export
    -xctestrun                          specifies a path to a test run specification
    -only-testing:TEST-IDENTIFIER       constrains testing by specifying tests to include, and excluding other tests
    -skip-testing:TEST-IDENTIFIER       constrains testing by specifying tests to exclude, but including other tests
    -json                               output as JSON (note: -json implies -quiet)
1.xcodebuild -list
➜  xxx-ios git:(develop) xcodebuild -list
Information about project "xxx":
    Targets:
        xxx
        xxxTests
        xxxUITests
    Build Configurations:
        Debug
        Release
    If no build configuration is specified and -scheme is not passed then "Release" is used.
    Schemes:
        xxx

通过输出结果可以得出 -list 展示的是 你当前工程的 Targets Schemes 以及可选择的Build Configurations

2.xcodebuild -version
➜  xxx-ios git:(develop) xcodebuild -version
Xcode 8.2.1
Build version 8C1002

Xcode的版本

3.xcodebuild -workspace
xcodebuild -workspace <workspacename> -scheme <schemeName> [-destination <destinationspecifier>]... [-configuration <configurationname>] [-arch <architecture>]... [-sdk [<sdkname>|<sdkpath>]] [-showBuildSettings] [<buildsetting>=<value>]... [<buildaction>]...

这个是build工程所需要命令,包括的参数有scheme configuration等,这些在-list中都可以拿到
当然,xcodebuild不只只这几个命令,还有很多,例如-license -showsdks 等等等等。

我们使用的这句就够了

xcodebuild \
-workspace $SOURCEPATH/$SCHEMENAME.$SUFFIXNAME \
-scheme $SCHEMENAME \
-configuration $CONGRUATION \
clean \
build \
-derivedDataPath $IPAPATH 

这个是复制sh脚本中的内容,后面我会解释含义

Build完事之后就改导出ipa文件,使用的是xcrun命令

同样的先看看 xcrun下都有哪些

➜  xxx-ios git:(develop) xcrun -help
Usage: xcrun [options] <tool name> ... arguments ...
Find and execute the named command line tool from the active developer
directory.
The active developer directory can be set using `xcode-select`, or via the
DEVELOPER_DIR environment variable. See the xcrun and xcode-select manual
pages for more information.

Options:
  -h, --help                  show this help message and exit
  --version                   show the xcrun version
  -v, --verbose               show verbose logging output
  --sdk <sdk name>            find the tool for the given SDK name
  --toolchain <name>          find the tool for the given toolchain
  -l, --log                   show commands to be executed (with --run)
  -f, --find                  only find and print the tool path
  -r, --run                   find and execute the tool (the default behavior)
  -n, --no-cache              do not use the lookup cache
  -k, --kill-cache            invalidate all existing cache entries
  --show-sdk-path             show selected SDK install path
  --show-sdk-version          show selected SDK version
  --show-sdk-build-version    show selected SDK build version
  --show-sdk-platform-path    show selected SDK platform path
  --show-sdk-platform-version show selected SDK platform version

使用的也是一句

#xcrun .ipa
xcrun -sdk iphoneos PackageApplication \
-v $IPAPATH/Build/Products/$CONGRUATION-iphoneos/$SCHEMENAME.app \
-o $IPAPATH/$IPANAME

好了,重要的这两句已经搞定了。接下来就要进行脚本的制作了

我们的代码托管用的是git,针对git主要使用的是 checkout 和 pull 。

git checkout $BRANCHNAME
if [ $? -ne ]; then
    #statements
    exit 1
fi
git pull
if [ $? -ne 0 ]; then
    #statements
    exit 1
fi 

对于git其他命令感兴趣的,自行百度吧。

最后就是往蒲公英托管内测平台提交文件了,这个根据他文档的说明

蒲公英上传App

curl -F "file=@$IPAPATH/$IPANAME" \
-F "uKey=$PGYUSERKEY" \
-F "_api_key=$PGYAPIKEY" \
-F "password=password" \
https://qiniu-storage.pgyer.com/apiv1/app/upload

👌大功告成

最后粘上我的代码

#!/bin/bash
# Author leeway 

# $1工程所在的根路径 
# $2工程打包ipa的路径
# $3分支名字develop OR master
# $4工程的名字一般情况下和scheme一致 app1 app2 app3
# $5启动脚本传入Debug或者Release就可以
PROJECTPATH=$1
PROJECTIPAPATH=$2
BRANCHNAME=$3
SCHEMENAME=$4
CONGRUATION=$5
#我这里假设,有的app用的pods有的没有用
if [[ $SCHEMENAME = app1 ]]; then
    #如果是app1
    SUFFIXNAME=xcworkspace
elif [[ $SCHEMENAME = app2 ]]; then
    #app2
    SUFFIXNAME=xcodeproj
else
    #app3
    SUFFIXNAME=xcworkspace
fi

PGYUSERKEY=716e2e6b24b34d65xxx
PGYAPIKEY=dd5c15cc9e7c7ff2592xxx


DATE=`date +%Y%m%d%H%M`
SOURCEPATH=$( cd $PROJECTPATH && pwd )
IPAPATH=$PROJECTIPAPATH/AutoBuildIPA/$BRANCHNAME/$DATE
IPANAME=$SCHEMENAME$DATE.ipa

git checkout $BRANCHNAME
if [ $? -ne ]; then
    #statements
    exit 1
fi

git pull
if [ $? -ne 0 ]; then
    #statements
    exit 1
fi

# delete trash files
if [ -e $IPAPATH/* ]; then
    #statements
    mv $IPAPATH/* ~/.trash
    if [ $? -ne 0 ]; then
        #statements
        echo "error:delete trash files failed!"
        exit 1
    fi
fi


# xcodebuild .app
xcodebuild \
-workspace $SOURCEPATH/$SCHEMENAME.$SUFFIXNAME \
-scheme $SCHEMENAME \
-configuration $CONGRUATION \
clean \
build \
-derivedDataPath $IPAPATH 

if [ -e $IPAPATH ]; then
    #statements
    echo "xcodebuild Successful!!!"
else
    echo "error: Build failed!!!"
fi

#xcrun .ipa
xcrun -sdk iphoneos PackageApplication \
-v $IPAPATH/Build/Products/$CONGRUATION-iphoneos/$SCHEMENAME.app \
-o $IPAPATH/$IPANAME

if [ -e $IPAPATH/$IPANAME ]; then
    #statements
    echo "\n--------------------------------------------\n\n\n"
    echo "leeway tell you: Configurations! Build Successful!"
    echo "\n\n\n-------------------------------------------\n\n"
    echo "Current Branch log:"
else
    echo "\n-------------------------------------------------\n"
    echo "leeway tell you: error:Create IPA failed!!"
    echo "\nPlease check the cause of failure and contact leeway"
    echo "\n-------------------------------------------------\n"

fi

#自动上传到蒲公英
curl -F "file=@$IPAPATH/$IPANAME" \
-F "uKey=$PGYUSERKEY" \
-F "_api_key=$PGYAPIKEY" \
-F "password=xxxxxxx" \
https://qiniu-storage.pgyer.com/apiv1/app/upload
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容