[BITRISE][iOS] BITRISE によるiTunes Connect へのDeploy

遅くなりましたが、[前回](https://qiita.com/a_jike/items/a97933a70cd4946d068e)の続きです。
BITRISE でiTunes Connect にアップロードするworkflowについて書きます。

### :warning: 初回アップロード
未リリースのストアにないアプリはこのworkflowを使ってアップロードすることができません。初回はXcodeから手動でアップロードする必要があります。

# :wrench: 設定
## :page_facing_up: YAML
まずはymlファイルの設定箇所抜粋。

```yaml

steps:
    - activate-ssh-key@3.1.1:
        run_if: '{{getenv "SSH_RSA_PRIVATE_KEY" | ne ""}}'
    - git-clone@3.5.2: {}
    - cache-pull@1.0.0: {}
    - certificate-and-profile-installer@1.8.8: {}
    - cocoapods-install@1.7.1: {}
    - xcode-archive@2.3.1:
        inputs:
        - project_path: <WORKSPACE_NAME>.xcworkspace
        - scheme: <SCHEME_NAME>
        - is_clean_build: 'yes'
        - configuration: Release
        - export_method: app-store
        - team_id: <TEAM_ID>
    - cache-push@1.1.4: {}
    - deploy-to-itunesconnect-shenzhen@2.1.2:
        inputs:
        - password: "$ITUNES_CONNECT_PASSWORD"
        - app_id: "$ITUNES_CONNECT_APP_APPLE_ID"
        - itunescon_user: "$ITUNES_CONNECT_USER_APPLE_ID"
    - ipa-info@1.0.1: {}
    - script@1.1.5:
        inputs:
        - content: |-
            #!/usr/bin/env bash
            # fail if any commands fails
            set -e
            # debug log
            set -x

            # write your script here

            buildNumber="$IOS_APP_VERSION_NAME ($IOS_APP_VERSION_NAME.$BITRISE_BUILD_NUMBER)"
            appName=$IOS_APP_NAME
            bundleId=$IOS_IPA_PACKAGE_NAME
            workflowId=$BITRISE_TRIGGERED_WORKFLOW_ID
            echo "$BITRISE_APP_TITLE $buildNumber $workflowId"
            message="The workflow \"$workflowId\" was succeeded!\n$appName $buildNumber\n$bundleId\n$BITRISE_GIT_MESSAGE"

            envman add --key SLACK_MESSAGE_BODY --value "$message"
            echo "SLACK_MESSAGE_BODY is $SLACK_MESSAGE_BODY"

            # or run a script from your repository, like:
            # bash ./path/to/script.sh
            # not just bash, e.g.:
            # ruby ./path/to/script.rb
    - slack@2.6.3:
        is_always_run: false
        inputs:
        - message: "$SLACK_MESSAGE_BODY"
        - emoji: ":bitrise:"
        - webhook_url: https://hooks.slack.com/services/<SLACK_WEBHOOK_URL>
        - channel: "#<SLACK_CHANNEL_NAME>"
        - from_username: Bitrise CI
        - image_url: ''
    envs:
    - ITUNES_CONNECT_APP_APPLE_ID: '<APPLE_ID>'
```
以下は適当にご自身のものと置き換えてください。

```
<TEAM_ID> ... チームID
<SLACK_WEBHOOK_URL> ... Slack Webhook URL で発行したURL(ID)
<SLACK_CHANNEL_NAME> ... Slack通知するチャンネル名
<APPLE_ID> ... アップロードに使用するApple ID
<WORKSPACE_NAME> ... xcworkspaceの名称
<SCHEME_NAME> ... スキーム名
```

## :bookmark_tabs: 説明
`Cocoapods Install` ステップまでは[前回](https://qiita.com/a_jike/items/a97933a70cd4946d068e)のworkflowと同じです。
![step_first.png](https://qiita-image-store.s3.amazonaws.com/0/156085/68b5dfd4-f68b-842d-9d84-8fa49f06ce23.png)

`Run CocoaPods Install` の次に`Xcode Archive & Export for iOS` ステップを追加します。
Archive の前に `Xcode Test` ステップを入れても良いかもしれませんが、Debugビルドと実装が同じなら特に意味はないので省略します。
![step_last.png](https://qiita-image-store.s3.amazonaws.com/0/156085/937cbade-ddd9-797e-5931-3000a987bad1.png)

Archive後に `Deploy to Bitrise.io`を追加しておくことでipaやdsymをチェックしたい時に役立ちます。もちろん非公開設定で。

iTunes Connectへのアップロードは `Deploy to iTunesConnect` か `Deploy to iTunesConnect shenzen` ステップが使用できます。
前者の`Deploy to iTunesConnect` の方が色々設定できるので便利そうですが、
Apple IDの２段階認証を有効にしている場合、エラーになりコケてしまいますので、後者の **`Deploy to iTunesConnect shenzen`** を使用しましょう。

![settings.png](https://qiita-image-store.s3.amazonaws.com/0/156085/db93ccb3-ec9e-0023-21e5-56713aee5128.png)
`Deploy to iTunesConnect shenzen` の設定はシンプルで、

- IPA path  
Archiveでoutputされた$BITRISE_IPA_PATHを使用します。
- iTunes Connect: User Apple ID (email)  
Secretsに定義したApple IDを指定します。
- iTunes Connect: Password  
Secretsに定義したApple ID のパスワードを指定します。
- iTunes Connect: App Apple ID  
アプリのApp Store IDを指定します。（例ではEnv Varsに定義している変数名を指定しています）

そのあとは[前回](https://qiita.com/a_jike/items/a97933a70cd4946d068e)と同じでSlackに通知します。
あとは作成したworkflowと適切なbranchを選択して `Start Build` してください。

# :triangular_flag_on_post: チェックポイント
基本的にはエラーログ見て解決しますが、見ても良くわからないこともあるためざっと記載しておきます。
- **Provisioning Profile** が本番アプリのものになっているか
- **p12ファイル** が本番アプリのものになっているか
- `Xcode Archive ステップ > Export options > Select method for export` が **app-store** になっているか
- `Xcode Archive ステップ > Export options > The Developer Portal team to use for this export` が本番アプリの **Team ID** になっているか（DebugビルドとReleaseビルドで別のApple IDを使用している場合など）
- 前述の通りApple IDが２段階認証有効になっていたらiTunes ConnectへのDeployステップは `Deploy to iTunesConnect shenzen` にする必要があります

# 感想
ボタンを押すだけでiTunes Connectへアップロードできるようになり、割とマメにリリースしているアプリであれば尚の事導入しておいて損はないと思います:thumbsup_tone1:

変更履歴
2018/03/16 14:31 `Deploy to iTunesConnect shenzen` の設定について追記。

---
https://www.bitrise.io/

```
                              MMMMMMMMMMMM                                
                              MMMMddddNMMM                                
                              MMMM    mMMM                                
                              MMMMssssNMMM                                
                              MMMMMMMMMMMM                                
                                 sMMMMd                                   
                                 yMMMMd                                   
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMdhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhdMMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
     MMMMM                                                      MMMMMM    
  MMMMMMMM                                                      MMMMMMMM  
 MMM' MMMM           .yy.                        .yy.           MMM  'MMM 
MMMh  MMMM         .MMMMMMl.                  .lMMMMMMM.        MMM   hMMM
MMM   MMMM       .MMMMMmNMMMl.               .MMMMNmMMMM.       MMM    MMM
MMMs  MMMM       .hhhh   yhhh.               .hhhh   hhh+       MMM   sMMM
 MMM. MMMM                                                      MMM  .MMM 
  MMMNMMMM                                                      MMMMNMMM  
    MMMMMM                                                      MMMMMM    
      MMMM                                                      MMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
      MMMM                                                      MMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
      MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM      
```