⚠️ circleci/orb-tools v8.27.6 を使っています。さっき見たら v9.0.0 がリリースされており、trigger-integration-workflow 等のジョブ名が変わり、互換性がなくなったことは確認しました。


先日、tfupdate の CircleCI Orb を作りました。

tfupdate とは

tfupdate は terraform のアップデートを支援してくれるツールです。ローカルの .tf ファイルに書かれた、terraform と terraform provider のバージョンを最新にしてくれます。

.circleci/config.yml に組み込むと、定期的に pull request を作ってくれます。
例: https://github.com/minamijoyo/tfupdate-circleci-example/blob/cd8e5561b7eabb25aa3cd024dfcf5b868c4bda45/.circleci/config.yml

タイムリーなことに、作者の minamijoyo さんが書かれた記事があります。詳しくはこちらをどうぞ。
tfupdateでTerraform本体/プロバイダ/モジュールのバージョンアップを自動化する - Qiita

なぜ circleci-tfupdate-orb を作ったのか

前述の .circleci/config.yml を見ると分かりますが、かなり行数が長いです。130 行あります。

tfupdate 以外にも CI の設定はありますし、これを各リポジトリに書くのは辛いです。そのため、ほぼそのまま Orb にしたのが v0.0.2 です。
https://github.com/masutaka/circleci-tfupdate-orb/tree/v0.0.2

CircleCI Orb Registry はこちらです。v0.0.2 は circleci CLI を使って手動で Publish しました。Publishing Orbs や他の記事など、読み漁りました。
https://circleci.com/orbs/registry/orb/masutaka/tfupdate?version=0.0.2

なぜ circleci/orb-tools を使ったのか

変更を加えるたびに Orb Registry に publish していくのはなかなか面倒です。

  • 手順を覚えるのが面倒
  • 手順通りに circleci CLI を使うのが面倒
  • どのバージョンに上げれば良いか考えるのが面倒

前述のドキュメントだとベストプラクティス的なものは分からなかったです。ただ継続的に Publish したいだけなのに。

仕方がないので、circleci/orb-tools をしっかり読んで、いい感じにしました。v0.0.4 です。
https://github.com/masutaka/circleci-tfupdate-orb/blob/v0.0.4/.circleci/config.yml

master ブランチにマージしたら、以下のようにいい感じに Orb Registry に Publish されます。

  • src/commands 以下が更新されたら minor version を上げて Publish される
  • src/{examples,executors} 以下が更新されたら patch version を上げて Publish される
  • major version は自動では上がらない。詳細は後述する
  • それ以外のファイルが更新されても、Publish されない

このフローを理解した時は本当に秀逸だと思いました。

フローに乗せるため orb.yml を分割しました。最初は分割しない方法を探りましたが、調べるうちに分割することが楽な道だと理解しました。

src
├── @orb.yml
├── commands
│   ├── provider.yml
│   ├── setup.yml
│   └── terraform.yml
├── examples
│   └── tfupdate_and_create_pull_request.yml
└── executors
    └── default.yml

今回作ったリリースフローの解説

今回作ったリリースフローを解説していきます。
https://github.com/masutaka/circleci-tfupdate-orb/blob/v0.0.4/.circleci/config.yml

まずは 7~34 行目の lint_pack-validate_publish-dev workflow から。

🔗 https://circleci.com/workflow-run/b1ad1325-648d-4e54-bfe9-66d6ea9f8a9e
lint_pack-validate_publish-dev workflow

<9行目> orb-tools/lint job(実行されたジョブ
yamllint を使った素朴な lint です。

<10~12行目>orb-tools/pack job(実行されたジョブ
以下のような YAML を 1 つにまとめてくれます。フローに乗るために、小さな Orb であってもこの構成にしましょう。

  • src/@orb.yml
  • src/commands/*.yml
  • src/examples/*.yml
  • src/executors/*.yml

<13~16行目> orb-tools/publish-dev job(実行されたジョブ
dev:alpha と dev:${CIRCLE_SHA1:0:7} というバージョンを Orb registory に publish します。

※ Orb registory では 1.2.3 のようなセマンティックバージョンは immutable(上書き不可)、それ以外のバージョン(dev:alpha 等)は mutable(上書き可能)です。

<17~25行目> orb-tools/trigger-integration-workflow job(実行されたジョブ
master ブランチ以外で実行されます。前述のファイル構成にしてくれれば、自動的に minor/patch のバージョンを上げるための git のタグを打ってくれます。
例: integration-{minor,patch,skip}-{ブランチ名}-${CIRCLE_SHA1:0:7}

ちなみに major バージョンのリリースにはまだ(?)対応していません。良いアプローチを考えてみましょう or 手動でやってね とのことです。

実はこの job はあまり意味はないです。git のタグを打つパーミッションがあるかのテストだと理解しました。cleanup-tags: true を設定すれば、打ったタグはすぐに消されます。

<26~34行目> orb-tools/trigger-integration-workflow job(実行されたジョブ
こちらは mater ブランチ用です。同じように git のタグを打ってくれます。
例: master-{minor,patch,skip}-{ブランチ名}-{commit hash}

このフォーマットのタグが打たれると、次に説明する orb-tools/dev-promote-prod job が発動します。

35~64 行目の prod-release workflow を説明します。

🔗 https://circleci.com/workflow-run/a7eb933e-00b9-43c5-8497-5a23a3319f35
prod-release workflow

<3744行目> orb-tools/dev-promote-prod job(実行されたジョブ
master-patch* という git tag が付いたら発動します。41
42 行目で全ブランチ ignore しているのがポイントです。
13~16行目で publish した dev:${CIRCLE_SHA1:0:7} を $ circleci orb publish promote … で Promote します。
$ circleci orb info でバージョン番号を取得し、git のタグを打ってくれます。
最後に master-patch* という git tag は掃除(削除)してくれます。

<46~54行目> orb-tools/dev-promote-prod job
minor バージョン版。
master-minor* という git tag が付いたら発動します。
最後に master-minor* という git tag は掃除(削除)してくれます。

<56~64行目> orb-tools/dev-promote-prod job
major バージョン版。前述のとおり、手動でタグを打たない限り、自動的にこのジョブは実行されません。
master-major* という git tag が付いたら発動します。
最後に master-major* という git tag は掃除(削除)してくれます。

感想

Orb バージョンは勝手に Bump していくので、今 1.0.1 だから、次 1.0.2 だなとか、考えなくてよいのが秀逸だと思いました。

欠点を挙げるのであれば、GitHub の release page が荒れることかな…。

例: https://github.com/CircleCI-Public/orb-tools-orb/releases
CircleCI-Public/orb-tools-orb releases