カクカクしかじか

技術的なアレコレ

CircleCIこと始めYAMLファイルの基本から

はじめに

CircleCIの設定はすべて .circleci/config.ymlYAMLファイルに記述されます。 CircleCIの使う上ではYAMLファイルの記載方法について理解することが重要です。 わたし自身、だいぶ理解があやふやなので、自分のメモとしてもYAMLの基本とあまり触れられていないCircleCI上でのYAMLの記載方法についてまとめてみます。 なお、対応バージョンはCircleCI2.0以降のバージョンを対象とし、最後の例はRailsアプリを前提に記載しています。

YAMLの基本

YAMLはデータをシリアライズするためのフォーマットの1つであり、配列やハッシュなどいくつかのデータ型で構成されています。
(シリアライズとはコンピューターのメモリ上にあるオブジェクトをファイルとして保存したり、データとして送受信するために変換すること。)

1. シーケンス(配列)

YAMLでは配列のことをシーケンスと呼び、以下のように-(ハイフン)と(半角スペース) の記載を指します。
※CircleCIの公式ドキュメントでは、シーケンスのことをSequenceやListと表記しています。

- a
- b
- c

# 実際の配列で表すと以下のイメージ
# ["a", "b". "c"]

インデントの深さでスコープを表現します。

- a
  - b
  - c

# 実際の配列で表すと以下のイメージ
["a", ["b", "c"]]

2. マップ(ハッシュ)

YAMLではハッシュのことをマップ(Map)と呼びます。
マップはキーと値のペアをコロン(:)と半角スペースで区切って表現します。

A: a
B: b
C: c

# 実際のハッシュで表すと以下のイメージ
# {"A": "a", "B": "b", "C": "c"}

ハッシュの値が配列であるシーケンスのマップ

A: - a
   - b
   - c
# 実際のハッシュで表すと以下のイメージ
# {"A": ["a", "b", "c"]}

ハッシュの配列であるマップのシーケンスも表現出来る。

- A: a
     b
     c
# 実際のハッシュで表すと以下のイメージ
# {"A": ["a", "b", "c"]}

3. スカラ(シーケンスやマップ以外)

シーケンスやマップ以外の文字列や数値、真偽値などのデータ型のことをスカラと呼びます。
代表的なスカラは以下の通り。

- 真偽値(true/false, yes/no, on/off)
- 整数(123, 1,234)
- 浮動小数てん(0.12)
- 文字列(string, "文字列")

4. 複数行の記載方法

複数行に渡る文字列を表現するときは|を使って表現することが出来ます。
CircleCIの設定ファイルでは複数行に渡るコマンドを記載する場合に使用することが出来ます。

run: |
  yarn install
  yarn build

CircleCIの設定ファイルの構成要素

記載例)

version: 2
jobs:
  build:
    docker: 
      - image: ruby:2.5.1 #Docker HubのRubyリポジトリのDockerイメージから2.5.1のタグを指定しているという意味
    steps:
      - run: yarn install
      - run: yarn build

主なキー

version

CircleCIのバージョンを記載することが出来ます。
この記事の時点では 22.1 が記載可能です。

最後に

最後に恥ずかしながら、個人的にハマった部分を共有させて頂きます。

CircleCI初心者の落とし穴①

workflowsに指定しない限りデフォルトではbuild以外のコマンドは実行されないので、RuboCopやRSpecなどを追加で実行したい場合はbuild成功時にそれらのコマンドを実行する記述をする必要があります。

workflows:
  version: 2
  build_and_test: #これがワークフロー名
    jobs:
    - build #ビルド実行
    - code_analyze: #code_analyzeという名前で定義しておいたRuboCopコマンド実行
        requires: #requiresにbuildを指定するとビルド成功時のみ実行するということになる
        - build

CircleCI初心者の落とし穴②

自分が試したところ bundle install の部分を bundle install --path vendor/bundler とオプション付きで記載するとgemが正常にインストールされずrubocopコマンドが見つからないというエラーが出ました。 とはいえ、公式のデモには bundle install --path vendor/bundler で記載されていたので、こちらでも可能だと思いますが、今回はうまくいかなかったため、オプション無しの方で自分は試しました。

実際にCIで動くようにした .circleci/config.yml

# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
defaults: &defaults
  docker:
    # specify the version you desire here
    - image: ruby:2.5.1
      environment:
        RAILS_ENV: test
        TZ: /usr/share/zoneinfo/Asia/Tokyo
        BUNDLE_PATH: vendor/bundle
        BUNDLER_VERSION: 1.17.2
    - image: postgres:11.1-alpine
      environment:
        - POSTGRES_USER: vimmer
        - POSTGRES_PASSWORD: vimate
        - PGDATA: /dev/shm/pgdata/data
  working_directory: ~/vimate_app
jobs:
  build:
    <<: *defaults
    steps:
      - checkout
      - restore_cache:
          key: vimate-app-gemfile-{{ checksum "Gemfile.lock" }}
      - run: gem install bundler -v 1.17.2
      - run: bundle install
      - save_cache:
          key: vimate-app-gemfile-{{ checksum "Gemfile.lock" }}
          paths:
            - vendor/bundle
      - persist_to_workspace:
          root: ~/vimate_app
          paths:
            - ./*
  # RuboCop check!!
  code_analyze:
    <<: *defaults
    steps:
      - attach_workspace:
          at: ~/vimate_app
      - run:
          name: Run Rubocop
          command: bundle exec rubocop --parallel
workflows:
  version: 2
  build_and_test:
    jobs:
    - build
    - code_analyze:
        requires:
        - build

おまけ

YAMLで参考になりそうだった「るびま」の記事もついでに貼っておきます。

magazine.rubyist.net