为iOS建立Travis CI(史上最全版)

前段时间由于公司需求,我为Github代码仓库配置travis,找了很多资料发现都不细致而且还有问题,对于我这种第一次配置的人来说花了一个多月才配置好。下面我提供大家最全的配置方法(其中绿色字体是.travis.yml中的内容,橘黄色字体是终端命令):

1. 在项目的根目录创建一个名叫 .travis.yml 的文件,根目录就是与.xcodeproj 同级的目录;

2..travis.yml的内容如下:

language: objective-c 

osx_image: xcode7.2

env:
  matrix:
  - http_proxy="......"

如果工程中用到了cocoapods可以使用代理提高pod install的速度
  global:
  - APPNAME=""
  - 'DEVELOPER_NAME=""'
  - PROFILE_NAME="TravisExample_Ad_Hoc"

APP_NAME通常就是你在项目主target下Xcode Build Settings 中Product Name的名字。DEVELOPER_NAME里是你在项目主target下Xcode Build Settings 中Code Signing Identity > Release里面看到的名字。最后搜索一下你应用的Ad Hoc或者In House配置文件,将其中的黑体文字全部去掉。根据你设置的不同,在一些属性的方括号里面可能不会有任何信息。PROFILE_NAME里是Provisioning Profiles的文件名去掉后缀。

接下来是最重要的一步:

为iOS建立Travis CI(史上最全版)_第1张图片

这是我的项目根目录中scripts里面的文件夹,包括profile和travis两个子文件夹

证书和配置文件

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

从苹果的配置页面中下载或者从你的Keychain中导出,将它保存到项目目录下scripts/travis/apple.cer这个位置。

 2. iPhone Distribution证书+私钥以及Developer证书+私钥

如果你还没有一个iPhone发布证书你需要创建一个。登陆你的苹果开发者账号,你可以跟随下面的步骤创建一个生产环境的新证书(Certificates > Production > Add > App Store and Ad Hoc)。确保你已经下载并安装了这个证书。以后你可以在你的Keychain中找到它,还有一个捆绑的私钥。现在打开你Mac上的Keychain应用:

为iOS建立Travis CI(史上最全版)_第2张图片

右击证书选择导出将其放在scripts/travis/dist.cer路径,在导出捆绑的私钥,保存到scripts/travis/dist.p12。可以根据你的需要设置一个密码。

你可以跟随下面的步骤创建一个开发环境的新证书(Certificates > Development > Add),确保你已经下载并安装了这个证书。在keychain中找到它,还有一个捆绑的私钥。现在打开你Mac上的Keychain应用,右击证书选择导出将其放在scripts/travis/dev.cer路径,在导出捆绑的私钥,保存到scripts/travis/dev.p12。可以根据你的需要设置一个密码。

Travis需要知道你的私钥密码,我们需要将其储存在某个地方。显然我们不想用简单的文本来存储这个密码。我们可以利用Travis的安全环境变量。打开终端进入包含.travis.yml文件的目录。首先用gem install travis命令安装Travis gem。安装完成后你就可以用以下命令添加密码:

travis encrypt “KEY_PASSWORD={password}” –add  这里的password是.p12的私钥

这样就可以安装一个叫做KEY_PASSWORD的加密环境变量到你的.travis.yml配置文件。在任何可以被Travis CI执行的脚本中都可以使用这个变量。

3. iOS 移动设备备案文件(发布用)

如果你还没有一个发布用的移动设备备案文件。根据你的开发者账号类型,你可以选择Ad Hoc或者In House两种不同的备案文件(Provisioning Profiles > Distribution > Add > Ad Hoc or In House).下载将其保存到scripts/profile/目录下。

4.加密证书和备案文件

不过你的GitHub权限是公开的。你可能会想要给你的证书和备案文件加密,因为他们包含了你应用的重要信息。如果你使用的是一个私有目录,你可以跳过这一小节。首先我们需要想出一个密码来加密我们所有的文件。在下面的例子中,我们使用foo这个单词,你完全可以将其替换为使用于你项目的更安全的密码。在命令行中需要使用openssl来加密这些敏感文件:

openssl aes-256-cbc -k "foo" -in scripts/profile/TravisExample_Ad_Hoc.mobileprovision -out scripts/profile/TravisExample_Ad_Hoc.mobileprovision.enc -a

