生産性向上ブログ

継続的な生産性向上を目指すエンジニアのためのブログ

CircleCI Orbs 入門

この記事は、CircleCI Advent Calendar 2018 初日の記事です。記事公開時点ではまだ空いてる日程があるので、CircleCI に関するネタならなんでも気軽に参加してください!

長いので目次。

Orbs とは?

Orbs は、最近 CircleCI 2.1 として追加された機能の一部で、CircleCI の設定をパッケージとして公開し、再利用するための仕組みです。2.1 も Orbs もまだプレビュー段階ですが、後述する設定を有効にすれば利用できます。

公式情報は ↓ から辿れます。

circleci.com

CircleCI 2.1 で追加された他の機能については過去に書いたので、興味ある人はそちらをご参照ください。

www.kaizenprogrammer.com

上の記事で書いた通り、これまで似たような設定で肥大化しがちだった CircleCI の設定ですが、2.1 で設定を再利用しやすくするための構文が追加されました。

Orbs が公開される前は他プロジェクトの設定を再利用するということができませんでしたが、CircleCI の設定を Orb としてパッケージングして公開することにより、2.1 の構文で書かれた再利用しやすい設定を、複数のプロジェクトにまたがって再利用することができるようになります。

さらに、他の人が公開した Orb を利用することもできるため、車輪の再発明をすることなく CI/CD の設定を簡単かつ高速に行えるようになります。

事前準備

2.1 の有効化

まず、事前準備として、Orbs を利用するプロジェクトの設定で 2.1 の機能を有効にする必要があります。過去記事の2.1 を有効にする方法を参考に、有効になっていることを確認してください。(新規に CircleCI で有効にしたプロジェクトだともうデフォルト有効になってるかもしれません)

Orbs のセキュリティ設定

自分たちで Orb を公開したい場合や、公式でもパートナーでもない野良のサードパーティー Orb を使いたい場合は、セキュリティの設定を変更する必要があります。こちらは Organization 単位で設定でき、ORGANIZATION SETTINGS → Security を開いて、Orb Security Settings で Yes を選択します。

f:id:miya-jan:20181201012608p:plain

CircleCI CLI

Orb の公開には CircleCI CLI が必要なので、事前にインストールしておきましょう。2.1 以前にインストールしている人は最新バージョンに更新する必要があるので、過去記事のCLI の変更を参考にしてください。

公開されてる Orbs を利用する

では、試しに CircleCI が公式で提供している、shellcheck の Orbを利用してみます。(shellcheck はシェルスクリプトの静的解析ツール)

以下の設定で、リポジトリ内のすべてのシェルスクリプトに対して shellcheck を実行できます。

version: 2.1

orbs:
  shellcheck: circleci/shellcheck@1.2.0

workflows:
  pipeline:
    jobs:
      - shellcheck/check

これは楽ですね!

解説しますと、まず最初の orbs ブロックで利用する Orb を読み込んでいます。バージョン指定できるので、Orb が更新されても既存のバージョンの Orb が変更されることはなく、いきなりビルドが壊れることはありません。

circleci/shellcheck Orb には、check というジョブの定義が含まれており、これを workflowsjobs で呼び出しています。

CircleCI の内部的には、ビルド実行時に前処理でいい感じに設定を展開してから実行しているようです。どのように設定が展開されるかは、CLI で circleci config process を実行することで確認できます。

$ circleci config process .circleci/config.yml
# Orb 'circleci/shellcheck@1.2.0' resolved to 'circleci/shellcheck@1.2.0'
version: 2
jobs:
  shellcheck/check:
    docker:
    - image: nlknguyen/alpine-shellcheck:v0.4.6
    steps:
    - checkout
    - run:
        name: Check Scripts
        command: find '.' -not -path '' -type f -name '*.sh' | tee /dev/tty | xargs
          shellcheck --external-sources
workflows:
  pipeline:
    jobs:
    - shellcheck/check
  version: 2

# Original config.yml file:
(以下省略)

