web-dev-qa-db-ja.com

iOS:夜間の内部ビルド(TestFlight)と頻繁なクライアントビルドにJenkinsを使用する

私はiOS開発者で、小さな代理店で働いています。私は現在、自分が唯一の開発者であるいくつかの小さなプロジェクトに取り組んでいます。最近、Jenkinsサーバーを取得しましたが、各プロジェクトは、その使用方法については自分で対処する必要があります。

ビルドの作成と配布に使用したいと思います。私の理想は:

  1. すべてのコミットは、HTTPでアクセス可能な場所に配置される単一のIPAとして構築されます。 (最新のものを保持するだけで十分です。そうしないと、ディスクがいっぱいになります。一部のアプリは500 MB以上です)。
  2. 1日1回ビルドを作成し、内部プロビジョニングプロファイルで署名し、バージョン番号の末尾にビルド番号を付加して、社内のTestFlightチームに送信します。
  3. 手動でプロンプトが表示されると、最新のコミットが作成され、手動で指定されたバージョン番号が付与され、クライアントのプロビジョニングプロファイルで署名され、TestFlightに送信されます。

私はジェンキンスにかなり新しいです。サーバーをセットアップした開発者は私たちのプロジェクトの1つでサーバーを実行しているので、Xcodeビルドを実行するために適切なものがインストールされています。私は彼がユニットテストを実行するためだけに使用していると私は信じています。コード署名、IPAの作成、またはTestFlightに関することは何もしていません。

だから私の質問:

  • 3つの異なる種類のビルドをリストしました。ジェンキンスはそれにどのように対処していますか? Jenkinsプロジェクトの構成に「ビルドトリガー」セクションがあるようですが、異なるタイプのビルドについては記載されていないようです。 「App X(continuous)」、「App X(nightly)」、「App X(client)」という複数のJenkinsプロジェクトをセットアップするだけですか?
  • Jenkinsを使用してプロビジョニングプロファイルを指定するにはどうすればよいですか?方法がない場合は、Xcodeプロジェクトで別の構成を作成できると思います…
  • 他の誰かがJenkinsを使用して、アプリのベータビルドのリリース(つまり、ビルドとTestFlightへのプッシュ)を実際に行いましたか?それは良い考えですか?それとも手動で続行する必要がありますか?
4
Amy Worrall

良いニュースは、これがすべて可能であることです。悪いニュースは、それがすべて手動であるということです。あなたは多くの夕方の微調整を燃やします、そしてそれが最終的に節約された時間で成果を上げるかどうかは必ずしも事前に知ることができません。

これは、JenkinsとXcodeをいじる過去数か月の間に学んだことの情報ダンプです。

Jenkins用のXcodeプラグインとTestflightプラグインがあります。それらを超えた後、ロジックのすべてのチャンクはShell/Ruby/Perl/python/whateverスクリプトになります。

たとえば、追加のスキームなどの単一の変数、または別の$ DEVELOPER_DIRを除いて、メインのビルドと同じである追加の密接に関連するビルドを作成するためにマルチ構成プロジェクトが必要であることに気づいたら、すぐにXcodeプラグインを使い果たしました。ベータXcode。一般的なプラグインによって公開されるフィールドにこれらの構成パラメーターを渡す方法はありませんでした。そこで、Xcodeプラグインがxcodebuildをどのように操作したかを把握するためにジョブログを確認し、それをスクリプトフェーズに移植しました。

プラグインが私のためにしていた別のこととして、任意のIDまたはプロビジョニングプロファイルからの署名は、別のスクリプトフェーズになりました。 SIGN_WITH_DEVELOPER_IDのようなブールジョブパラメーターは、次のようなスクリプトフェーズと通信します。

if [ "${SIGN_WITH_DEVELOPER_ID}" = true ]; then
  echo "Re-signing build with Developer ID"
  $WORKSPACE/ci-scripts/developer-id-sign --path [...]
fi

それが呼び出すスクリプトは、次のようなものに要約されます。

/usr/bin/security unlock-keychain -p yourkeychainpassword ~/Library/Keychains/login.keychain
/usr/bin/codesign -f -vv -s 'Developer ID Application' path/to/binary 2>&1