其中TravisExample_Ad_Hoc.mobileprovision是你配置文件的文件名

openssl aes-256-cbc -k "foo" -in scripts/travis/dev.cer -out scripts/travis/dev.cer.enc -a

openssl aes-256-cbc -k "foo" -in scripts/travis/dev.p12 -out scripts/travis/dev.cer.p12 -a

openssl aes-256-cbc -k "foo" -in scripts/travis/dist.cer -out scripts/travis/dist.cer.enc -a

openssl aes-256-cbc -k "foo" -in scripts/travis/dist.p12 -out scripts/travis/dist.cer.p12 -a

这样可以创建.enc后缀的加密版本证书和配置文件。现在你可以删除或者忽略那些原始文件。但是有一点千万不要提交未加密的证书与配置文件,否则它们会出现在GitHub上。如果你不小心这样做了,立刻去寻求帮助。现在我们的文件都已经加密,我们需要告诉Travis如何解密。所以我们需要提供解密的密码,使用之前创建KEY_PASSWORD变量一样的方式:

travis encrypt “ENCRYPTION_SECRET=foo” –add

为iOS建立Travis CI(史上最全版)_第3张图片

就如同下面这种格式:

- secure: QJFiFpPXO/JnT7ZQEtTPOF5oM8XnoTikaLg01VFrDUdcFMkq9iIOdO/j2j4WOCPCvpdyOQrCdcThoiDRCMJTuaV9PABiVCLH7iyO8Bjd5cOWgcKsSlkMiGlcr8sIUXw3qrixIRskFXhtQY4QHyB7V9ZkhVDXZYai858fJ1379/4tJyK1VL2lSSv43VNMAxFhgFUnk4Sw6JxlEUEfObZ21X3Lr80d14SUrTB7yUS0jEflkiLCkb6onFlUCdj4W5Oxaboo8g5AunenFAxTQwbGqWxmNVhZvgNpGaXeTOyccdzJOMQFx+l+Y8NDLSHtJ8xSeqU/i67DHzLnLeDz2S8x4Et/pTHTlqnd92GVfjad+uC0kPN6ptiTXIVgi/QLO5eyyshR3D0ef3rAm1Wf3LjhKQRDg8psEzlnzEnFFujyWpZbSNO5ZVV3rhfQop3gU23M/RNqYIi33EYF4LKH+S49+2uMWQ0UST+iWFh3B1zegx6qJ+87VYMaxmHxShvEBnK+inW+oq6x9dBkkkh3GsCJGSIj2TyP38H0HZuYjMCUqY9XucnuzhrE54wzShgImVfV7UzIJGjNFFcwgwZrLnCibJIhEDzTQWyjJXcevWkDXhHtKZTx+rZ7JFY1/S54qyopUeIjOhN+khek0crJsgH9RyEFSgZeRt45XC1Fq9X5ntQ=

最后我们需要告诉Travis哪些文件需要解密。在.travis.yml文件的before-script阶段添加如下命令:

before_script:
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/profile/TravisExample_Ad_Hoc.mobileprovision.enc -d -a -out scripts/profile/TravisExample_Ad_Hoc.mobileprovision
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dist.cer.enc -d -a -out scripts/travis/dist.cer
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dist.cer.p12 -d -a -out scripts/travis/dist.p12
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dev.cer.enc -d -a -out scripts/travis/dev.cer
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dev.cer.p12 -d -a -out scripts/travis/dev.p12

5.添加脚本

5.1现在我们需要确保所有的证书都导入到Travis CI的钥匙串中。这一步我们需要在scripts/travis文件夹下面添加一个新的文件add-key.sh,下面附上图片和代码:为iOS建立Travis CI(史上最全版)_第4张图片

security create-keychain -p travis ios-build.keychain
# Make the keychain the default so identities are found
security default-keychain -s ios-build.keychain
# Unlock the keychain
security unlock-keychain -p travis ios-build.keychain
# Set keychain locking timeout to 3600 seconds
security set-keychain-settings -t 3600 -u ios-build.keychain

# Add certificates to keychain and allow codesign to access them
security import ./scripts/travis/apple.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/dist.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/dev.cer -k ~/Library/Keychains/ios-build.keychain -T /usr/bin/codesign
security import ./scripts/travis/dist.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASSWORD -T /usr/bin/codesign
security import ./scripts/travis/dev.p12 -k ~/Library/Keychains/ios-build.keychain -P $KEY_PASSWORD -T /usr/bin/codesign

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

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

