Titanium で CircleCI して fabric.io の Beta で .ipa を配布するまで

More than 1 year has passed since last update.

Titanium でも自動化したい方へ

一連の流れ

  1. GitHub にプッシュ
  2. CircleCI が拾う
  3. Mocha(in ti-slag)テスト
  4. Titanium ビルド
  5. Beta へサブミット

準備

一度アプリをビルドしてから Fabric の Crashlytics を導入しておきます。記事中、2. の Paste in the following command にある、Crashlytics の API_KEY と BUILD_SECRET が必要になります。スクリプトの第一引数が API_KEY、第二引数が BUILD_SECRET になるのでどこかにメモしておいてください。

CircleCI の project settings → Experimental Settings で Build iOS project を On にして、ページ右下にあるチャットボタンから iOS のビルドができるようにお願いしておきます。

CircleCI の project settings → Environment variables で各種環境変数を設定しておきます。iOS アプリの継続ビルドを CircleCI に変更したを参考にさせていただきました。

Name Value
APPLE_CERTIFICATE Apple Worldwide Developer Relations Certification Authority を Base64 エンコードしたもの
APPLE_DEVELOPER_ID developer.apple.com の Apple ID
APPLE_DEVELOPER_PASSWORD developer.apple.com のパスワード
CLASHLYTICS_API_KEY Crashlytics の API_KEY
CLASHLYTICS_BUILD_SECRET Crashlytics の BUILD_SECRET
CLASHLYTICS_GROUP_ALIASE Beta で配布する際のグループ
DISTRIBUTION_CERTIFICATE Distribution 証明書を Base64 エンコードしたもの
DISTRIBUTION_NAME Distribution 証明書の名前
DISTRIBUTION_P12KEY Distribution p12キーを Base64 エンコードしたもの
P12KEY_PASSWORD Distribution p12キーのパスワード
PROVISIONING_PROFILE プロビジョニングプロファイルの UUID

circle.yml

CircleCI の Build iOS project を On にすると、nvm が使えなくなってしまうため、machine:pre でインストールしておきます。machine:environment の XCODE_SCHEME と XCODE_PROJECT は tiapp.xml の name で OK です(ぶっちゃけ適当で OK なはずです、無いと怒られるだけですので...)。

テストは Xcode のテストが動こうとするので、test:override で npm test が動くように変更しておきます。test:pre で Alloy のコンパイルを忘れずに行いましょう。Titanium の ビルドでも良いのですが、SDK のインストールにそこそこ時間がかかるので、Alloy のコンパイルで終わらせたほうが良いと思います(テストが失敗した時のことを考えて)。今回は Mocha(ti-slag)でテストしています。gulp jshint はお好きにどうぞ。

テストが通過したら Titanium SDK をインストールし、実際にビルドします。その後、Crashlytics/submit で配布します。プロビジョニングプロファイルのダウンロードには cupertino を利用していますが、最新版だとエラーが出ますのでバージョンを指定しています。

machine:
  pre:
    - curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.26.1/install.sh | bash
  timezone:
    Asia/Tokyo
  xcode:
    version: "6.4"
  node:
    version: "0.10.34"
  environment:
    XCODE_SCHEME: App
    XCODE_PROJECT: App.xcodeproj

dependencies:
  pre:
    - npm install -g titanium alloy tisdk
    - npm install

test:
  pre:
    - gulp jshint
    - alloy compile --config platform=ios
  override:
    - npm test

deployment:
  adhoc:
    branch: adhoc
    commands:
      - sudo gem install cupertino -v 1.3.2
      - /bin/bash misc/keychain.sh
      - tisdk install 4.0.0.GA
      - /bin/bash misc/adhoc.sh

package.json

テストスクリプトと依存関係は以下のとおり。テストスクリプト自体は ti-slag Titanium faker API, Titanium app running on Node.js を参考にしてください。ぼくはカバレッジまでとっています。

{
  "scripts": {
    "test": "mocha --no-timeouts test.js"
  },
  "devDependencies": {
    "gulp": "^3.9.0",
    "gulp-jshint": "^1.11.2",
    "gulp-load-plugins": "^0.10.0",
    "istanbul": "^0.3.17",
    "jshint-stylish": "^2.0.1",
    "lodash": "^3.10.0",
    "mocha": "^2.2.5",
    "moment": "^2.7.0",
    "request": "^2.60.0",
    "signal-exit": "^2.1.2",
    "ti-slag": "0.0.23"
  }
}

gulpfile.js

gulp jshint ですね。これはお好みでどうぞ。ぼくは jsbeautifier もしています。

var gulp = require('gulp'),
    plugin = require('gulp-load-plugins')();

gulp.task('jshint', function(){
    return gulp.src('app/controllers/**/*.js')
        .pipe(plugin.jshint())
        .pipe(plugin.jshint.reporter('jshint-stylish'))
        .pipe(plugin.jshint.reporter('fail'));
});

keychain.sh

こちらもiOS アプリの継続ビルドを CircleCI に変更したを参考にさせていただきました。

#!/bin/sh

DIR=tmp/certs
KEYCHAIN=$HOME/Library/Keychains/ios-build.keychain
KEYCHAIN_PASSWORD=`openssl rand -base64 48`
rm -rf $DIR
mkdir -p $DIR
echo $APPLE_CERTIFICATE | base64 -D > $DIR/apple.cer
echo $DISTRIBUTION_P12KEY | base64 -D > $DIR/dist.p12
echo $DISTRIBUTION_CERTIFICATE | base64 -D > $DIR/dist.cer
security create-keychain -p "$KEYCHAIN_PASSWORD" ios-build.keychain
security import $DIR/apple.cer -k $KEYCHAIN -T /usr/bin/codesign
security import $DIR/dist.cer  -k $KEYCHAIN -T /usr/bin/codesign
security import $DIR/dist.p12  -k $KEYCHAIN -T /usr/bin/codesign -P "$P12KEY_PASSWORD"
security list-keychain -s $KEYCHAIN
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN
rm -rf $DIR

PROVISIONING=~/Library/MobileDevice/Provisioning\ Profiles
mkdir -p "$PROVISIONING"
ios profiles:download:all --type distribution -u $APPLE_DEVELOPER_ID -p $APPLE_DEVELOPER_PASSWORD --team "$DISTRIBUTION_NAME"
echo "./App.mobileprovision -> $PROVISIONING_PROFILE.mobileprovision"
mv ./App.mobileprovision "$PROVISIONING/$PROVISIONING_PROFILE.mobileprovision"
rm -rf *.mobileprovision

adhoc.sh

Titanium ビルドして、Crashlytics/Submit しています。

#!/bin/sh

ti build --platform ios --target dist-adhoc --distribution-name "$DISTRIBUTION_NAME" --pp-uuid $PROVISIONING_PROFILE --output-dir ./
misc/Crashlytics.framework/submit $CLASHLYTICS_API_KEY $CLASHLYTICS_BUILD_SECRET -groupAliases $CLASHLYTICS_GROUP_ALIASE -notifications YES -ipaPath ./App.ipa

まとめ

というわけで、GitHub の adhoc ブランチにプッシュすると、テストしてビルドして配布するところまで Titanium でも自動化することができました。通常は develop ブランチで運用して、こちらはテストまで動く感じです。最終的には release ブランチで iTunes Connect へサブミットまでやっちゃいたい感じですね!