MIXI DEVELOPERS NOTE
⚙️

Bitrise でカスタムステップを作成する

2022/12/05に公開

この記事は MIXI DEVELOPERS Advent Calendar 2022 の 5 日目の記事です。

最近、業務で Bitrise のカスタムステップを作成する機会がありました。
Bitrise のカスタムステップを使用すると、 bash や Go を使用して独自のビルドステップを実行することができるようになります。
公式のステップでは機能が足りないと思った時に作ってみると良いかもしれません。

今回開発していて、Bitrise のカスタムステップ作成についての文献が少なかったので、紹介がてら作成する方法を書こうと思います。

情報

公式のドキュメントはこちら↓
https://devcenter.bitrise.io/en/steps-and-workflows/developing-your-own-bitrise-step/developing-a-new-step.html

ちなみに、公式の日本語のドキュメントは翻訳が怪しいので、英語版を読むと良いです。

作り方

基本的には公式のドキュメントの通りに作れば良いです。
全体の流れは以下。

  1. BitriseCLI のインストール
  2. bitrise コマンドでステップの雛形を作成
  3. 処理を諸々書く
  4. bitrise run test でテストを実行
  5. workflow への組み込み

もう少し細かく見ていきます。

1. BitriseCLI のインストール

まずは BitriseCLI をインストールします。
https://devcenter.bitrise.io/ja/bitrise-cli/installing-and-updating-the-bitrise-cli.html

homebrew の場合は以下でインストール

brew install bitrise

バイナリを直接落としてくる場合はこちら

curl -fL https://github.com/bitrise-io/bitrise/releases/download/1.38.0/bitrise-$(uname -s)-$(uname -m) > /usr/local/bin/bitrise
chmod +x /usr/local/bin/bitrise

インストールが終わったら、以下のコマンドを実行して初期設定をします。

bitrise setup

このコマンドでは、環境の確認と、必要なツールのインストールが行われます。
また、今回はステップの開発をするため、ステップ開発用のプラグインを最新にアップデートしておきます。

bitrise plugin update step

以上で BitriseCLI のインストールと初期設定は完了です。

2. bitrise コマンドでステップの雛形を作成

自分で必要なファイルを一から作っても良いんですが、めんどくさいので bitrise コマンドで雛形を作成します。
以下のコマンドを実行すると雛形を作成できます。

bitrise :step create

すると開発者やらステップの名前やらリポジトリやら色々聞かれるので、答えていきます。

% bitrise :step create
Who are you / who's the author? : test author
What's the title / name of the Step? : test step
Generated Step ID (from provided Title): test-step
Please provide a summary : This is test step of bitrise
Please provide a description : This is test step of bitrise