# Put the provisioning profile in place
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp "./scripts/profile/team.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/
cp "./scripts/profile/$PROFILE_NAME.mobileprovision" ~/Library/MobileDevice/Provisioning\ Profiles/

5.2这一步我们需要在scripts/travis文件夹下面添加一个新的文件sign-and-upload.sh,下面附上图片和代码:
为iOS建立Travis CI(史上最全版)_第5张图片

#!/bin/sh
if [[ "$TRAVIS_PULL_REQUEST" != "false" ]]; then
  echo "This is a pull request. No deployment will be done."
  exit 0
fi
if [[ "$TRAVIS_BRANCH" != "dev" ]]; then
  echo "Testing on a branch other than dev. No deployment will be done."
  exit 0
fi
PROVISIONING_PROFILE="$HOME/Library/MobileDevice/Provisioning Profiles/$PROFILE_NAME.mobileprovision"
OUTPUTDIR="$PWD/build/Release-iphoneos"
xcrun -log -sdk iphoneos PackageApplication "$OUTPUTDIR/$APPNAME.app" -o "$OUTPUTDIR/$APPNAME.ipa" -sign "$DEVELOPER_NAME" -embed "$PROVISIONING_PROFILE"
#fir p $OUTPUTDIR/$APPNAME.ipa -T $FIR_APP_TOKEN
curl http://www.pgyer.com/apiv1/app/upload \
  -F uKey="$PGYER_UKEY"\
  -F file="@$OUTPUTDIR/$APPNAME.ipa" \
  -F _api_key="$PGYER_APIKEY"
  
  RELEASE_DATE=`date '+%Y-%m-%d %H:%M:%S'`
  RELEASE_NOTES="Build: $TRAVIS_BUILD_NUMBER\nUploaded: $RELEASE_DATE"

这里的PGYER_UKEY和PDYER_APIKEY需要加密

travis encrypt “PGYER_UKEY=应用的UKEY” –add       travis encrypt “PGYER_APIKEY=应用的APIKEY” –add

5.3这一步我们需要在scripts/travis文件夹下面添加一个新的文件remove-key.sh,下面附上图片和代码:为iOS建立Travis CI(史上最全版)_第6张图片

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

最后附上完整的.travis.yml文件内容:为iOS建立Travis CI(史上最全版)_第7张图片为iOS建立Travis CI(史上最全版)_第8张图片

