目次


モバイル DevOps: 第 1 回 UrbanCode Deploy を使用してエンタープライズ規模の iOS 継続的ビルドを実装する

アプリの複雑なライフサイクルに対応した、汎用の継続的インテグレーション・システムを作成する

Comments

私たちのチームが作成しているエンタープライズ iOS アプリの数は、100 を超えています。それぞれのアプリは、複数の言語にローカライズされて、数百の顧客のバックエンド・システムに統合されることになります。アプリ (およびクラウド統合用 API の各バージョンやソース・コード) を作成、機能強化、カスタマイズするのは非常に複雑なため、サポート・ツールが必要でした。

社内でモバイル DevOps の実装に取り掛かる場合は、継続的ビルドと、継続的テストが含まれていて、品質と効率性に主眼が置かれた、完全な継続的インテグレーション (CI) プロセスにフォーカスする必要があります。このチュートリアルでは、ビッグバンを試みるのではなく、CI を繰り返し実行できるよう、最初にフォーカスすべき点を説明します。また、スケーラビリティーを確実にするために、オーケストレーションを使用し、各種の設計決定に従う方法を詳しく説明します。

このチュートリアルは、完全な DevOps ライフサイクルの 1 つの側面である、アプリの継続的ビルドを、プロジェクトでサポートする方法を説明する連載の第 1 回です。以降のチュートリアルでは、大規模なアプリを実現するために、この実装を機能強化して保守しやすくする方法を説明します。

必要なもの: エンタープライズ規模の CI

私たちに必要だったのは、次の機能を備えたエンタープライズ CI システムです。

  • 多数の OSX Server インスタンスの間でのアプリと依存関係の全体を中央で調整する機能
  • Xcode の各種のベータ版リリースでアプリをサポートする機能
  • アプリのバージョンを API およびクラウド・ソース・コードのバージョンと関連付ける機能
  • 開発者によるセットアップと環境を正確に一致させる機能

私たちがプロジェクトに対して定めた要件に適合したのは、IBM UrbanCode Deploy という多用途のツールです。UrbanCode Deploy は、DevOps のすべての自動化と統合を調整するためにも、詳細なデプロイメント・タスクを実装するためにも使用することができます。継続的開発を始めようとしていて、複数のツールを実装する前のスプリント・ゼロが必要だとしたら、これは完璧なツールです。また、開発者向けのセットアップと環境をそのまま再利用できるため、自動化されたすべてのツールが、いずれも手動で実行したときと同じように動作します。UrbanCode Deploy 環境は手動で操作することも自動化することもできるため、CI 運用を簡単かつ迅速にトラブルシューティングすることができます。

すべてのコンポーネントは再利用可能であると同時にプロパティーを継承することから、UrbanCode Deploy に実装したパイプラインは複数のアプリと環境に拡張することができます。

iOS アプリのビルドを調整して DevOps パイプラインに通すために、次のものを実装しました。

要件

私たち開発者チームの要件は、次のとおりです。

  • 開発者がより多くの時間をコードの作成と品質の確保にかけられるようにする。
  • 開発者がコードの品質に関するフィードバックを受けられるようにする。
  • 開発者がコードの実行を常に管理できるようにする。

ビジネス要件は次のとおりです。

  • 品質の高いビルドにするためのテスト・メカニズムを用意し、テスト・リリースの前に適用する。
  • CI が実証されると拡張できるプロセスを実装する。

DevOps について、次の点を確実にする必要もありました。

  • 組織および開発チームの成熟度に適したレベルから開始する。
  • フローを妨げることなく、改善するプロセスを実装する。
  • 中央で調整されたエンタープライズ・レベルの CI プロセスのために、Xcode ボットを UrbanCode Deploy で置き換えると、成功することを証明する。

パイプラインの設計

CI パイプラインの設計を可視化するのは、重要なステップです。図の中で矛盾点や曖昧な部分を認識することによって、ソリューションに欠落している部分をすぐに明らかにすることができます。さらに、モデルの成熟度を即座に明らかにし、そのモデルをどれぐらいの期間で構築できるかを判断することもできます。

