技術向上

プログラミングの学び、気になるテクノロジーやビジネストレンドを発信

Steps【CircleCI】

概略

CircleCIの.ymlファイルに記述されるコードには、jobsという、どんな命令を実行させたいかを羅列するブロックがあります。jobsに記載される一つひとつのjobは、どのような処理をどの順番で処理させたいかをstepsに定義します。

version: 2
jobs:
  build:
    docker:
      - image: circleci/golang:rc-node-browsers-legacy
    steps:
      - checkout
      - run: mkdir -p workspace
      - run: echo "Hello" >> workspace/echo.txt

  test:
    docker:
      - image: circleci/golang:rc-node-browsers-legacy
    steps:
      ...


stepsはいくつかのkey/valueペアによって表現され、keyはstepの種類を、valueはその設定を文字列かmapによって表します。

mapの例

...
    steps:
      - run:
          name: Running tests
          command: make test
      - run: make test    // name、commandともにmake test


文字列の例

...
    steps:
      - checkout


stepの種類

run
コマンドラインによる命令を実行するために用いられます。
commandは次のように複数行、複数命令を指定することもできます。

- run:
    command: |
      echo Running test
      mkdir -p /tmp/test-results
      make test


デフォルトですと、複数命令が記述されている場合に1つでも失敗すると、途中でプログラムが終了し、全体のステータスは失敗として処理されます。
途中で1つ処理に失敗しても最後まで処理をさせたい場合には、「step +e」をcommand内に記述するか、runのshellキーでオーバーライドします。デフォルトでshellキーには「/bin/bash -eo pipefail」または、「/bin/sh -eo pipefail」が指定されており、1つでも処理が途中で失敗すると中断するようになっています(詳細はConfiguring CircleCI - CircleCIを参照)。「-eo pipefail」オプションを指定しないようにshellキーを指定することで、途中で失敗しても中断しないようにすることができます。

- run:
    command: |
      echo Running test
      set +e
      mkdir -p /tmp/test-results
      make test

#または

- run:
    shell: /bin/sh
    command: |
      echo Running test
      mkdir -p /tmp/test-results
      make test

また、backgroundキーにtrueを指定することで、対象のstepの終了を待たずに次のstepの処理を開始させることができます。

- run:
    name: Running X virtual framebuffer
    command: Xvfb :99 -screen 0 1280x1024x24
    background: true

- run: make test


whenキーというものもあります。デフォルトですと、前に記述されている全てのstepが成功したら処理されます(when: on_success)が、whenキーの指定によって、以前の処理の結果如何に関わらず処理させる(when: always)、以前の処理が1つでも失敗した場合に処理させる(when: on_fail)ことが可能です。

 - run:
      name: Upload Failed Tests
      command: curl --data fail_tests.log http://example.com/error_logs
      when: on_fail

alwaysであればlogやコードカバレッジのアップロードに、on_failであればテスト結果が失敗したことの調査のためにデータを保存する、失敗箇所をメールなどで通知するために用いることができるでしょう。

他にもキーは存在します。詳細はConfiguring CircleCI - CircleCIを参照ください。


when(runのwhenキーとは別)
version2.1から導入された種類です。conditionによって実行するかしないかを分岐させることができます。

version: 2.1
jobs:
  myjob:
    parameters:
      preinstall-foo:
        type: boolean    // stringなどを指定し、定義されていることをもってconditionでtrueと扱うことも可能
        default: false
    machine: true
    steps:
      - run: echo "preinstall is << parameters.preinstall-foo >>"
      - when:
          condition: << parameters.preinstall-foo >>
          steps:
            - run: echo "preinstall"
      - unless:
          condition: << parameters.preinstall-foo >>
          steps:
            - run: echo "don't preinstall"



checkout
ソースコードのチェックアウトに使用します。ただし、HTTPS経由でgitを実行する場合には、このcheckoutを使用してはいけません。その場合は、ssh経由でチェックアウトするよう設定します。また、checkoutはsubmoduleのチェックアウトは行いません。submoduleをチェックアウトするには次のようにします。

- checkout
- run: git submodule sync
- run: git submodule update --init

checkoutを使用すると、gitのガベージコレクションをスキップします。restore_cacheを用いて.gitディレクトリをキャッシュしていて、その容量を削減したいときは、checkoutする前にrun stepにて、git gcコマンドを実行するようにします。