language: objective-c
osx_image: xcode7.2
env:
  matrix:
  - http_proxy=""
  global:
  - APPNAME=""
  - 'DEVELOPER_NAME=""'
  - PROFILE_NAME=""
  - secure: QJFiFpPXO/JnT7ZQEtTPOF5oM8XnoTikaLg01VFrDUdcFMkq9iIOdO/j2j4WOCPCvpdyOQrCdcThoiDRCMJTuaV9PABiVCLH7iyO8Bjd5cOWgcKsSlkMiGlcr8sIUXw3qrixIRskFXhtQY4QHyB7V9ZkhVDXZYai858fJ1379/4tJyK1VL2lSSv43VNMAxFhgFUnk4Sw6JxlEUEfObZ21X3Lr80d14SUrTB7yUS0jEflkiLCkb6onFlUCdj4W5Oxaboo8g5AunenFAxTQwbGqWxmNVhZvgNpGaXeTOyccdzJOMQFx+l+Y8NDLSHtJ8xSeqU/i67DHzLnLeDz2S8x4Et/pTHTlqnd92GVfjad+uC0kPN6ptiTXIVgi/QLO5eyyshR3D0ef3rAm1Wf3LjhKQRDg8psEzlnzEnFFujyWpZbSNO5ZVV3rhfQop3gU23M/RNqYIi33EYF4LKH+S49+2uMWQ0UST+iWFh3B1zegx6qJ+87VYMaxmHxShvEBnK+inW+oq6x9dBkkkh3GsCJGSIj2TyP38H0HZuYjMCUqY9XucnuzhrE54wzShgImVfV7UzIJGjNFFcwgwZrLnCibJIhEDzTQWyjJXcevWkDXhHtKZTx+rZ7JFY1/S54qyopUeIjOhN+khek0crJsgH9RyEFSgZeRt45XC1Fq9X5ntQ=
  - secure: fzqdixyHFMNVhKtMOHdpWuPbPAF0ZiPB7tvR1ACBjDM/zFZV+kCAmVvW+IEhhHCUs39dqLC4Zrp5/nenn8HvoTKNtQA22mngYizEpAhxI2h7aPuCNUX2bIZZOjfh/ufFAClTYw7EtbkyimuVef6Y6k1+Gp7eO65igPKB2fYgurmrHXfJiy2BvxtPl/CbxmuIZ4ZuXPQE18ezZjgaq/b+j8Lpd53POUl1Z2m0nAWuDqB8zi5hBkYHVVbyfNy1zTf6HJAXeYsaUrwGoxXiD933UI2xSxjEushpLRR2Gg/2S/Dl2rshZ2pVizU2i544jJ6+ORihvFSxsKPi/X/wRlgdLXQj/ATn9/A2qBYQhjTYfdFXISwltd8JNV3qKaFkipedVoM8BVEpRJ89Uqc0Rxgxd0Wnuk8NJ9pqRK1U6rSdrZZyvF3MPibhnouQI5/xlRBNCBo4LJRP73/v1zYXq+J0CvkU6q1ew0vhB6Gz0SJxUsag6F0zaLgZMGJ/ky0ILfpWLw6RDt3syYcOZH+fW381Fc38gTTUsHmW0uulXc3fs/9e6PLA6MQxeVFl8UE0sjy/uNbqbHkCAfRGYbk21sGUSHG9hb9yMBKwu5x3IFZVcAdl6Wbfb2F+7ZWTBSgd5Oy9DAMegUyAdv/9AuIYOclIVeA2Z/wc1a74zxILwLarhMY=
  - secure: lNIKapTUZ8Gg7tONPWaT+pwahxm5Uk0PkS5PDSMYeULcNauUWPpmec4I8LANs5dP/MJAXBDKseGCSiDlFv93Md3GMzE1DAX5fq6mgLhBRk2+wfeQcIlOzUvOpJCIZptXFneC8DMTj6Y3402qnA5l8exdL3oKGx2sDcr4iA+mitvU9NwgrWFtjaK0AKeDyVclMvMczSEabCjI/6T8yDrmEDBrpLgldO6JiaE7YOFHVLUMe2MN0WbTWlNDu6uLJ5X0kCE04o2DaXtWGtHXVLrRaIQVRGsKOz9fiJZ3xRfy8Vo6IrD9aK8hNRwSQxzHnVmCfD/ANiGpXKvZ7LEb6nwV6pLHi/GI0bgM2qVIDGXgs5cb+oAeBVEbAuqtTR//r7xH+xT7jdUEYpQbMVUoj0wIgCv5AB0KPsHK67//4B69DtknL/ONH2lyCPm+eXFSWI5bqCcjc7wd12ivSlxDv8qW5u+dbxh1BJnA9REJwG6A4kOtJVhtMh78Jdvs95T4OndMep/BaLyKsu0vFxNmGHomcxG+oCiiQuobvFcfUw5cP5zCQnyCGx96gkWGkt+FK6l96VhmjmRF4oXNi7BaE4ZpgdEZ95JKHVd4nbV8mzoTLb6aLxx2KC1vRpqM0+XIn+2331+u8lxLWuSJQ0wNtOn9fTDC3KkSDVh7YuCNV4i9uHg=
  - secure: CNU+hcs0LhVYrlH8Iz1vwl/mEY3+mpNKke/0wuSC+iFNPGW8GchV7XhLtbm6BOhM2G+PuQ1nCB73mtCGTi/fmRxts4WondCSz8HijeuNipoZDeKaC+5irokhChDKSC9NI8noCErnEjOO7n8PFcO4XBb/ayMeS4vftgxJ+57Fp72Qr9bDeXo6hDOpmxu8/qUrd2j5DBx6yDB4yo0Jh8Rt4WACrAIrpPvtlRxwlt/lFx30+Kj5kNvvnqL/8I3DuzwhfZek2wHAJx6iy38yUosF3nhYDct8T8UVf42tvno4bFB07pMCjxnaMn5XUUEHVGvt6mPw+QW+Go1xwv+wAIhEDBfc7XD59M9yDHt0y29DvwKgqv5JEwSHNNTmprnEckQIWiMjNIJdCd8jf2ILGPpchi8uPWVUWeATJMRiKnP3+UcpUcefwEFAmQs+5IZXeQun5xeUH7xQ2qOvviHJM/Jyft5NGcdWqeC+Y8s9UF5GP7m+HVqdH/Atk7EVAj++vXn28Tx9IzF27Puki8APZu79z0SiuqDGXxCwGyE2tl0bsVoo0ozsIWkUZhO6FCchIMkBUpunwc/G6LRiJWzAsKAaRilN2uFYgnrG0SuxydZLO8Ht186HODqSzwGOEdc8Nyk1F+6tUrYFFZtMrO6mJ81PBp/cj8pjQkWxOp6i/y8YPZ0=
  - secure: J+4SNoYbPRc8ewzCvsupUqP9Ijp7eSYn2J7sA7lJ2w6U6JLWS3CPVGMXGE+vm4hjmQSAkdPKYx0TU/hpnsWecFWp/gVmLxfEjecni4sys2p8C9QguTa5mTWbvKgOJmK3MVaZBAdpmj57P9QBn4ciFBzRHe9HcyXM1R+OJBklRrqbZNXPw071s/G3uS0KqqSODJ7QfDZO5rC2+Y/OrXzDEvaUIjGyMMf3LGcj8tGnubJcSUoJ7tKBroF+a37pZ8OSTA697BKpENUQE1ErRq6TrLEDv7EYGqmhaCH3flpIuk4VPc1+UgsnVrZ7xc8QZGg/+TAs7rukFrJblby3aoZcUUyeyCKhMPlFAXlPjxT+89Q78X1j6ZT15DfxjcOoYD9/8L9XFj6DKrEEQ884t+l3q3ZhDVYQONYQ6fQpbnC/ymIkGJ8Rv3soaO3bobR80ak3bvNcffvtIMiHFM7Onh5gFU3zP0Ou2P/TWbxYaovgfd0HLQonobLcQR4KsRPHP99y5y7pS2gZRYXKlLzZaxOvJUOtXdsxrOlkkZa9f2iYH8Lg2LUrja9kMWLux4Sid5itx4zPTKfBuYarIp74GXeX+0RfKH6ndtSfRtkjUWpUsgvnmtZM6l/arkjp9algGju1BFqWP38vGjG3cz+k3JGhmo3B6fmG/QxAP/41MbMgWYg=