私たちのモバイル・アプリのパイプラインでは、限られた CI しかセットアップされていなかったため、コンポーネント・ツールを必要最小限にした単純なフローにして、プログラムの進化に併せて拡張できるようにする必要がありました。

パイプラインの設計を示す図
パイプラインの設計を示す図

このパイプラインでは、次のことが行われます。

  1. 開発者が Swift コードをコミットして IBM Bluemix DevOps Services に送信する。
  2. UrbanCode Deploy がメインの安定ブランチで Git タグをモニタリングし、Mac Mini 上の Xcode で自動的にビルドを行い、Slack を介してチームに通知する。
  3. 関連付けられた端末またはシミュレーターにビルドがデプロイされる。
  4. モバイル・アプリに対してユニット・テストとインスツルメント・テストが自動的に実行され、その結果が Slack を介してチームに通知される。

このソリューションの優れた点

この単純な実装では、パイプラインによって開発者がコードの作成を続行できると同時に、Git タグによってビルドのタイミングを制御できるようにします。品質を確保するためのプロセスでは、開発サイクルの早い段階で通信メカニズムを通じてフィードバックを提供して、開発者をサポートします。

さらに、すべてのコンポーネントは再利用可能であると同時にプロパティーを継承することから、UrbanCode Deploy に実装したパイプラインは複数のアプリと環境に拡張することができます。この CI で使用するコンポーネントは、1 つのモバイル・アプリでも 30 のモバイル・アプリでも変わりません。そのため、これらのコンポーネントを基礎として、その後の拡張を行うことができます。スケールアップする際には、フックと新しいアプリに応じた環境を追加することで、DevOps スプリントを開始することができます。

詳細

このパイプラインを構築するために、私たちは UrbanCode の原則に従って、再利用可能なコンポーネントとアプリの階層型アーキテクチャーを使用して、ビルド、デプロイ、テスト、通知の実行を実装することにしました。そのために、UrbanCode Deploy 内でアプリ・レベルおよび環境レベルでプロパティーを実装し、コンポーネントを再利用できるようにしました。

システム・アーキテクチャーの図
システム・アーキテクチャーの図

コンポーネントは、以下の共通ドメイン別に分離しました。

  • ビルド
  • ユニット・テスト
  • デプロイ (後で実際の端末に実装)
  • フック (新しい概念)

フック: 私たち独自の概念

フックは基本的に、UrbanCode Deploy コンポーネント構成の組み込み機能を利用する空のコンポーネントです。フックを使用することで、Git を統合し、新しいタグをポーリングし、環境の中でアプリのプロセスをトリガーすることができます。

フックの目的は、ビルド・スタイルとリポジトリーとの統合を再現して、アプリのプロセスを開始することです。こうすることで、実際のコンポーネント・プロセスを再実装する必要がなくなります。この「トリック」により、基本コンポーネントが確実に再利用可能になるというわけです。

次のスクリーンショットを見ると、フックにセットアップしたコンポーネントのプロパティーがわかります。私たちは標準のデフォルト・プロパティーを選び、Git が統合されるようにして、正規表現を追加しました。そして、Git リポジトリーが UrbanCode Deploy の Code Station (UrbanCode 成果物リポジトリー) に取り込まれないようにしました。最後に、実行対象のアプリのプロセスと環境を選択しています。

「Basic Settings (基本設定)」ダイアログ・ボックスのスクリーンショット
「Basic Settings (基本設定)」ダイアログ・ボックスのスクリーンショット

概念上、フックは UrbanCode の初心者にとって大きな一歩となります。この連載の以降のチュートリアルでは、コンポーネント・テンプレートを使用してフックを実装する方法を説明します。

ビルド

IBM UrbanCode Deploy 用 Apple Xcode プラグインを使用すると、コンポーネントのビルドはとても簡単です。

「Edit Properties (プロパティーの編集)」ダイアログ・ボックスのスクリーンショット
「Edit Properties (プロパティーの編集)」ダイアログ・ボックスのスクリーンショット

