编译、测试、打包、部署这一系列的操作实在是太麻烦而且容易出错漏,能自动化的东西我们就没必要手动去点。端着咖啡悠哉地等着叮的一声,安装包出现在面前,这才是我们想要的
花了点时间,把正在进行的 React Native 项目的自动部署完善了一下,实现了通过 Travis CI 自动编译测试,并打包成 ipa 发布到 FTP 的整个流程
现在只要 Push 到 Github 上,等到 Travis CI 运行完成,就直接可以拿到 ipa 包安装测试了
准备工作:
首先你需要一个 Github 账户
Travis CI 连接 Gtihub 后,会自动检查根目录下带有 .travis.yml
的项目
关于 Travis CI 的功能和文档,请参考 https://docs.travis-ci.com/
这里给出一个 React Native 项目的 yml 文件示例:
language: objective-c
osx_image: xcode7.1
xcode_project: ios/MyApp.xcodeproj
xcode_scheme: MyApp
env:
matrix:
- SPEC=spec1
before_install:
- ./scripts/decrypt_key.sh
- ./scripts/add_key.sh
- brew update
install:
- brew reinstall node flow watchman xctool
- npm install -g react-native-cli
branches:
only:
- master
script:
- ./scripts/release.sh
首先设置项目编译环境:
包括 language
和 要使用的编译镜像 osx_image
,并指定项目文件和编译的 scheme
证书加密:
由于 iOS 打包过程需要一些证书密钥,这些是无法公开 Push 到 Github 的
虽然 Travis CI 没有提供 security file 的功能,但是提供了一个 security 的环境变量的功能
因此,我们可以通过在本地加密证书然后上传,线上编译时再解开来实现这一目的
比如:
# encrypt_key.sh
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/MyAppdev.mobileprovision -out scripts/MyAppdev.mobileprovision.enc -a
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/dist.cer -out scripts/dist.cer.enc -a
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/dist.p12 -out scripts/dist.p12.enc -a
# decrypt_key.sh
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/MyAppdev.mobileprovision.enc -out scripts/MyAppdev.mobileprovision -d -a
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/dist.cer.enc -out scripts/dist.cer -d -a
openssl aes-256-cbc -k ${ENCRYPT_PASS} -in scripts/dist.p12.enc -out scripts/dist.p12 -d -a
注意: 请不要直接上传你的证书和密钥!也不要把密码上传到公开的地方!
导入证书到 Travis 编译环境:
参考下面的步骤:
# add_key.sh
# Create a custom keychain
security create-keychain -p travis ios-build.keychain
# Make the custom keychain default, so xcodebuild will use it for signing
security default-keychain -s ios-build.keychain
# Unlock the keychain
security unlock-keychain -p travis ios-build.keychain
# Set keychain timeout to 1 hour for long builds
# see http://www.egeek.me/2013/02/23/jenkins-and-xcode-user-interaction-is-not-allowed/
security set-keychain-settings -t 3600 -l ~/Library/Keychains/ios-build.keychain
# Add certificates to keychain and allow codesign to access them
security import ./scripts/apple.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASS -T /usr/bin/codesign
# Put the provisioning profile in place
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp "./scripts/MyAppdev.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
安装环境
安装编译所需要的环境,比如 xctool、node、npm、react-native 等等
编译和打包
举个栗子:
# release.sh
npm install
react-native bundle --dev false --platform ios \
--bundle-output "/tmp/main.jsbundle" --entry-file index.ios.js
xctool -project ios/MyApp.xcodeproj -scheme MyApp build -sdk iphoneos \
configuration Release OBJROOT=$PWD/build SYMROOT=$PWD/build
if [[ $? != 0 ]];then
echo ">> build failed"
exit 1;
fi
PROVISIONING_PROFILE="$HOME/Library/MobileDevice/Provisioning Profiles/MyAppdev.mobileprovision"
OUTPUTDIR="$PWD/build/Release-iphoneos"
NAME=Esports_${TRAVIS_COMMIT:0:6}.ipa
xcrun -log -sdk iphoneos PackageApplication "$OUTPUTDIR/MyApp.app" \
-o "$OUTPUTDIR/$NAME"
if [[ $? != 0 ]];then
echo ">> package application failed"
exit 1;
fi
cd $OUTPUTDIR
curl --ftp-create-dirs -T "$NAME" -u $FTP_USER:$FTP_PASSWORD \
ftp://$FTP_SERVER/esports/$NAME
echo ">> {$NAME} uploaded!"
echo ">> all done!"
基本上和本地编译运行 React Native 项目类似,不同之处在于使用了 xctool 命令行来编译
- 首先安装依赖 package
- 然后 react-native bundle (如果使用 online 的模式,可以忽略这一步)
- 使用 xctool 编译和测试项目
- 打包 App 为 ipa 文件
- FTP 发布(Travis CI 支持多种发布方式,可以参考文档实现)
- 完成,邮件或 IM 通知(如果你需要)
ref: https://www.objc.io/issues/6-build-tools/travis-ci/