BitriseにContributeをする

# BitriseにContribute
「[Get Info on Android App Bundle](https://www.bitrise.io/integrations/steps/get-info-on-android-app-bundle)」というIntegrationをBitriseにContributeしました。Android App Bundle(.aab)から情報を抽出できます。
![Get Info on Android App Bundle](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125724/eb4e429f-52e8-4ac9-2f6a-69a06c583716.png)

# 背景
Bitriseでは、APKから情報を抽出するステップはいくつか公開されているものの、Android App Bundle(.aab)からパッケージ名やバージョンを抽出するワークフローステップが見当たらなかったため、自作のスクリプトを作成して抽出していました。
主にFirebase App DistributionやDeploygateでの配布メッセージや、Slackへのビルド完了通知に含めるためです。

しかしながら、Google Playでの公開はAndroid App Bundleがデファクトになる昨今、同じようなことで悩む開発者の助けになれば良いと思い、BitriseにContributeにできないかと考えたのがきっかけです。
つまり、この記事は宣伝、あとはBitriseが「もっと便利になると良いな」という思いから記述されています。

# Android App Bundleからパッケージ名やバージョンを抽出する
Android App Bundle(.aab)とは、[Google公式](https://developer.android.com/guide/app-bundle)の記載がある通り、アプリのコンパイル済みコードとリソースがすべて含まれた公開形式のことで、Google PlayにAndroid App Bundle形式でバイナリをアップロードすると、Google Playからデバイスごとに最適化されたAPKを配信してくれるようになります。

このAndroid App Bundleを解析するには[bundletool](https://developer.android.com/studio/command-line/bundletool)を使用します。
自作のスクリプトでは、このbundletoolからManifest情報をダンプして、パッケージ名やバージョンを抽出しています。以下はBitriseで設定していたスクリプトの一部です。

```bash
#!/usr/bin/env bash
# 前略：bundletoolの準備など
ANDROID_VERSION_NAME=`$BUNDLE_TOOL_CMD dump manifest --bundle $BITRISE_APK_PATH --xpath /manifest/@android:versionName`
ANDROID_VERSION_CODE=`$BUNDLE_TOOL_CMD dump manifest --bundle $BITRISE_APK_PATH --xpath /manifest/@android:versionCode`
# 後略：Bitriseの環境変数への設定など
```

# Bitrise用のワークフローステップを作成する
前述の自作スクリプトをカスタマイズして、Bitrise用のワークフローステップを自作するには、[Bitrise公式](https://devcenter.bitrise.io/contributors/create-your-own-step/)を参照すれば、手順が書いてあります。2021年時点だと日本語翻訳がまだのようですが、大まかな流れは次の通りです。既に公式のドキュメントを読めば困らない内容については割愛させていただきます。

1. Bitrise CLIのインストール、CLIの準備
1. BitriseStepプラグインを使用して空のステップを作成
1. step.ymlの編集
1. step.sh(メイン処理)の記述
1. bitrise.ymlの編集とテスト
1. GitへPush＆バージョン管理
1. Bitrise StepLibへの共有

Bitrise用のワークフローステップのメイン処理はGo、Bashのどちらかで記述できますが、今回はBashで記述しています。

## Bitrise CLIのインストール
[Bitrise CLIのインストールと更新](https://devcenter.bitrise.io/jp/bitrise-cli/installation/)をご確認ください。

## BitriseStepプラグインを使用して空のステップを作成
[Creating the Step](https://devcenter.bitrise.io/contributors/create-your-own-step/)をご確認ください。
プラグインの手順にしたがって入力すると、次のようなファイルが作成されます。

1. Who are you / who's the author? [nosaka] : [Enter]
1. What's the title / name of the Step? : `Get Info on Android App Bundle`
1. Please provide a summary : bitrise : `Extracts the version name and the version code from the Android App Bundle(aab).`
1. Please provide a description : `Extracts the version name and the version code from the Android App Bundle(aab). Android Application Package (apk) is not supported.`
1. What's the primary category of this Step? : `[2] : artifact-info`
1. Which toolkit (language) would you like to use? : `[1] : bash`
1. Will you host the source code on GitHub? [YES/no]: `YES`
1. What's your GitHub username (user/org where you'll register the step's repository)? : `nosaka`

```bash
$ ls -1
LICENSE
README.md
bitrise.yml
step.sh
step.yml
```

## step.ymlの編集
ステップを作成すると、入力情報をもとにstep.ymlが生成されます。
これをもとに編集していくのですが、、今回のContributeでは次の部分を編集しました。

- `project_type_tags`を追加
  - 今回、Androidが対象のため、`android`を設定します。
- `deps`セクションを削除
  - ステップの依存関係で`apt-get`や`brew`が必要な場合は定義が必要ですが、今回は不要のため削除します。
- `input`セクションに以下のこのステップを実行する上で必要な入力環境変数を追加
  - `$BITRISE_AAB_PATH`: Android App Bundleのパス
- `output`セクションに以下のこのステップで作成される出力環境変数を追加
  - `ANDROID_VERSION_CODE`: Androidアプリのバージョンコード
  - `ANDROID_VERSION_NAME`: Androidアプリのバージョン名
  - `ANDROID_PACKAGE_NAME`: Androidアプリのパッケージ
  - `ANDROID_MIN_SDK_VERSION`: AndroidアプリのMin Sdk Version
  - `ANDROID_TARGET_SDK_VERSION`: AndroidアプリのTarget Sdk Version

各種ステッププロパティーについての詳細は[こちら](https://devcenter.bitrise.io/jp/bitrise-cli/step-properties/)をご確認ください。

## step.sh(メイン処理)の記述
次に、step.ymlで定義した入力する環境変数、出力する環境変数をもとに、実際のメイン処理を記述していきます。
処理概要は次の通りです。

1. 入力環境変数`$BITRISE_AAB_PATH`のファイル存在チェック
1. bundletoolで指定されたAndroid App BundleのManifestをダンプ、情報を抽出
1. 抽出した情報を環境変数に出力

このとき、bundletoolは実際のBitriseのパッケージ管理システムにないため(※)、あらかじめ[Git上からダウンロード](https://github.com/google/bundletool/releases/tag/1.4.0)後、プロジェクト内に配置しておきます。

```bash
$ ls -1 ./tools/
bundletool
bundletool-all-1.4.0.jar
```

## bitrise.ymlの編集とテスト
bitrise.ymlも同様に、ステップを作成すると、入力情報をもとに生成されます。
生成されたbitrise.ymlの`workflows::test`セクションにテストを記述していきます。

テストでは、デフォルトだと`change-workdir`のステップがあり、`./_tmp`ディレクトリが作業ディレクトリになるように指定されています。
こちらのディレクトリに後ほどテストで必要になるAndroid App Bundleのファイルを配置しておきます。


```yml
- change-workdir:
    title: Switch working dir to test / _tmp dir
    description: |-
      To prevent step testing issues, like referencing relative
      files with just './some-file' in the step's code, which would
      work for testing the step from this directory directly
      but would break if the step is included in another `bitrise.yml`.
    run_if: true
    inputs:
    - path: ./_tmp
    - is_create_path: true
```
```bash
$ ls -1 ./_tmp/
app.aab
```

`path::./`で実際の今回記述したステップが実行されます。
このセクションの`input`にstep.ymlで定義した入力する環境変数に対して、テスト用のAndroid App Bundleファイルのパスを指定します。
`$BITRISE_STEP_SOURCE_DIR`とはBitrise CIによって自動的にエクスポートされる、ステップの実行ディレクトリのパスが設定された環境変数です。

```yml
- path::./:
    title: Step Test
    description: |-
      The example input has a default value,
      you can overwrite it if you want to, just like we did below,
      but the step would use the default value specified in the `step.yml`
      file if you would not specify another value.
    run_if: true
    inputs:
    - aab_path: "$BITRISE_STEP_SOURCE_DIR/_tmp/app.aab"
```

`script`でステップの結果、出力用の環境変数が正しく設定されるか確認します。

```yml
- script:
    inputs:
    - content: |
        #!/bin/bash
        echo "ANDROID_VERSION_NAME:=${ANDROID_VERSION_NAME}"
        echo "ANDROID_VERSION_CODE:=${ANDROID_VERSION_CODE}"
        echo "ANDROID_PACKAGE_NAME:=${ANDROID_PACKAGE_NAME}"
        echo "ANDROID_MIN_SDK_VERSION:=${ANDROID_MIN_SDK_VERSION}"
        echo "ANDROID_TARGET_SDK_VERSION:=${ANDROID_TARGET_SDK_VERSION}"
```

これで、作成したステップのテストができるようになりました。
以下のコマンドで正しく完了していたらテストOKです！ お疲れさまでした。

```
$ bitrise run test
...
+------------------------------------------------------------------------------+
|                               bitrise summary                                |
+---+---------------------------------------------------------------+----------+
|   | title                                                         | time (s) |
+---+---------------------------------------------------------------+----------+
| ✓ | Switch working dir to test / _tmp dir                         | 5.67 sec |
+---+---------------------------------------------------------------+----------+
| ✓ | Step Test                                                     | 3.36 sec |
+---+---------------------------------------------------------------+----------+
| ✓ | script                                                        | 1.06 sec |
+---+---------------------------------------------------------------+----------+
| Total runtime: 10.09 sec                                                     |
+------------------------------------------------------------------------------+
```

## GitへPush＆バージョン管理
テストができたら、自分のリモートリポジトリにGitをPushします。その後、セマンティックバージョニング（MAJOR.MINOR.PATCH)でタグ、リリースを作成します。
詳細は[こちら](https://devcenter.bitrise.io/contributors/testing-and-versioning-your-steps/)に記載があります。
![Git_Version.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125724/169be864-e2b2-05e7-698d-c4138b4f09a6.png)

## Bitrise StepLibへの共有
詳細は[こちら](https://devcenter.bitrise.io/contributors/sharing-steps-with-all-bitrise-users/)に記載がありますが、今回のContributeの手順をおさらいするかたちで記載させていただきます。


1. [BitriseStepLib](https://github.com/bitrise-io/bitrise-steplib)リポジトリをフォークします。今回のフォークしたURLは「https://github.com/nosaka/bitrise-steplib」です。
1. フォークした[BitriseStepLib]をローカルで利用できるように、BitriseStepプラグインでフォークしたリポジトリを指定します。
    - `$ bitrise share start -c https://github.com/nosaka/bitrise-steplib`
1. BitriseStepプラグインでステップID、[GitへPush＆バージョン管理](#GitへPush＆バージョン管理)で作成したタグを指定して、フォークしたStepLibリポジトリに追加します。今回のステップID、タグはそれぞれ「get-info-on-android-app-bundle」「0.0.1」です。
    - `$ bitrise share create --tag 0.0.1 --git [step-git-uri].git --stepid get-info-on-android-app-bundle`
1. 追加後に`$ bitrise share audit`コマンドでヘルスチェックを行います。
1. 問題なければ、`bitrise share finish`で終了します。


### Pull Request
Pull Requestは次のようにPR Templeteにそって、次のように行います。参考までに、今回のPull Requestは[こちら]((https://github.com/bitrise-io/bitrise-steplib/pull/2860))になります。
![Pull Request](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125724/e036e7f9-ede2-96ed-1afc-a9e3523fe83c.png)

これで、完了です。
レビューが承認されれば、これでもれなくBitriseのIntegrationに自分の作ったステップが公開されます！

# おわりに
今回、はじめてBitriseにContributeをしましたが、公式の資料だけでほぼ迷わずに公開できました。

Bitriseユーザのプロジェクトの中には、自分のワークフローだけでしか使用していない宝石のように素晴らしいScriptがたくさんあるかと思います。
私はBitriseが大好きで、そのような素晴らしいエンジニアの方にも自分のとっておきのステップをシェアしてくれると嬉しいと思い、記事を投稿させていただきました。

本作業のソースコードはこちらの[Github](https://github.com/nosaka/bitrise-step-get-info-on-android-app-bundle)で管理されています。よろしければご覧ください。

お粗末さまでした。