正在加载今日诗词....
12 min read

iOS自动化打包分发

iOS持续集成
iOS自动化打包分发

为什么要自动化

  • 节省时间,快速迭代: 减少重复繁琐的过程,本地继续编码,使用工具自动拉取远程库代码后打包
  • 纠错: 打包出错,会自动查找到编译错误
  • 快速分发多个版本: 配置好不同分支的打包策略,可以将打包任务移交测试,分工更明确

工具

  • Jenkins CI
  • Flow CI
  • Travis CI
  • Hudson CI
  • Circle CI

本文只关注 Jenkins 的使用

Jenkins 的三种安装方式

  • war
  • pkg
  • homebrew

推荐使用 homebrew

jenkins 安装

1、正确安装Homebrew的方式
2、安装: brew install jenkins
3、终端启动命令: jenkins
4、浏览器访问jenkins地址: http://localhost:8080/ , 如果不能正常访问,要么Java环境出问题,要么jenkins没有启动; Java环境的去官网下载最新的jdk安装;jenkins开关命令
5、 正常的浏览器启动页面是如下的

unlock-jenkins-4339b810-93b4-4f1d-ae46-e6bdf83c539f-1535512255668-60783653

根据提示修改文件夹权限,获取密钥,登录jenkins
6、安装插件 ,Jenkins功能很多以来相应的插件,简化了接入的难度

最好先跳过这一步,因为电脑环境问题,有些插件是需要翻墙安装,所以导致jenkins安装插件的时候,会卡在一个地方,然后就一直卡着,我安装过多次jenkins,因为这个问题,我习惯于跳过插件安装,先登录配置好环境,然后再手动安装插件!!!!!!!!!

custom-jenkins-462a8741-f81c-4968-954f-1efcc8c4028c-1535512288319-02089846

如果出现一只卡死在安装插件的界面,关机重启,重新启动Jenkins后,登录http://localhost:8080 进入管理员注册页面
7、 管理员注册
要牢记这个名称,如果是自己测试用,直接用 admin admin 这种更简单的组合.

create-jenkins-admin-2f9411a6-8eb4-4b7e-9254-9d0465569ccb-1535518855745-25755904

8、 进入首页,首先将需要安装的插件 再次补充全

fix-jenkins-plugins-13cc4f71-47e0-4c8c-8010-52eb96cea89f-1535518889278-14113452

需要的插件如下

  • Git , Gitlab,SVN , SSH Credentials用于授权后拉取远程库的代码
  • Keychains and Provisioning Profiles Management: 证书与描述文件的管理
  • Xcode integration Xcode打包的插件,所以iOS的打包只能部署在Mac系统
  • Cocoapods 如果项目使用了cocoapod插件 来获取依赖库
  • Mailer Plugin 用来发送通知邮件
  • fir-plugin 用来将ipa包分发到 fir.im上面,或者使用蒲公英(只能是脚本)也可以
  • Post-Build Script Plug-in 脚本插件

9、配置项目的访问ssh私钥
jenkins-configuration-c3d81447-b4ed-444e-ac55-19dfdaf23d54-1535518921202-02315491
根据图上的路径
jenkins-ssh-c4a53fd9-adc0-4ea3-802a-a6e7c11a9801-1535518949753-31156101

添加SSH的私钥, 一般你项目的访问私钥是 ~/.ssh/id_rsa 这个文件,如果没有配置,则询问你的源代码的管理员
jenkins-ssh-key-54d28ce1-aa28-4832-8399-959d9b984cf5-1535518975904-22711775
如果私钥是错误的,则配置项目的时候会出现下面👇的错误

jenkins-git-ssh-5750e735-0305-4f4f-b8e0-db7f25157470-1535518992338-72173597
所以务必要明白,项目的私钥是如何配置的. 需不需要口令码!!!
如果是公司项目,询问运维,当然一般运维会搭建jenkins(iOS必须要在Mac电脑上面搭建,如果是给JAVA使用,一般用linux,不能打包iOS).
自己的项目,不论是在Coding,Github,Gitlab 都可以在页面上查找对应的SSH添加,以明确将要在jenkins使用的ssh私钥是什么

10、配置项目依赖的证书与描述文件

jenkins-login-key-5d415016-1ffb-47cf-9d0a-674e2d491a83-1535519066120-87152609

进入后的界面是
jenkins-ios-keychains-01ebd844-6559-4c89-a1cf-5cb1dbb0a121-1535519080790-00065765
主要有两个步骤,
①是 上传钥匙串的 login.keychain , mac地址~/Library/Keychains/

login-keychains-location-bff6ede9-44ae-49e6-bc0a-8bbf32b3c993-1535519111963-32438767

② 设置参数
login-keychains-password-f66027f7-f238-40c8-8be6-eabfc35fc19d-1535519131033-76470196

注意 证书的名称就是本机钥匙串,安装后的证书简介的 常用名称