これまでは、同様のジョブを定義するためには自分たちで上記のような設定を書かなければいけませんでした。どの Docker イメージを使うのが適切か調べたり、run コマンドがいい感じになるように調整したりといったことをしてると、意外と時間を取られるのが当たり前でした。

しかし、Orbs によってジョブ定義すら書かなくてよくなり、簡単かつ高速に設定が行えるようになりました。さらに、設定ファイルもシンプルになるので、CI/CD のメンテナンスも楽になります。

Orbs を公開する

今度は自分で作成した Orb を公開してみましょう。

Namespace の作成

Orbs を公開するには、まず Namespace が必要です。

Namespace とは、中に複数の Orb を登録することができる名前空間で、VCS(今回だと GitHub)の organization によって所有されます。Namespace は、organization の administrators のみが作成することができ、既存の Namespace と同じ名前の Namespace を作成することはできません。デフォルトでは一つの organization につき、一つの Namespace のみ作成できます。

Namespace は、CLI で circleci namespace create <name> <vcs-type> <org-name> を実行することで作成できます。自分の場合、以下のように miyajan organization 下に miyajan という Namespace を作成しました。(organization と Namespace を同名にしたので分かりづらかったらすみません)

$ circleci namespace create miyajan github miyajan
Namespace `miyajan` created.
Please note that any orbs you publish in this namespace are open orbs and are world-readable.

現状だと公開された Orbs は全世界に公開され、特定のメンバーのみ private に公開するということはできないようなので注意してください。

コマンド実行時に Error: Your organization must enable the 'Uncertified Orbs' feature in org settings to create namespaces. のようなメッセージが表示されるときは、事前準備に書いた Orbs のセキュリティ設定を見なおしてください。

Orb の作成

次に、Orb を作成します。

作成する Orb はなんでもいいですが、この記事では自動フォーマットツールの prettier をリポジトリ内のすべての YAML に対して実行して、差分があったら失敗にするジョブを公開してみることにします。

なので、まずは CLI で circleci orb create を実行して、miyajan/prettier という Orb を作成します。

$ circleci orb create miyajan/prettier
Orb `miyajan/prettier` created.
Please note that any versions you publish of this orb are world-readable.
You can now register versions of `miyajan/prettier` using `circleci orb publish`.

この段階ではまだ中身はなく、Orb を公開する場所ができただけです。

Orb の中身の作成

Orb の中身として、次のような YAML ファイルを prettier.yml として用意します。

version: 2.1

jobs:
  check-yaml:
    executor: prettier
    steps:
      - checkout
      - run:
          name: Check YAMLs
          command: prettier --list-different **/*.{yml,yaml}

executors:
  prettier:
    docker:
      - image: miyajan/prettier:1.15.3

前述したように、リポジトリ内のすべての YAML ファイルに対して prettier をかけて差分があったら落ちるジョブ check-yaml を実装しています。

Orb のバリデーション

CLI で circleci orb validate を実行すると、Orb のコードをバリデーションできます。

$ circleci orb validate prettier.yml
Orb at `prettier.yml` is valid.

Orb の公開

まずは、CLI で circleci orb publish を実行して、Orb を dev バージョンとして公開してみます。

$ circleci orb publish prettier.yml miyajan/prettier@dev:first
Orb `miyajan/prettier@dev:first` was published.
Please note that this is an open orb and is world-readable.
Note that your dev label `dev:first` can be overwritten by anyone in your organization.
Your dev orb will expire in 90 days unless a new version is published on the label `dev:first`.

Orb には、dev と production のバージョンがあります。production は 1.5.3 のような semver で表し、dev は dev: で始まる文字列で表します。

production は organization の administrators のみが公開でき、dev は organization 内のどのメンバーでも公開できます。

また、dev は organization 内のどのメンバーでも上書き可能で、変更がなければ 90 日で期限切れになります。一方、production は変更不可能で期限がありません。

production に公開するときは、上記のように circleci orb publish で直接バージョンを指定して公開することもできますが、circleci orb publish incrementcircleci orb publish promote が推奨されています。

例えば、circleci orb publish promote だと以下のようになります。

$ circleci orb publish promote miyajan/prettier@dev:first patch
Orb `miyajan/prettier@dev:first` was promoted to `miyajan/prettier@0.0.1`.
Please note that this is an open orb and is world-readable.

promote を使うと dev として公開した Orb を production に昇格させることができます。

patch を指定したので、semver のパッチバージョンアップとなり、バージョン 0.0.1 として公開されました。patch の他に、minormajor を指定できます。

circleci orb publish increment だと以下のようになります。

$ circleci orb publish increment prettier.yml miyajan/prettier patch
Orb `miyajan/prettier` has been incremented to `miyajan/prettier@0.0.2`.
Please note that this is an open orb and is world-readable.

increment は、ファイルから直接 production に公開します。patch, minor, major が指定できるのは promote と同じです。

公開された Orb の確認

circleci orb source コマンドで公開されてる Orb のソースを見られるので、確認してみます。

$ circleci orb source miyajan/prettier@0.0.2
version: 2.1

jobs:
  check-yaml:
    executor: prettier
    steps:
      - checkout
      - run:
          name: Check YAMLs
          command: prettier --list-different **/*.{yml,yaml}