What's the primary category of this Step?
Please select from the list:
[1] : access-control
[2] : artifact-info
[3] : installer
[4] : deploy
[5] : utility
[6] : dependency
[7] : code-sign
[8] : build
[9] : test
[10] : notification
(type in the option's number, then hit Enter) : 9

Toolkit: the entry/base language of the Step.
Our recommendation is to use Bash for very simple Steps
 and for more complex ones use another language, one which we have toolkit support for.
If you're just getting started with Step development our suggestion is to select Bash,
 as that's the easiest option. It's possible to convert the step later, if needed.
Note: Of course even if you select e.g. Bash as the entry language, you can run other scripts from there,
 so it's possible to write the majority of the step's code in e.g. Ruby,
 and have an entry Bash script which does nothing else except running the Ruby script.
Which toolkit (language) would you like to use?
Please select from the list:
[1] : bash
[2] : go
(type in the option's number, then hit Enter) : 1

Website & source code URL:
Will you host the source code on GitHub? [YES/no]: no
To use your step quickly in your bitrise configs, and in case you'll want to share it with others,
 you'll have to make the source code available on a git hosting service.
Please create a repository on your favorite source code hosting service,
 with the repository name: bitrise-step-test-step
Once created, please copy paste the repo's HTTPS URL.
If you create it on GitHub the HTTPS URL should look like this:
 https://github.com/YOUR-GITHUB-USERNAME/bitrise-step-test-step
What's the step's repo (website) URL? : https://github.com/bbq-all-stars/test-bitrise                                               o
Creating Step directory at: /Users/bbq-all-stars/bitrise-step-test-step
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/README.md
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/LICENSE
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/.gitignore
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/step.yml
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/bitrise.yml
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/.bitrise.secrets.yml
 * [OK] created: /Users/bbq-all-stars/bitrise-step-test-step/step.sh

Initializing git repository in step directory ...
 $ git "init"
 $ git "remote" "add" "origin" "https://github.com/bbq-all-stars/mtest-bitrise"

Step is ready!

You can find it at: /Users/bbq-all-stars/bitrise-step-test-step

TIP: cd into /Users/bbq-all-stars/bitrise-step-test-step and run bitrise run test for a quick test drive!

一通り答えると雛形が作成されます。
選択した言語が bash の場合は、コマンドを実行したディレクトリ直下に、 bitrise-step-${Step ID} という名前で作成されます。
Go の場合は GOPATH 以下に入力したリポジトリの名前でディレクトリが作成されます。

ファイル構成は以下のようになっています。

% tree .
.
├── LICENSE
├── README.md
├── bitrise.yml
├── step.sh / main.go
└── step.yml

選択した言語によって、step.sh か main.go のどちらかのファイルが生成されています。
これで雛形の作成は完了です。

3. 処理を諸々書く

bitrise の step の主要なファイルの役割は以下のようになっています。

  • bitrise.yml
    • bitrise run test で実行するテスト用の workflow を書きます。(後述)
  • step.yml
    • ステップのメタ情報や、入力する変数、出力する変数などの定義を書きます。
  • step.sh / main.go
    • 実行したい処理を書きます。

step.yml の作成

作成した雛形の step.yml をみると、 step.yml は Bitrise のステップの GUI 部分に対応することがわかります。
GUI 部分というのは ↓ これです(Script ステップの例)

この step.yml に、ステップのタイトルや説明、入力する変数(inputs)や出力する変数(outputs)の定義を書いてきます。
基本的には雛形に書いてある通りにパラメータを埋めていけば良いです。
詳細なパラメータは下記の公式ドキュメントを参照してください。
https://devcenter.bitrise.io/en/steps-and-workflows/developing-your-own-bitrise-step/developing-a-new-step.html

このうち、覚えておくと良いパラメータがあるのでいくつか紹介します。

deps

deps というパラメータがあります。
以下のように書いておくと、 mac でのビルドや Linux でのビルド時に、事前にパッケージマネージャーでツールをインストールしておいてくれます。
以下の例は cmake をインストールしておく例です。

step.yml
...
deps:
  brew:
  - name: cmake
  apt_get:
  - name: cmake
...

これにより、既存のツールに依存している処理を書く場合に便利です。

toolkit

toolkit というパラメータがあります。
このパラメータでは、どのファイルで処理を実行するかを書きます。
AWS Lambda とかでいう handler みたいなものです。

bash の場合は実行するシェルスクリプトのファイル名を書きます。

step.yml
...
toolkit:
  bash:
    entry_file: step.sh
...

Go の場合は実行する GOPATH 以下のパッケージ名を書きます

step.yml
...
toolkit:
  go:
    package_name: github.com/bbq-all-stars/bitrise-step-test-step-2
...

これにより、任意のファイル名の処理を実行させることができるようになります。

step.sh / main.go の作成

step.sh / main.go には、実際にステップで実行させたい処理を書きます。
step.yml に書いた inputs は、環境変数として参照することができます。

step.sh
...
echo ${example_step_input}"
...
main.go
...
fmt.Println(os.Getenv("example_step_input"))
...

また、step.yml に書いた output の変数に値を代入する場合は、 envman のコマンドを実行します。

step.sh
...
envman add --key EXAMPLE_STEP_OUTPUT --value 'the value you want to share'
...
...
cmdLog, err := exec.Command("bitrise", "envman", "add", "--key", "EXAMPLE_STEP_OUTPUT", "--value", "the value you want to share").CombinedOutput()
if err != nil {
        fmt.Printf("Failed to expose output with envman, error: %#v | output: %s", err, cmdLog)
        os.Exit(1)
}
...

実際に行う処理には、特に制限はありません。
たとえば bash で別のスクリプト言語をインストールして、その言語のファイルを実行することもできます。
Bitrise にあるステップの中には、 Ruby や Python で実際の処理が行われているものがありました。

4. bitrise run test コマンドでテストを実行

ステップは bitrise run test コマンドを実行することで、手元で実行することができます。
テストを実行するには、 bitrise.yml を書きます。

bitrise.yml の作成

bitrise.yml では、テスト用のパラメータを設定していきます。
workflows.test のパラメータが、 bitrise run test で実行するテストの処理を表します。

下記は、以下の処理を実行している例です。

  1. script
    • A_SECRET_PARAM を echo するスクリプトを実行
  2. change-workdir
    • 作業ディレクトリの変更
  3. path::./
    • ステップの処理の実行
  4. script
    • output するパラメータを echo するスクリプトを実行
bitrise.yml
...
workflows:
  test:
    steps:
    - script:
        inputs:
        - content: |
            #!/bin/bash
            echo "Just an example 'secrets' print."
            echo "The value of 'A_SECRET_PARAM' is: $A_SECRET_PARAM"
    - 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
    - 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:
        - example_step_input: Example Step Input's value
    - script:
        inputs:
        - content: |
            #!/bin/bash
            echo "This output was generated by the Step (EXAMPLE_STEP_OUTPUT): $EXAMPLE_STEP_OUTPUT"
...

テストで与える input は、 path::./.inputs で与えます。

また、直接 bitrise.yml に書きたくない秘匿したいような変数は、 app.envs パラメータと、 .bitrise.secrets.yml ファイルを使用して与えます。

bitrise.yml
...
app:
  envs:
  - A_SECRET_PARAM: $A_SECRET_PARAM
...
.bitrise.secrets.yml
envs:
- A_SECRET_PARAM: "A secret Value"

これで A_SECRET_PARAMS という環境変数で値を取得できます。
.bitrise.secrets.yml は、雛形作成時に自動で .gitiignore に追加されているので、git へ追加されません。

これらの設定を書いたら、あとは bitrise run test コマンドを実行すればテストを行うことができます。

% bitrise run test

██████╗ ██╗████████╗██████╗ ██╗███████╗███████╗
██╔══██╗██║╚══██╔══╝██╔══██╗██║██╔════╝██╔════╝
██████╔╝██║   ██║   ██████╔╝██║███████╗█████╗
██╔══██╗██║   ██║   ██╔══██╗██║╚════██║██╔══╝
██████╔╝██║   ██║   ██║  ██║██║███████║███████╗
╚═════╝ ╚═╝   ╚═╝   ╚═╝  ╚═╝╚═╝╚══════╝╚══════╝
version: 2.0.1

CI mode: false
PR mode: false
Debug mode: false
Secret filtering mode: true
Secret Envs filtering mode: true
No output timeout mode: false

Running workflow: test

Switching to workflow: test
Step uses latest version, updating StepLib...
+------------------------------------------------------------------------------+
| (0) Script                                                                   |
+------------------------------------------------------------------------------+
| id: script                                                                   |
| version: 1.2.0                                                               |
| collection: https://github.com/bitrise-io/bitrise-steplib.git                |
| toolkit: bash                                                                |
| time: 2022-12-02T21:33:55+09:00                                              |
+------------------------------------------------------------------------------+
|                                                                              |
Just an example 'secrets' print.
The value of 'A_SECRET_PARAM' is: [REDACTED]
|                                                                              |
+---+---------------------------------------------------------------+----------+
| ✓ | Script                                                        | 3.35 sec |
+---+---------------------------------------------------------------+----------+

                                        ▼

+------------------------------------------------------------------------------+
| (1) Switch working dir to test / _tmp dir                                    |
+------------------------------------------------------------------------------+
| id: change-workdir                                                           |
| version: 1.0.3                                                               |
| collection: https://github.com/bitrise-io/bitrise-steplib.git                |
| toolkit: bash                                                                |
| time: 2022-12-02T21:33:58+09:00                                              |
+------------------------------------------------------------------------------+
|                                                                              |
=> Changing working directory to /Users/bbq-all-stars/bitrise-step-test-step/_tmp
|                                                                              |
+---+---------------------------------------------------------------+----------+
| ✓ | Switch working dir to test / _tmp dir                         | 0.54 sec |
+---+---------------------------------------------------------------+----------+

                                        ▼

+------------------------------------------------------------------------------+
| (2) Step Test                                                                |
+------------------------------------------------------------------------------+
| id: ./                                                                       |
| version:                                                                     |
| collection: path                                                             |
| toolkit: bash                                                                |
| time: 2022-12-02T21:33:59+09:00                                              |
+------------------------------------------------------------------------------+
|                                                                              |
+ echo 'This is the value specified for the input '\''example_step_input'\'': Example Step Input'\''s value'
This is the value specified for the input 'example_step_input': Example Step Input's value
+ envman add --key EXAMPLE_STEP_OUTPUT --value 'the value you want to share'
|                                                                              |
+---+---------------------------------------------------------------+----------+
| ✓ | Step Test                                                     | 0.06 sec |
+---+---------------------------------------------------------------+----------+

                                        ▼

+------------------------------------------------------------------------------+
| (3) Script                                                                   |
+------------------------------------------------------------------------------+
| id: script                                                                   |
| version: 1.2.0                                                               |
| collection: https://github.com/bitrise-io/bitrise-steplib.git                |
| toolkit: bash                                                                |
| time: 2022-12-02T21:33:59+09:00                                              |
+------------------------------------------------------------------------------+
|                                                                              |
This output was generated by the Step (EXAMPLE_STEP_OUTPUT): the value you want to share
|                                                                              |
+---+---------------------------------------------------------------+----------+
| ✓ | Script                                                        | 0.54 sec |
+---+---------------------------------------------------------------+----------+


+------------------------------------------------------------------------------+
|                            bitrise summary: test                             |
+---+---------------------------------------------------------------+----------+
|   | title                                                         | time (s) |
+---+---------------------------------------------------------------+----------+
| ✓ | Script                                                        | 3.35 sec |
+---+---------------------------------------------------------------+----------+
| ✓ | Switch working dir to test / _tmp dir                         | 0.54 sec |
+---+---------------------------------------------------------------+----------+
| ✓ | Step Test                                                     | 0.06 sec |
+---+---------------------------------------------------------------+----------+
| ✓ | Script                                                        | 0.54 sec |
+---+---------------------------------------------------------------+----------+
| Total runtime: 4.50 sec                                                      |
+------------------------------------------------------------------------------+


Submitting anonymized usage information...
For more information visit:
https://github.com/bitrise-io/bitrise-plugins-analytics/blob/master/README.md

Bitrise build successful

ちなみに、テスト時の実行ディレクトリは change-workdir で設定されるディレクトリですが、実際に Bitrise の workflow で実行される際の実行ディレクトリは、 ビルド時に clone してきたソースのルートディレクトリになります。
そのため、カスタムステップのディレクトリを参照したい場合は、以下のように実行スクリプトからパスを取得し、参照する必要があります。
https://qiita.com/koara-local/items/2d67c0964188bba39e29

5. workflow への組み込み

テストを実行して問題がなければ、実際に Bitrise の Workflow に組み込みます。
Workflow に組み込むには、リポジトリを公開する必要があります。
Workflow の bitrise.yml を開き、組み込みたい workflow に公開したリポジトリを書きます。

---
format_version: '11'
default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git
project_type: flutter
workflows:
  test_workflow:
    steps:
    # ↓ これを追加
    - git::https://github.com/bbq-all-stars/bitrise-step-test-step.git@main:

そうすると、以下のように GUI 上に表示されます。

あとは必要なパラメータを GUI 上で設定したら、晴れてカスタムステップを使うことができます🎉

おわりに

実際に作ってみると、割と簡単にカスタムステップを作れることがわかると思います。

使える言語が bash か Go しかありませんが、 bash であれば任意のスクリプト言語をインストールして動かすことができるので、そこまで困ることはなさそうです。
みなさんもぜひ気軽に Bitrise のカスタムステップを作ってみてください。

MIXI DEVELOPERS NOTE
MIXI DEVELOPERS NOTE

Discussion