GitLab CIでiOSアプリをビルドし、ipaを配布する

GitLab CI で Xcode プロジェクトを自動ビルドし、 ipa を配布する手順を紹介します。

本記事では、既に GitLab CI を導入済みの Xcode プロジェクトを対象に、 ipa を生成、配布する手順を説明します。
Xcode プロジェクトに GitLab CI を導入する手順は、以下の記事で紹介していますのでそちらをご覧ください。

[GitLab CIでXcodeプロジェクトをCIする手順](http://qiita.com/enmtknt/items/83935c1137203e1c2c0f)

## artifacts
CI においてビルドが正常に完了した後に入手できる成果物をアーティファクトと呼びます。
GitLab CI では、コミットされたファイルを元にビルドを行い、成果物を zip ファイルとして GitLab 上から配布することができます。

## バージョン
ツールおよび OS は以下のバージョンを使用しました。

- GitLab 8.5
- Xcode 7.2.1
- OS X 10.11.2（ビルドマシン）

## 手順

### artifactsを使用するためのGitLabの設定
まず、 GitLab の artifacts の設定を有効にします。
詳しくは以下を参照してください。

[Introduction to build artifacts](http://doc.gitlab.com/ce/ci/build_artifacts/README.html)

### .gitlab-ci.yml の設定

プロジェクトの ``.gitlab-ci.yml`` にビルドスクリプトと成果物をアップロードする設定を記載します。

- ``before_script:`` 必要があれば、ビルド前の行程を記述します。
- ``script:`` にビルド手順とキーチェーンの設定を記述します。 `xcodebuild` の詳細な使用方法については別の記事を参照してください。
- ``artifacts:`` にアップロードしたいファイルのパスを指定します。

```.gitlab-ci.yml
job:
  before_script:
    - export LANG=en_US.UTF-8
    - security unlock-keychain -p $PATH_PHRASE /Users/$USER_NAME/Library/Keychains/login.keychain
    # Xcode7, Xcode8のプロジェクトが共存している場合、　使用するXcodeを明示的に指定
    - export DEVELOPER_DIR=/Applications/Xcode7.app/Contents/Developer
  script:
    - xcodebuild -scheme <スキーマ名> archive -archivePath /<任意のアーカイブ名> -configuration "Debug"
    - xcodebuild -exportArchive -exportOptionsPlist <export optionを記載するplist名>.plist -archivePath "<任意のアーカイブ名>.xcarchive" -exportPath "artifacts"
  artifacts:
    paths:
      - artifacts/<アプリ名.ipa>

```

### 環境変数の設定

上記 yamlで使用している環境変数（ここでは$PATH_PHRASE）を GitLab 上で設定します。

**Project > Settings > Variables > Secret Variables**

![secret_variables.png](https://qiita-image-store.s3.amazonaws.com/0/39720/93bb512d-1a9b-30bf-ac53-893d20ba0b82.png "secret_variables.png")


### ビルドマシン側の準備

当然ですが、ビルドマシンに Xcode がインストールされている必要があります。
またプロジェクト側で指定している Certificates, Provisioning Profile をマシンにインストールしておきます。

### ビルドの実施

前述の設定が正しく完了すれば、ビルド毎に ipa が作成できます。
**GitLab > Project > Builds** からダウンロードが可能です。

![marked.png](https://qiita-image-store.s3.amazonaws.com/0/39720/1307a747-7c47-fe84-5da6-ccd6a1460140.png "marked.png")


## ハマりやすいポイント

上記設定を行っても、うまくいかないケースがあるかもしれません。
躓きやすいポイントを2つ挙げておきます。

### User interaction is not allowed.

```
/usr/bin/codesign --force --sign 以下中略...
...
: User interaction is not allowed.

```

アーカイブ時の `codesign` 実行時に発生するエラーです。

本来であればユーザにパスワードの入力を求めるダイアログが表示されるものの、コマンドラインで実行しているためにダイアログを表示させることができずに発生します。
以下の記事を参考に2つの対応を行うことで、解決することができました。

[MacのJenkinsでiOSアプリをビルドするときにKeychain周りで失敗する時の対処](http://qiita.com/ginrou@github/items/6b81f7a48d47872e5a1e)


#### 1. 署名用秘密鍵をimportするときに /usr/bin/codesign にアクセス権限を与える

キーチェーンアクセスから、codesignから秘密鍵へのアクセスを許可します。

**キーチェーンアクセス > 左ペイン ログイン > 使用する秘密鍵 > 右クリック > 情報を見る > アクセス制御**

「これらのアプリケーションによるアクセスを常に許可：」に codesign を追加
もしくは「この項目の使用を全てのアプリケーションに許可」をチェック

![keychain.png](https://qiita-image-store.s3.amazonaws.com/0/39720/7f259538-0334-2921-4aea-2542927085ba.png "keychain.png")


#### 2. ビルドする際にkeychainのパスフレーズを入力するポップアップが出ないようにする

yaml ファイルの `- security unlock-keychain -p $PATH_PHRASE /Users/<ユーザ名>/Library/Keychains/login.keychain` という行が該当します。

### not supported: outside build directory 

```
Archiving artifacts...
WARNING: /Users/foobar/Desktop/hoge.ipa: not supported: outside build directory 
WARNING: /Users/foobar/Desktop/hoge.ipa: no matching files 
```

読んで字のごとくですが、 artifacts の対象ファイルはビルドディレクトリ内に作成しないとうまくアップロードされません。
ipa ファイルの作成場所をビルドディレクトリの外に指定した場合に発生します。
前述の yaml ファイルを参考にしていただければ特に問題ないかと思います。

## 参考URL

- [MacのJenkinsでiOSアプリをビルドするときにKeychain周りで失敗する時の対処](http://qiita.com/ginrou@github/items/6b81f7a48d47872e5a1e)
- [Introduction to build artifacts](http://doc.gitlab.com/ce/ci/build_artifacts/README.html)
- [Configuration of your builds with .gitlab-ci.yml](http://doc.gitlab.com/ce/ci/yaml/README.html)
- [GitLab Documentation - Variables](http://doc.gitlab.com/ce/ci/variables/README.html)