ios-p12-name-8a5e8fcb-aa03-47b8-a64b-c7d817edd648-1535519157179-12580762
描述文件的地址 一般是 ~/Library/MobileDevice/Provisioning Profiles
不过我多次尝试 发现配置项目的时候 并没有得到描述文件,后面只能用脚本自己打包的

11、创建新的项目
jenkins-new-job-d90f8eca-7577-408e-ade6-9df519493c90-1535519175380-35068245
选择项目的类型

jenkins-new-job-setting-d05520f7-764a-4f1c-bf16-186c35f9eb1e-1535519192857-69129684

进入项目的配置页面

jenkins-job-config-0913685e-568d-4b6b-beb8-022609b5235e-1535519208946-80768467

jenkins-item-config-6496069c-7d2a-467d-a236-228ec4a53a54-1535519224271-50104761

丢弃旧的构建 ,可以自己定义策略

jenkins-build-settings-ce37a23d-5251-4d62-8c15-27fe534d82cb-1535519889768-91369479

设置 源码的 拉取, 这一步 主要是可能卡在 私钥的配置上面,所以一定要明确SSH的配置(见上面的说明)

jenkins-job-git-config-d70ec19e-ebb5-4b8a-8563-cf8e67ea7ba0-1535519970248-96686472

构建触发器 , 这里主要是 定时去 自动化打包项目

jenkins-job-build-time-0633b3bc-46c1-403e-8c59-8befe80d6247-1535519970923-10898736

构建环境, 主要配置的是 证书与描述文件

jenkins-keychains-codesign-19900646-14c4-4566-ae9c-0e50a0d01296-1535519978523-67833556

下面是正确的环境链接在此,我不知道是不是xcode8之后才有的这问题,还是我使用homebrew确实获取不到.

jenkins-build-job-setting-config-3ee044af-ae30-4735-8483-c595c34e5885-1535519890935-92077824

Xcode的配置

jenkins-codesign-keychains-78c8752a-d645-412b-854f-a0e5cb282575-1535519921907-12153956

具体配置

jenkins-ios-job-general-settings-d65f0484-16e4-4857-9c4d-e8197c1ecddc-1535519948611-85415073

钥匙串 选择配置好的钥匙串

jenkins-keychain-ios-76d9813c-a99d-49cd-af8c-e88c724a1282-1535519977491-40711112

其他的编译打包参数 , 如果使用了cocoapods还需要指定具体的一些参数,并且执行脚本,拉取依赖的远程库

jenkins-ios-archive-config-cd99909b-7ab7-4fa8-93b5-db63aa38051b-1535519941955-29553479

最最重要的来了,打包的脚本

jenkins-job-shell-b09a844d-6d45-4457-b85d-8acb9808f53e-1535519972693-27035723

