Pgyer document center

使用 Travis CI 实现持续集成 (iOS)

这篇文章将会给大家介绍如何在 iOS 项目中使用 Travis CI ,并将 App 签名后发布到蒲公英。

关于 Travis CI 产品分类

Travis CI 是目前比较流行的持续集成工具之一,用来构建及测试在 Github 托管的代码,使用它可以极大的简化工作流程。Travis CI 产品分为:

  1. Travis CI.org (用于Github开源项目的免费产品)
  2. Travis CI.com (用于私有项目的付费产品)

注:本文中介绍的Demo是基于(Travis-ci.org)

准备工作

需要在本地安装 Travis CI 命令工具。

  1. 确保本地系统配置 Ruby 1.9 以上版本:

    ruby -v
    
  2. 安装Travis-CI (如果使用 Mac OS 最好先更新 Ruby 到最新版本,然后再安装)

    gem install travis --no-rdoc --no-ri
    
  3. 验证 Travis 是否安装成功 (有版本输出则说明安装成功)

    travis -v
    1.8.8
    
  4. 登录 Travis。在命令行中,使用 GitHub 账号登录

    travis login 
    

    登录后,可以用

    travis accounts
    

    来验证账号是否成功登录。

集成步骤

一、启用Travis CI

通过 Github 账号登录 Travis 平台。Travis 会自动同步Github账号上所有的开源项目。通过列表选择需要启动的项目。

添加项目

二、创建Travis CI构建

  1. 在工程根目录下添加 .travis.yml文件。这个文件用于说明 Travis CI 需要处理的构建。
  • Travis CI 本身提供基本的构建和支持语言,同时开发者可以通过.travis.yml文件设置自己的构建操作,同时需要遵从 Travis CI 自己规定的构建生命周期。具体可查阅这里

  • 在完成 .travis.yml 定义后, 可以通过 travis lint [path to your .travis.yml] 命令验证这个文件语法是否正确性。如果正确会出现以下的提示:

    验证构建文件

  1. 配置 iOS 工程基本模板,在 .travis.yml 中定义以下内容:

    language: objective-c
    osx_image: xcode9
    

    如果你只是想使用 Travis CI 的构建功能,那么这两行已经足够了。在你把.travis.yml Push 到 Github 上之后,Travis CI 就会自动开始 Build 流程,在 Build 完成之后,Github 绑定的邮箱就能收到通知。当然,对蒲公英的用户来说,只是 Build 是不够的,我们还希望能够对 App 进行打包,签名,并发布到蒲公英平台上。

三、配置项目:

在使用 Travis CI 需要我们修改两处项目配置,否则的话,会导致 Build 失败。

  1. 将项目的 scheme 管理方式改成 shared:

  1. 关闭 bitcode 选项:

四、打包签名并上传至蒲公英

为了对 App 进行签名,我们必须得配置好证书和配置文件。

1. 苹果全球开发者关系认证

苹果官网下载证书,或者从钥匙串中导出。并将其保存到项目的目录 travis/certificates/AppleWWDRCA.cer 中。

2. 导出发布证书和私钥

钥匙串程序中选中证书分别导出证书和私钥。

切记:不要上传没有加密的证书和描述文件到 GitHub 的公开仓库(下文会讲如何加密)

将证书和和 p12 文件放在 travis/certificates/sdk_demo.certravis/certificates/sdk_demo.p12 。导出 p12 文件的时候要输入密码。

Travis CI 在使用 p12 文件的时候需要知道密码,而我们又不能将密码明文保存在某个地方,所以这个时候我们可以使用到 Travis CI 的安全环境变量功能。

打开终端,定位到.travis.yml文件所在的目录,用下列命令来保存 p12 文件的密码。

travis encrypt "KEY_PASSWORD=123456" --add