executors:
  prettier:
    docker:
      - image: miyajan/prettier:1.15.3

公開された Orb を使うときは、circleci/shellcheck のときと同じように呼び出します。

version: 2.1

orbs:
  prettier: miyajan/prettier@0.0.2

workflows:
  pipeline:
    jobs:
      - prettier/check-yaml

Orbs Registry

公開されている Orbs は以下のページから参照できます。

https://circleci.com/orbs/registry/

f:id:miya-jan:20181201014246p:plain

CircleCI 自身が公式で提供している Orbs には "CERTIFIED"、CircleCI によるパートナープログラムを結んだサードパーティーが提供する Orbs には "PARTNER" と表示されるようです。右上の "Show all Orbs" をクリックすると、自分が作ったような野良のサードパーティー Orbs も含めてすべて表示されます。

それぞれの Orb をクリックすると、その Orb が提供する設定のドキュメントが表示されます。

f:id:miya-jan:20181201014308p:plain

まとめ

まだまだ書きたいこと(複数のファイルを 1 つの Orb にまとめる仕組みや、CI/CD、自動テストなど)があるのですが、入門記事としては長くなりすぎな気がしてきたので、ここまでにします。すでに登録されている Advent Calendar のタイトルでも Orbs について書いてくださる方が数名いらっしゃるようなので、期待してます!

Orbs の所感としましては、まず利用者側としては汎用的なビルド内容がかなり楽になるのではないかと感じています。Registry の公式 Orbs をいくつか眺めただけでも使ってみたいものがありますし、パートナー製やサードパーティー製も今後どんどん便利なものが増えていくと思われます。CI/CD の設定は沼に陥りがちなので、再利用の仕組みが発展していくのはありがたいですね。

他人が作った Orbs を利用するのはセキュリティ面が気になるところではありますが、production の Orbs は公開後は不変ですし、ソースは確認できるので事前に中身を読むということを徹底すれば、基本的には大丈夫なのではないかと思います。(ソースを読まないと詳細な使い方が理解できないので結局読むことになりそうですし)

製作者側としては、今回試した感じだとかなり手軽に Orbs を公開していけるように感じました。自分たちの CI/CD ノウハウを公開したり、他の人が作ったプラグインに PR を送ったりしてコミュニティに貢献していけるようになったのは、とても盛り上がりそうで楽しみです。12/15 に、CircleCI Orbs ミニハッカソンが開催されるようなので、興味ある人はぜひ。(自分も参加予定です)

個人的な要望としては、仕事で使ってる CircleCI Enterprise の方でも早く Orbs を使いたいので、CircleCI の中の人なにとぞよろしくお願いします!🙇

CircleCI Advent Calendar の明日の記事は、@yasuhiroki さんの予定です。よろしくお願いします!