如果使用了 cocoapods 则需要提供拉取依赖库的代码 否则请忽略这一步(比如我们叮叮暂时没有)
分别是 指定这是一个脚本(截图有问题,应该是#bin/bash -l), podfile文件的 中文格式编码, 切换到podfile的路径下,拉取依赖的pod
jenkins-ios-job-build-shell-5bff6db3-4911-4ea6-861d-5c7c0684b82d-1535519943670-23240935

jenkins-job-ios-shell-6d1dbadf-1723-4c7f-979c-a32cb630076b-1535520472464-06581058
具体的代码如下

脚本① 样本 xcodebuild -workspace "demo.xcworkspace" -sdk iphoneos -scheme "targetName" -configuration 'Release Adhoc' CODE_SIGN_IDENTITY="keychain中证书代号名称" SYMROOT='$(PWD) 这里 -workspace "demo.xcworkspace"是使用cocoapods的样本, 没有使用就像下面的 -project "project的路径"

if [ -d "${WORKSPACE}/builds" ]; then rm -rf ${WORKSPACE}/builds; fi;
mkdir ${WORKSPACE}/builds;
if [ -d "${WORKSPACE}/builds/${BUILD_NUMBER}" ]; then rm -rf ${WORKSPACE}/builds/${BUILD_NUMBER}; fi;
mkdir ${WORKSPACE}/builds/${BUILD_NUMBER};
xcodebuild -project ${WORKSPACE}/ProjectName/ProjectName.xcodeproj 
-scheme "ProjectName" 
-sdk iphoneos 
archive -archivePath ${WORKSPACE}/builds/${BUILD_NUMBER}/archive 
CODE_SIGN_IDENTITY="iPhone Developer: xxxx"

注意 scheme 一定还要勾选 分享

ios-scheme-53fefed6-775e-4078-940f-76e5f12c1211-1535519883530-17213699

jenkins-ios-archive-share-c4f04eee-c4c3-4c63-8b8b-1dd6abbeafce-1535519941976-55544545

并且注意 不同的打包method 要对应好.

脚本② xcodebuild官方文档

xcodebuild -exportArchive 
-archivePath ${WORKSPACE}/builds/${BUILD_NUMBER}/archive.xcarchive 
-exportOptionsPlist ${WORKSPACE}/ProjectName/ProjectName/ExportOptions_development.plist 
-exportPath ${WORKSPACE}/builds/${BUILD_NUMBER}/${JOB_NAME}_${BUILD_NUMBER}.ipa 
PROVISIONING_PROFILE="iPhone Developer: xxxx"

这里有一个注意点 就是 exportOptionsPlist ,需要自己在项目中配置 相应的信息

jenkins-ios-exportplist-3ea42c96-8e35-4fd9-9ac3-810e0995f375-1535519942747-49702137

一切顺利就可以正常打包了
后面就是打包后 上传到 fir.im或者是蒲公英 给测试团队 .

jenkins-fir.im-0c2f7981-717e-4010-a652-d7a1a4a6769a-1535519922765-68614233

还有就是 邮件通知

jenkins-email-406292f4-a7e3-4c71-9156-76e377fa53e5-1535519921745-72367286

12、 正常使用

jenkins-build-1bae8d05-0a4c-4993-9819-ea2548e5fb1f-1535519896645-30861782

点击进入控制台输出,查看运行的细节

jenkins-log-b6f6bc62-ab20-4952-aadc-185471bdd96d-1535519996202-77777874

团队的使用

1、 设置一个 局域网的固定访问地址

jenkins-url-4c68c517-249a-496f-b60d-6455e6dd0fe2-1535519997646-58133198

公司内其他同事就可以通过这个地址,访问jenkins 自己去配置项目,进行打包
2、 设置jenkins运行电脑的安装工作目录 为 分享目录

mac-share-file-location-635f4725-e44c-4453-96d6-650f40565f4a-1535520004379-34089227

mac-share-01-46d5da8b-ba1d-4c68-b3b9-1546c95b3f99-1535520002397-79510648

mac-share-2c4872fc-4a1d-4219-bafd-fa75d296ca62-1535520002992-50369483

同事可以通过Finder 访问共享的电脑,找到manajay名称的电脑,选择连接,可以设置密码,我直接让同事可以以客人的身份,无密码访问jenkins下的 workspace目录.
这样即使 上传失败,自己可以获取到ipa包,自己分发.
3、 jenkins 设置成,开机自启的程序 brewed-jenkins小插件

jenkins-start-with-mac-86d53f40-ce2a-4c7e-8916-6508a50e0854-1535519995845-45528697

补充另一种打包方式 fastlane

如果你的项目使用的是 fastlane那就简单很多了.

  • match 配置证书与描述文件
  • gym 负责打包
  • pgyer 负责分发测试, fastlane有个蒲公英的插件,亲测有bug,所以我还是用的脚本

整个打包上传脚本,注意如果使用了fastlane就不需要配置证书的钥匙串,上面的xbuild脚本了.

#bin/bash -l
pwd
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8

echo "pod 更新项目依赖 ----开始----"
/usr/local/bin/pod update --verbose --no-repo-update
echo "pod 更新项目依赖 ----结束----"

cd fastlane
pwd
echo "fastlane 打包命令-----开始-----"
fastlane development
echo "fastlane 打包命令-----结束-----"

echo "pyger 上传命令-----开始----"
sh ./deploy_pgyer.sh
echo "pyger 上传命令-----结束----"

待完成的

  • 测试蒲公英分发 curl -F "file=@/tmp/example.ipa" -F "uKey=" -F "_api_key=" https://qiniu-storage.pgyer.com/apiv1/app/upload
  • 添加webhooc自动触发构建

问题

fir 命令找不到 或者 can't find gem fir-cli

fir publish /Users/xxx/.jenkins/workspace/Archives/A_Test_2018080811261533698819/TEST.ipa -T 52101992f55f4a4c8de13c831396bf1e
/Users/xxx/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems.rb:271:in `find_spec_for_exe': can't find gem fir-cli (>= 0.a) (Gem::GemNotFoundException)
 from /Users/xxx/.rvm/rubies/ruby-2.4.0/lib/ruby/site_ruby/2.4.0/rubygems.rb:299:in `activate_bin_path'
 from /Users/xxx/.rvm/gems/ruby-2.4.0/bin/fir:23:in `<main>'
 from /Users/xxx/.rvm/gems/ruby-2.4.0/bin/ruby_executable_hooks:15:in `eval'
 from /Users/lile/.rvm/gems/ruby-2.4.0/bin/ruby_executable_hooks:15:in `<main>'
Build step '执行 shell' marked build as failure
Finished: FAILURE
  • 原因: 环境变量的问题 1️⃣ PATH 没有配置好, 2️⃣ 使用 rvm 配置的 ruby
  • 解决
    执行脚本处添加
#!/bin/bash -l # 指定脚本
rvm info        # print info about rvm (for debugging)
bundle # 打印环境信息, 查询具体出错的打印

环境变量配置 rvm, 修改文件 ~/.bash_profile 插入语句如下

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*

然后再次执行

参考链接