⚠️ 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
<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
<37~44行目> 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