这其中的123456就是你导出 p12 文件时输入的密码。在输入了这条命令之后我们就会发现.travis.yml多了一行数据

 - secure: xJz9E1EJdBDAIZcNaz86a7nrJpbdPHS3xiXU5L4Gj4rFR0TcxHsHuu2dcZR/yRJRHg6oum2zuMr0XBsSffMBYFHX5Kw2jb31Ci6uFbOTI/FGBrwdvfhQBL+h/7xe/j3l1bmbmfElYP02fiJvN5VSVyA0    3Iobp7u3vY0TW7yce+po23DmJCTYgnUdfuf4EBO3gpgbOTPdmIxqyhqqw5Ndwmvxpq9BqneqEc3pmNCC1FC6H4RmgjkWnMln5ffWIxNN+nwgPzSDqHDMUnQaYtVUU/CHLQCmNCgQmkrG/OWYvlo4RqpEX6VZv5BUa6gD    7d4lgcfXHONkmLKNbiWBGDRbbBQNNSbubTtGlyGtzCHwEe4KvHoM4n0yDZqtd9edgrxlOSuBgNlQK+/3C6BhZZi2rWNlnqBU7F/ZSmjBONWgRuFZJ2zJByHWLoTTOHvYbFdk4CTmT5qMQPQ7favMu1L9TUBpbX4qBX4D    iXpEKNODtwOvdYjlfiZ+US6i637JeZF8OK9bBtUf4oKjvl1Oz5ly56snTBknF3V+if6VoHlG1Cfroqhy2F7ahS2K3Aq0u4O2gMIVqTRd1juBLo6QkzV/F+go4KvYDwOFpAX05AYrJNOQgAHae5a8Px2YIct1QcRTL++r    Enqx1QzQWXIEXpezm8m1pR8TcB8d2WbLGtwTd/8=

这行数据就是通过上述命令安装到.tarvis.yml文件中的环境变量KEY_PASSWORD,在后续打包的过程中,Travis 就可以通过引用KEY_PASSWORD来使用 p12 文件对应的密码。

3. 描述文件

签名打包的时候,我们还需要用到 .mobileprovison 描述文件。描述文件可以在在苹果开发者网站上创建和下载(Provisioning Profiles > Distribution > Add > Ad Hoc or In House)。将下载后的文件保存在travis/certificates/sdk_demo.mobileprovision

同时,我们还需要将对应的,描述文件的文件名,App 名称,开发者名称都保存在 .travis.yml 文件中:

env:
  global:
  - APPNAME="PgySDKDemo"
  - 'DEVELOPER_NAME="iPhone Distribution: your developer name (your developer code)"'
  - PROFILE_NAME="sdk_demo"

4. 加密证书和配置文件

如果使用的是 GitHub 的公开仓库,我们还需要对证书,配置文件,私钥这些敏感文件进行加密。加密了之后,我们还需要告诉 Travis CI 如何去解密这些文件。

  1. 加密

Travis 在解密时只支持单文件,所以,我们还需要在加密前把证书和配置文件打包成一个压缩包。

tar cvf certificates.tar sdk_demo.cer sdk_demo.p12 sdk_demo.mobileprovison

运行完命令之后,就会发现,文件目录中多了一个 certificates.tar的文件,我们把这个文件放到项目的根目录下。然后在项目的根目录下运行命令:

travis encrypt-file certificates.tar -a

对压缩后的证书和配置文件进行加密。-a 参数的作用是自动的把解密文件的指令添加到.travis.yml文件中。运行完指令后,我们会得到一个名为 certificates.tar.enc的加密文件。这个时候,就可以把未加密的 certificates.tartravis/certificates 文件夹目录下的 sdk_demo.cer sdk_demo.p12 sdk_demo.mobileprovison这四个文件删除掉。

  1. 解密

运行完加密命令后,我们还会发现 .travis.yml 文件中多了一行:

- openssl aes-256-cbc -K $encrypted_2838d02a56a6_key -iv $encrypted_2838d02a56a6_iv
  -in certificates.tar.enc -out certificates.tar -d

这一行的作用就是解密证书文件。需要注意的是,解密之后的文件仍然是一个压缩包,我们需要将压缩包解压缩。

before_install:中添加下列代码:

- tar xvf certificates.tar -C ./travis/certificates

5.导入钥匙串

为了进行签名打包,我们还需要将证书导入到 Travis CI 运行环境的钥匙串中。为了导入钥匙串我们在 scripts文件夹中添加一个名为add-key.sh的文件。下面是add-key.sh的全部内容:

#!/bin/sh
# Create a custom keychain
security create-keychain -p travis ios-build.keychain
security default-keychain -d user -s ios-build.keychain
security unlock-keychain -p travis ios-build.keychain
security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain

security import ./scripts/travis/AppleWWDRCA.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/sdk_demo.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/certs/sdk_demo.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASSWORD -A

echo "list keychains: "
security list-keychains
echo " ****** "

echo "find indentities keychains: "
security find-identity -p codesigning  ~/Library/Keychains/ios-build.keychain
echo " ****** "

mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp "./scripts/profile/sdk_demo.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/

通过add-key.sh这个脚本,我们创建了一个名为 ios-build 的临时钥匙串。临时钥匙串里包含了所有的证书信息。其中 $KEY_PASSWORD就是在引用 p12 文件的密码。通过这个脚本创建的临时钥匙串,还需要在我们完成了签名打包之后删除掉。