before_install:
- brew update
- brew install beanstalk
- brew outdated xctool || brew upgrade xctool
- gem install fir-cli --no-ri --no-rdoc
- gem install cocoapods -v '0.32.1'
- chmod +x scripts/travis/add-key.sh
- chmod +x scripts/travis/remove-key.sh
- chmod +x scripts/travis/sign-and-upload.sh
install:
- pod install
script:
- xctool -workspace customer-ios.xcworkspace -scheme customer-ios-dev -sdk iphoneos -configuration Release CODE_SIGN_RESOURCE_RULES_PATH='$(SDKROOT)/ResourceRules.plist' OBJROOT=$PWD/build SYMROOT=$PWD/build ONLY_ACTIVE_ARCH=NO
before_script:
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/profile/user_dis.mobileprovision.enc -d -a -out scripts/profile/user_dis.mobileprovision
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dist.cer.enc -d -a -out scripts/travis/dist.cer
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dist.cer.p12 -d -a -out scripts/travis/dist.p12
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dev.cer.enc -d -a -out scripts/travis/dev.cer
- openssl aes-256-cbc -k "$ENCRYPTION_SECRET" -in scripts/travis/dev.cer.p12 -d -a -out scripts/travis/dev.p12
- ./scripts/travis/add-key.sh
after_script:
- ./scripts/travis/remove-key.sh
after_success:
- ./scripts/travis/sign-and-upload.sh
podfile: ./podfile
cache:
  - cocoapods

对于使用CocoaPods的项目,你需要指定workspace和scheme。

Schemes是由Xcode自动生成的,但这在服务器上不会发生。确保所有的scheme都被设为shared并加入到工作目录中。否则它只会在本地工作而不会被Travis CI识别。

为iOS建立Travis CI(史上最全版)_第9张图片


你可能感兴趣的:(ios)