特定のジョブによるすべてのビルド出力をアップロードする必要がなくなるとすぐに、Testflightプラグインよりも大きくなります。代わりに、別のジョブパラメータによって通知されたTestflightのアップロードAPIをプログラムで呼び出すことをお勧めします。

(Testflightのアップロードプロセスはまだ完全に自動化していません。これは、主にTestflightを使用してクライアントに配布しているためです。また、デフォルトで間違ったプロファイルになっている、または転送中に破損したクライアントビルドを送信するのに1、2回の時間がかかりました。 。したがって、私はそれらを手作業で精査します。ただし、Testflightにアップロードするプロセスは、単に ビルドサーバーでcurlを呼び出す の問題です。これを行わなければ、実行可能であると確信していますJenkinsがMacアプリの実際のリリースで dsymsをHockeyAppにアップロードする とほぼ同じことを行っているので、それはうまく機能しています。)

ジョブを複製せずに密接に関連する複数のビルドを実現するための最良の方法として、マルチ構成ジョブをお勧めします。これにより、関連するジョブの同期を維持する必要があるため、ハウスキーピングがたくさん作成されます。複数の構成ジョブは、すべてのビルドバリアントで毎回実行する必要がない限り、一般にプラグインと互換性がありません。このように、マルチ構成ジョブは、初期の複雑さと将来の柔軟性との間のトレードオフです。

ただし、概説した3つのビルドは実際にはそれほど異なっておらず、厳密にマルチ構成ジョブである必要はありません。着陸したコミットごとに開始される継続ビルドがデフォルトです。 CFBundleVersionを更新するかどうか、および/または特定のディストリビューションでTestflightにアップロードするかどうかは、実行時の構成の決定であり、ジョブパラメーターとそれらを監視するスクリプトフェーズによって、または最初からビルドを開始するロジックによって制御できます。

その他の考え:

  • スクリプトフェーズでシバン行を指定しないと、/bin/bash -xe動作が想定されます。これにより、各行がログに出力され、ゼロ以外の戻り値が検出されるとすぐにビルド全体が失敗します。この組み合わせは通常必要なものであり、トラブルシューティングの手間を軽減します。

  • Bashが気に入らず、他のスクリプト言語で作成する場合は、終了コードに注意して、自分でbash -xeの動作をエミュレートしてください。プロジェクトにアタッチするスクリプトに重要なロジックを埋め込み、条件付きでJenkinsから、できるだけ短く宣言的なスクリプトフェーズを介して呼び出すことが望ましいと思いました。

  • 雑草に深く入り込むことなく、Jenkinsがソースバージョン管理に何か(更新されたバージョン番号など)を書き込むことはトリッキーであり、CIコードの匂いのようなものと見なされます。また、毎晩のビルドにも非常に便利ですが、それを引き出すための十分に認可された方法を見つけていません。 bundleversionを更新してスクリプトを作成し、夜間のビルドを開始し、ビルドアーティファクトをフェッチし、ファイルサーバーに保存し、Dropboxにコピーをアップロードします。このシナリオでは、Jenkinsがウェイクアップする前に更新されたバージョン番号が設定されています。これは、Jenkinsがビルドの途中でそれを実行しようとするよりも望ましい方法です。)

  • それは話の焦点では​​ありませんが、いくつかの例がWWDC 2012セッション404で放り出されたのを見て、マルチ構成ジョブを含む多くのJenkins機能に信仰を持ちました。

  • Macビルドノードを備えた仮想マシン(おそらくLinux)でJenkinsを実行して、Xcodeの大げさな作業を行うことをお勧めします。私はMacの男ですが、JenkinsはLinuxで最も徹底的にテストされており、毎週のようなアップデートは簡単に適用でき、問題が発生した場合は作業スナップショットにロールバックできます。 Linux VMはオーバーヘッドが少ないため、時間の投資により、問題が発生する新しいバージョンに初めて更新したときに、その費用を支払うことができます。

長期的には、Jenkinsの信頼性が低いためではなく、CIが会社のワークフローに永続的に追加され、遅かれ早かれすべてが失敗するため、問題が発生します。

6
Nathaniel Irons