为了保证脚本能够正常运行,我们还需要给脚本设置可执行权限:

before_install:
 - chmod +x scripts/travis/add-key.sh

6. 打包

在 Xcode 8.2 以前广泛使用的打包工具 xctool 现在已经不能使用了,我们只能通过 xcodebuild 来打包,打包分为两步:Archive 和 签名。打包脚本如下:

#!/bin/sh
xcrun xcodebuild -project PgySDKDemo.xcodeproj -scheme PgySDKDemo \
  -archivePath PgySDKDemo.xcarchive archive

xcrun xcodebuild -exportArchive -archivePath PgySDKDemo.xcarchive \
  -exportPath ./build -exportOptionsPlist ExportOptions.plist

这其中需要一个-exportOptionsPlist 文件,获取这个文件最简单的方式就是通过使用 Xcode 导出一个 ipa ,在导出的 ipa 所在的文件夹中就有一个 ExportOptions.list。我们把这个文件放在项目的根目录中就可以了。

运行完打包脚本之后,我们就可以在项目的 ./build 目录下找到签名好的 ipa 文件了。

7. 上传蒲公英

我们已经写好了一个上传 ipa 文件的 shell 脚本。你只需要在 before_install: 中下载该脚本,并给与该脚本执行权限,并在打包完成之后调用该上传脚本。

- wget -c https://raw.githubusercontent.com/Pgyer/TravisFile/master/pgyer_upload.sh
  -O pgyer_upload.s
#!/bin/sh
./pgyer_upload.sh "./build/$APPNAME.ipa" $PGYER_APIKEY

上传的时候,需要用到蒲公英的 API_KEY, 你可以在这里找到你的 API_KEY。由于 API_KEY 不能明文保存,所以我们通过使用和保存密码一样的方式,把它安装到 .travis.yml文件中。打开终端,定位至项目的根目录,在命令行中输入:

travis encrypt "PGYER_APIKEY=655b39fe4bad7a701bd44dfbcafdcc2f" --add

8. 清理钥匙串

在所有环节都结束后,我们还需要删除掉导入的钥匙串信息。我们在 /scripts/travis 文件夹下添加一个新的文件 remove-key.sh :

#!/bin/sh
security delete-keychain ios-build.keychain
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/$PROFILE_NAME.mobileprovision
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/team.mobileprovision

完成上述工作之后,每次我们新上新代码到 GitHub 都会触发 Travis CI 的持续集成,并将打包签名后的 App 发布到蒲公英上。

一个完整版的 .travis.yml 文件如下所示:

language: objective-c
osx_image: xcode9.2
env:
  global:
  - APPNAME=PgySDKDemo
  - PROFILE_NAME=sdk_demo
  - 'DEVELOPER_NAME="iPhone Distribution: shengtao lei (DG37YK9PRK)"'
  - secure: iL2KhNdYKzWLTtvaXmmQ3/ci66b0Z5c8VCTmpaoMIotdtwyTOgMnpzH+Vyrof3QBH/nV2oF6puT/b5Y6S6lrCY5b4nZSfhy8xL6FEPDboVzpq2qIAS4gn6qCGUkIkAxpcnKG9sbcxDsI5aLVOqxoevuHKB2Rkw925TWrg6+bfagtWQzVvkByIHT2jm2+7bkmNUx7UiIggNYN+H2ACpfdf/d9g7lC7w2hLb6hO0Mt5pK5eGbzlh8kn/1CnX7jSWw3SyEABEJ3CQOZX5x/yNP4oIJLgdEGW3sy1ErAi2uO+i89VDu1SaRcDLbNuAmlxb95dLVBVU7uWILdWTh6+o6FVL2Eoj1YPrNBJdcRykTvaCSR1eXPs6uCoq9tcWz0zinamSBzemOjdK+G+lOC6IpT9lTimt5Ln0lGQoVYERXnvJMEhR/2rFLvsTIqd+Wt8Agfqr9EeU0ah8agWiTIE6EuA0xdTyC0EyKVYKzXBy4wI6R2fknfn6uHyeFeIN9zpWY8tcwz8pRLDD+xiyoHgSybS1DK+Xr21llOopXkC/aacnoeslciNN28In9QRDwsiDUSlAb6dQ3pRCS/cDoRJBm759xcZ7kdMnwVAcSX7aZ9p8HT0uGvyuJdYNDr4vp0r98RtPI/7JonPXqXuWzsAzZdq5AAzchwNFAbTCrASw6qqHY=
  - secure: KuD0JYZqJEtezCBkJ6Zkfw7I+0VGiv6E7GOa34KUzYsJWpLnzPYB08+NsYZYMh6Yjc8pkC8+MixgXLOHupWm5v3iRthWqD/tdmuF5bdQqIdrWkmQSl0cK9M+rMgc+vaPajguC0/yf+BoPWL6CJXouLLzj3D6IXUwZEVYhmPB4nBv/YHVk/FNwNS4aqP9SSp98VQoYrAGAvUSY3jm5L1qSNwCjPMBcX4QnlbX5mjl0mEf0pEbJ3ZZAz9AzpALfCYR4pPsS7/eSHxVAPNboD5JVQAK6NhaFCTUw0/UlGHW9m9eY3AezMpZo1M8kHXZXsC0BWoP8R4H6WYTybILxz6Aramb8N12R+ntLfAawnFnG5kV4mtUHFY7BqNu+tyBkba4axkclaY90fETekHUcCIqTlVmMjlKq6dzWkq4hGmDtEajajZHqMPBUMy5o8n8lXKww/ZkpvgEhrJjbxbmFcoP4oS2u9Vxi/Q18t+mRoQhGfan2cVQXdpQhk0S8scisVVnUSFHSglt79KjgKwNuVKtIpW89bG8HHQaqIgPFycvIbDRxSM6Xd+I7AIzz25XFdE/ao03ULrnDaIZLbgUa+IGjDknkRJmG9hFQKO2grkZ/JqNXQDSMEIXZrH46CocD1+j39k6wvYler5fdcIStf+wAW4hXmiO0en2hl2+qEFtJds=
  - secure: YecGZLdjxnbJuIyJOywDan2lJ4sToYx2iq8ficMEzODXUxEGHRL6s6XFOPltsm6CnyUZKfT9bzAEWuGWnnES8fcPvMUAKvyNhcRW/D9JtMm/fboIdSjb2Ht8f/dY1IfgB241pMU7SkPifVIL08yxeMYZfwgFxbDQn60aXCiUKWuEcqMgxX2yLX9uHR+T/xuY6E+NX6UEB/6imx3rQ047nVfefMgh9YMGGl0ZH/N9beZgMrwlZn1lAfKMrkbJ3vw1go2RzxnDwa/Noy+6eKfbC8R4RgCvwQ6oXBEXG1IUjHbiNhR5pXajz/5jbum9T64fHUrx8e2aPKrYRWWjooQ5Q7+AER7PnAhTgFymHhDwUm7wEXoMuh5Ltp7jCNZiaKDxUoONw4Hz+oEXKbm4nYJCMFczjW4bQKH0gqNytPhl/y/08u0fuQxTP3wu6Zi0q0qo6e3eqCTGv3Q9YzEm7JWAb6RSO09aRRVvz7HwdZFwbHy07T9//YMUsX/chhw7fziso1wkutWOsVCfBVjMGO6Nve/B8xdCVV4sqiex/Wk3c/cNHB7dTVe9SC6nelrkuyvEqKtxk87/IDBo0sAHxounw9phwtXg+RM8fN+rvBqd9rY4H8hrRaZKdFqikMt3yexoFKcrAqbQuHEDVlz2dxDxZhgjOPyVaejsOHI2jt1bB58=
before_install:
- openssl aes-256-cbc -K $encrypted_2838d02a56a6_key -iv $encrypted_2838d02a56a6_iv
  -in certificates.tar.enc -out certificates.tar -d
- cd $TRAVIS_BUILD_DIR
- wget -c https://raw.githubusercontent.com/Pgyer/TravisFile/master/pgyer_upload.sh
  -O pgyer_upload.sh
- tar xvf certificates.tar -C ./travis/certificates
- chmod +x pgyer_upload.sh
- chmod +x travis/scripts/add-key.sh
- chmod +x travis/scripts/build.sh
- chmod +x travis/scripts/upload.sh
- chmod +x travis/scripts/remove-key.sh
before_script:
- "./travis/scripts/add-key.sh"
script:
- "./travis/scripts/build.sh"
after_success:
- "./travis/scripts/upload.sh"
after_script:
- "./travis/scripts/remove-key.sh"

结语

本文介绍了如何使用 Travis CI 对 iOS 项目进行持续集成,并把打包签名后的 App 上传到蒲公英。希望对你能有所帮助。对应的 Demo 项目你可以在GitHub上找到。