特定の Xcode コマンド・ライン上でビルドをトリガーするために私たちが使用したのは、xcrun ステップです。これにより、一部のモバイル・アプリに古いバージョン (またはベータ版) への依存関係がある場合に備え、ビルド・マシンに複数の Xcode をインストールできるようにしました。Apple Xcode プラグインを使用すると、プロジェクトのワークスペースの中で指定された設定を変更する必要がある場合、コマンド・ライン・パラメーターを追加することもできます。

ユニット・テスト

UrbanCode Deploy で Xcode プラグインを使用してユニット・テストを実行するために指定する必要があるパラメーターは、スキーマやプロジェクト・ディレクトリーなどといった 2、3 のパラメーターのみです。しかし、私たちはユニット・テストをさらに有効活用して、ユニット・テストからのフィードバックを開発者に提供したかったため、事後処理を追加しました。具体的には、関連するすべてのテスト・スイートを取得して配列に渡し、その配列をフラット化して、結果をテキストのストリングとして保管し、通信システム (Slack) に出力できるようにするという処理です。

commandOut.print("\n==== Starting post processing ====\n");
properties.put("Status", "Success");
arrTestStatus = new java.util.ArrayList();
commandOut.print("\nEstablishing Regular Expression\n")
scanner.register("^Test Suite.*passed.*", function(lineNumber, line){
    //commandOut.print(line);
    //commandOut.print("\n");
    arrTestStatus.add(line);
});
scanner.register("^Test Suite.*failed.*", function(lineNumber, line){
    //commandOut.print(line);
    //commandOut.print("\n");
    arrTestStatus.add(line);
});
scanner.scan();
if (arrTestStatus == null) {
    properties.put("dev.test.results","");
}
else {
    var strTestStatus = arrTestStatus.toString();
    //Multiple slashes gets used as its parsed twice through the use of a plugin
    // \\\\ becomes \\ which becomes \
    var strTestResults = strTestStatus.replaceAll("\.,","\\\\n");
    var strStringLength = strTestResults.length();
    strTestResults = strTestResults.substring(1,strStringLength - 1);
    properties.put("dev.test.results",strTestResults);
    commandOut.print(strTestResults);
}
var exit = properties.get('exitCode');
if (exit == 0) {
    properties.put('Status', 'Success');
}
else {
     properties.put('Status', 'Failure');
}
commandOut.print("\n==== End post processing ====\n");

以下に、開発者が受信するメッセージの一例を示します。

メッセージの例のスクリーンショット
メッセージの例のスクリーンショット

次のステップ

私たちが実装しているモデルでは、アプリに環境を簡単に追加し、パイプラインを強化して品質ゲートを組み込んで、CI テストが特定のしきい値を超えてからでないと、ビルドしたアプリを次の環境にデプロイできないようにすることができます。この連載の以降のチュートリアルでは、これらの改善について取り上げ、初期のモバイル・アプリでは対処できないほどワークロードが増大した場合に、テンプレートから取り出してコンポーネント化したアプリを実装する方法を説明します。

品質ゲートの一例は、私たちがそうしているように、テスト環境にデプロイする前にユニット・テストを実行するだけでなく、UI インスツルメント・テストも組み込んで、特定の重要な機能が正常に動作すること、そしてビルドに重大度 1 の欠陥がないことを確実にすることです。アプリへのログインは (アプリへログインすることにより、アプリがバックエンド API に接続されます)、そのような重要な機能の一例です。この場合の次の環境が、テスト・フライトでのテスター・チームへのデプロイメント環境であるとしたら、次のように対処することができます。

  • ある程度の品質のビルドだけをテスターに提供するように、システムを自動的に拡張する
  • 承認フェーズを組み込んで、誰かが配布を承認しなければならないようにする

あるいは、xctool を使用してユニット・テストからの情報を増補し、JUnit レポートのようなフォーマットにレポートを変換することもできます。


ダウンロード可能なリソース


関連トピック


コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Mobile development, DevOps, Cloud computing
ArticleID=1008738
ArticleTitle=モバイル DevOps: 第 1 回 UrbanCode Deploy を使用してエンタープライズ規模の iOS 継続的ビルドを実装する
publish-date=06252015