iOS 持续集成打包脚本

我是一名测试,所以编码能力有限,在大家看代码的过程中,若发现问题或者建议请及时指出,或者直接在 GitHub 提交代码
写此文档的初衷,因为两年前就写过 iOS 打包脚本,后来去做提升效能的测试工具的开发,就不在关注前端的知识了,现在
又要测试前端的业务,但是之前的打包不能通用,所以自己就重新整理了一套通用的打包脚本与大家分享一下

摘要:本文主要介绍 iOS 打包脚本所必须的配置,及注意事项。脚本中不涉及第三方打包工具,如:fastlane,或者第三方应用分发 平台,如:fir.im。完全是基于 Apple 官方提供的 xcodebuild 编译打包,通过 itms-services 分发应用,以及通过 altoolipa 上传至 iTunes Connecnt

项目

  • 项目名称:iOS-CI-Script
  • 前提:
    • 使用此项目进行持续集成,项目中的证书管理必须采用手动管理的方式
    • 项目须使用 Cocopods 管理第三方模块(如不符合此条,可以自行调整 xcodebuild 打包命令即可
      Tip:此项目主要针对持续集成,如:Jenkins 或 GItLab CI 使用,若想在本地直接运行,需要进行微调
  • 能做什么???
    1. 打包之前修改 APP 名称(CFBundleDisplayName)、版本号(CFBundleShortVersionString)及构建号(CFBundleVersion
    2. 可以结合 Jenkins 选择 Configuration 的打包类型,选择你需要构建的类型,如:DebugEnterpriseRelease 等等
    3. 结合 Jenkins 或 GitLab CI 实现应用分发,无需依赖第三方平台
    4. 结合 Jenkins 或 GitLab CI 将 ipa 自动上传 iTunes Connect,并发布 TestFlight 内测
      Tip:无论各位所在的公司中有多少个开发项目或者马甲包,使用此脚本,只需一个配置文件即可轻松搞定持续集成哦

运行环境

  • Python 3.5 及以上(Mac 安装:brew install python3
  • xcodebuild
  • xcpretty(安装方式:gem install xcprettyRubyGems 安装请点击链接,这里就不再赘述)
    Tip:脚本运行所需第三方模块,见项目根目录下的 Pipfile 文件内容

运行方式

python3 ci.py

目录结构

├── Pipfile  // pipenv 安装依赖库的配置文件
├── README.md  // 使用说明文件
├── ci.py  // 入口文件
├── modify_plist.py  // 修改项目中的 APP 配置文件,及脚本中打包依赖的 plist 文件
├── compile.py  // xcodebuild 打包相关的配置,包含:clean、archive、export ipa、zip dSYM
├── archive.py  // 处理 Jenkins 归档的相关操作,详情请看代码注释
├── configurations  // 此目录存放 app 的配置信息文件(支持多个 APP 打包配置文件,在 `Jenkins + iOS 持续集成配置` 会进行持续集成配置讲解),详情请看下面文件的介绍信息
│   └── example.plist  // 配置文件模板
├── libs  // 此目录存在一些工具里及环境变量文件
│   ├── __init__.py
│   ├── configuration.py  // 初始化配置类
│   ├── env_enum.py  // 存在环境变量文件
│   ├── html_tools.py  // html 解析类(目前暂未使用)
│   ├── make_qr_code.py  // 生成二维码函数
│   └── plist_operation.py  // 操作 plist 工具类
├── plist  // 存在 exportOption 配置文件
│   ├── ad-hoc.plist
│   ├── app-store.plist
│   ├── development.plist
│   ├── enterprise.plist
│   └── itms-services.plist  // 此文件的作用是分发应用,与打包无关
└── static  // 存放静态资源文件
    ├── html  // 存放 html web 静态页面的目录,在 `Jenkins + iOS 持续集成配置` 这篇中会进行演示
    └── icon  // 存在 app icon 的目录

使用说明

基础参数配置

# 编辑 `lib` 目录下的 `env_num` 变量文件
# 需手动更改的参数(选择默认也可以)
DIST_CONFIGURATION_NAME = 'Release'
ARCHIVE_DIR_NAME = 'Products'
SCRIPT_DIR_NAME = 'scripts'
WORKSPACE_URL = f'{BUILD_URL}execution/node/3/ws/'
  • 变量说明
    • DIST_CONFIGURATION_NAME:项目中配置发布证书的 configuration 的名称
    • ARCHIVE_DIR_NAME:Jenkins 配置归档的目录名称,此目录是被创建在代码的根目录
    • SCRIPT_DIR_NAME:存在脚本项目的目录名称,也是在项目的根目录下
    • WORKSPACE_URL:此 URL 是通过 Jenkins 的 Web 页面上访问的 WORKSPACE 的 URL(必须修改)

iTunes Connect 参数配置

# 编辑 `lib` 目录下的 `env_num` 变量文件
# iTunes Connect 配置
UPLOAD_ITUNES_CONNECT = os.getenv('UPLOAD_ITUNES_CONNECT', 'false') 
ITC_USER = os.getenv('ITC_USER', None)
ITC_PASSWORD = os.getenv('ITC_PASSWORD', None)
  • 变量说明
    • UPLOAD_ITUNES_CONNECT:上传 iTunes Connect(发布 TestFlight 内测),默认 false 不上传
    • ITC_USER:开发者账号用户名
    • ITC_PASSWORD:开发者账号密码(若 Apple 账号已开启双重认证,请生成并使用专用密码
      注:为了安全起见,不建议将开发者账号的用户名和密码写死在脚本或则环境系统的环境变量中,个人建议写在 Jenkins 的 JOB 中,针对此 JOB 做权限控制即可

APP 配置文件参数讲解

example.plist
  • 配置文件参数说明
    • appName:应用名称
    • workspace:app workspace(注:如果无 workspace,就需要修改 compile.py 文件的中打包命令,针对目前大部分项目都是用 Cocopods 管理依赖库的,所以目前未对未使用 workspace 的项目兼容
    • scheme:scheme (嗯.....不好描述,如果对 workspacescheme 不理解的,请点击 这里
      • 注:在项目中必须将此 scheme 设置为 shared
    • iconPath:存在 static/icon 目录下的 icon
      • icon 规格:推荐 128 * 128 或 144 * 144(大小适中即可
        Tip:这是用于生成二维码时,给中间增加图标用的,如果图片不合法会报错,所以需要让 UE 或者 RD 把这个 icon 给你
    • plistPaths:配置自代码根目录下的 info.plist 文件的相对路径,主要包括:项目及 Extension 中的 info.plist 文件路径(注:和 APP 不相关的 info.plist 无需配置
    • DebugAdHocReleaseEnterprise,这几个都是项目中 Configuration 的名称,由于配置都是一样的,所以就 Debug 进行说明,如下👇
      • method:此参数的值有四种类型:app-store, ad-hoc, enterprise or development 详情请查看 Xcode Archive: export options 此文档
      • teamID:开发者账号的 ID,获取方式:登录开发者账号 → 点击 Team Name → 选择 View Account,然后在页面中找到 Team ID 即可
      • bundleID:就是 APP 的唯一标识,如:com.companyName.porjectName
      • provisioningProfiles:此配置参数是字典类型 key: value
        • key 的值为 bundleID
        • value 的值为 buildID 所对应的描述文件(Provisioning Profile)的名称
          注:项目中涉及到所有的 bundleID 都必须要用 key: value 的形式写在这里,例如:除了项目的 bundleID 和 NotificationServiceExtension(如果 APP 不涉及推送,请忽略) 的 bundleID这两个,可能还有自定义的 ExtensionbundleID

其它

itms-services(了解即可)

通过 itms-services 协议,发布或者分享 iOS 应用程序导读:itms-services 协议常用于 iOS 企业应用的无线部署,这可在不使用 iTunes 的情况下将内部软件发布或者分享给用户。

  • 实现原理
OTA 方式安装,是通过 Safari 解析链接中的 "itms-services://" 来实现的。
例如:
<a title="iPhone" href="itms-services://?action=download-manifest&url=https://github.com/NAISI-ZC/iOS-CI-Script/blob/master/plist/itms-services.plist">
  安装应用
</a>
Safari 会去读取 itms-services.plist 中的信息,如:iOS 应用的名称、版本、安装地址等。
什么是 OTA???
OTA 即 Over-the-Air,是 Apple 在  iOS 4 中新加的一项技术,目的是让开发者能够脱离 Appstore,实现从自己的服务器下载并安装 iOS 应用。
简单地说,就是用户只需要在 Safari 中点开一条链接,就能直接在主界面中安装 APP
  • 注意事项
    1. itms-services 协议拼接的 URL 必须是 HTTPS 服务
    2. HTTPS 无须暴露在公网下,只要保证是可信的证书即可(自签名证书生成,个人没做过,所以不做断言。个人觉得关于证书问题直接找运维解决就可以了

配置持续集成请查看 Jenkins + iOS 持续集成配置

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

推荐阅读更多精彩内容