CircleCI Orbのテストを自動化しよう

CircleCIのOrbなんとテスト書けますが、ドキュメントを読んでも自動化までなかなか遠かったので書き残しておきます。

https://circleci.com/docs/2.0/testing-orbs/

Orbのテストを書く記事なので、Orbはすでに書いてある前提で書いていきます。

`circleci/orb-tools@9.0.0` で動作確認済です。
https://circleci.com/orbs/registry/orb/circleci/orb-tools?version=9.0.0

前準備
---

### CircleCIのPersonal API Tokens

Orbの公開などするためにCircleCIのAPI Tokenを払い出し、環境変数`CIRCLE_TOKEN`にセットします。プロジェクトごとにTokenを発行するのが面倒なので、Contextsにセットしておくと便利です。
ちなみに、プロジェクトのAPI Tokenでは動きませんでした。

https://circleci.com/account/api

テストを書く
---

テストを`.circleci/config.yml`に書いていきます。
`circleci/orb-tools`に便利なJobが揃ってるので、これを活用して書いていきます。
https://circleci.com/orbs/registry/orb/circleci/orb-tools

大まかな流れとしては

1. orbをpackする (`orb-tools/pack`)
1. `dev:alpha`としてOrb Registryにpublishする (`orb-tools/publish-dev`)
1. `run-integration-tests` Pipeline Parameterを`true`にしてorbのテストが書かれているworkflowをkickする (`orb-tools/trigger-integration-tests-workflow`)
1. テストのstepを流す (`orb-tools/test-in-builds`)

ポイントはテストしたいorbのpublishと、実際のテストはworkflowが分かれているいて、publishした後にテストのworkflowがkickしていることです。
workflowが読み込まれた時点でorbを読み込まれているので、workflow実行中に上書きしても、その`dev:alpha`は前回Publishしたものを使ってしまいます。

```yaml
version: 2.1

orbs:
  orb-tools: circleci/orb-tools@9.0.0
  # For test
 <orb-name>-alpha: <namespace/orb-name>@dev:alpha

# https://circleci.com/docs/2.0/pipeline-variables/
parameters:
  run-integration-tests:
    type: boolean
    default: false
  dev-orb-version:
    type: string
    default: "dev:alpha"

workflows:
  version: 2
  dev:
    # これを書かないと無限ループする
    unless: << pipeline.parameters.run-integration-tests >>
    jobs:
      - orb-tools/pack:
          name: pack-dev
      - orb-tools/publish-dev:
          name: publish-dev
　　　　　　# Contextsを使う場合
          # もしくは環境変数`CIRCLE_TOKEN`が設定がされていればOK
          context: orb-publishing
          requires: [pack-dev]
          orb-name: <namespace/orb-name>
          publish-token-variable: CIRCLE_TOKEN
          validate: true
          checkout: false
          attach-workspace: true
      # このjob内で pipeline.parameters.run-integration-tests がtrueに変わる
      - orb-tools/trigger-integration-workflow:
          name: trigger-integration-workflow-dev
　　　　　　# Contextsを使う場合
          # もしくは環境変数`CIRCLE_TOKEN`が設定がされていればOK
          context: orb-publishing
          requires: [publish-dev]

  integration_dev:
    when: << pipeline.parameters.run-integration-tests >>
    jobs:
      - orb-tools/pack:
          name: pack-integration_dev
      - orb-tools/test-in-builds:
          name: test-in-builds-integration_dev
          requires: [pack-integration_dev]
          orb-name: <orb-name>-alpha
          attach-workspace: true
          test-steps:
            - run: echo "ここにテストを書く"
```

個人の好みが出ているところを少しだけ補足しておくと、
workflow中でorbを使ったjobにわざわざ`name`をつけているのは、job名が重複したときに`orb-tools/pack-1`とか出るが嫌だからです。`name`で一意なjob名をつけておくことで、見た目がスッキリしますし、（未だこれをやなくて被害を被ったことはないけど）GitHubの「Require status checks to pass before merging」のブランチの設定がズレる心配もないので安心します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83325/11cbd802-8ab9-13b6-da00-64c0d5258225.png)


参考
---

`orb-tools`の実装は大変参考になります。
https://github.com/CircleCI-Public/orb-tools-orb/blob/e302710073ca365243bf990bfe3dfb66573843a1/.circleci/config.yml

↑を参考に自分で作ってみたorbです。
https://github.com/sawadashota/envsubst-orb