save_cache
依存関係やソースコードなどのファイルまたはディレクトリをキャッシュに保存するために使用します。
keyとpathの指定が必要です。keyはキャッシュを生成した後から変更することができません。既存のキャッシュと同じkeyが指定された場合、キャッシュは生成されず、次のstepの実行に移ります。keyをプログラマティックに指定するテンプレートが用意されています。pathの指定にワイルドカードを用いることはできません。他のキーも併せてConfiguring CircleCI - CircleCIと、依存関係のキャッシュ - CircleCIを参照ください。
保存の期限は30日間です。

- save_cache:
    key: v1-myapp-{{ arch }}-{{ checksum "project.clj" }}
    paths:
      - /home/ubuntu/.m2


「v1-」は、ツールなどキャッシュに関連するファイルのヴァージョンアップに対応するためのtipsです。このように簡単に編集できる部分を設けることで、例えばnpmモジュールのバージョンアップがあった場合に、「v-2」とconfig.ymlファイルを編集することで、キャッシュを再生成させることができます。


restore_cache
生成済みのcacheを復元します。keyの指定だけでよく、pathの指定は不要です。
keyによる判定には前方一致のアルゴリズムが用いられています。マッチするものが複数ある場合、最も新しく生成されたキャッシュのみが復元されます。
keyの代わりに、keyをリスト化したkeysを指定することができます。keysで指定した場合、1度マッチすると、後のkeyについては捜索されません。この特徴とkeyの前方一致のアルゴリズムを利用した次のような記述は、より優れた記述方法です。

- restore_cache:
    keys:
      - v1-myapp-{{ arch }}-{{ checksum "project.clj" }}
      # 上の条件keyに一致するものがあれば、以下のkeyはチェックしない
      - v1-myapp-
    ... 

曖昧な条件を最後に指定することによって、keyが一致するキャッシュを取得できない、という事態を避けることができるでしょう。

cacheは、他のworkflowなどにアクセスを許可しても問題がなく、かつキャッシュすることで速度改善に効果があるようなデータを保存するために使われます。


deploy
デプロイに使用されます。キーや記号はrunと同じものが使用できます。振る舞いもrunと同じようになりますが、deployには並行性がなく(deployはnode #0でのみ実行される)、他の処理が全て成功した場合にのみ処理されます。

- deploy:
    command: |
      if [ "${CIRCLE_BRANCH}" == "master" ]; then
        ansible-playbook site.yml
      fi



store_artifacts
プログラムの実行ファイルやログを長期間保存するために使われます。
pathキーで保存するファイルを指定し、任意のdestinationキーで保存する際のファイル名を指定します。destinationキーを指定しない場合、ファイルパスがファイル名になります。store_artifactsに実行回数の制限はありません。同じファイルをdestinationキーを指定せずに保存すると、既に保存したファイルを上書きします。これを避けるためには、ユニークな名称をdestinationキーに指定する必要があります。
なお、保存されたファイル名はJava URLEncoderによってエンコードされています。
保存が完了すると、CircleCIのJobページのArtifactタブで確認することができます。

- store_artifacts:
    path: /code/test-results
    destination: prefix



persit_to_workspace
一時的にファイルやディレクトリを保存します。Workflowの処理が全て完了したら、workspaceは削除されます。また、Workflowをまたいだ共有はできません。
rootキーでworkspaceとして扱うrootディレクトリ(絶対パスまたはworking_directoryからの相対パス)を指定し、pathキーで保存する対象のファイルまたはディレクトリ(GoのGlobを使用している)をrootからの相対パスで指定します。ファイルのパターンマッチにはGoのfilepath - The Go Programming Languageが使用されています。

- persist_to_workspace:
    root: /tmp/workspace
    paths:
      - target/application.jar
      - build/*



attach_workspace
persist_to_workspaceによってworkspaceに保存されたものを、atキーで指定されたディレクトリに全て保存します。workspaceに保存されているものの削除はできません。
また、取得できるworkspaceの内容は、同じworkflowの上流のjobで保存された内容に限られます。
並行するjobが同じ名前でworkspaceに保存すると、attach_workspaceの処理でエラーになります。

- attach_workspace:
    at: /tmp/workspace


workspaceは、workflowの実行中の後続処理でしか必要のないデータを渡すために使われます。


紹介しきれていない内容もありますので、Configuring CircleCI - CircleCIを参照ください。

Git submodule の基礎 - Qiita