CircleCIのmachine Executorでbuildジョブからdeployジョブへとファイルの受け渡しを行う(Workspace)


概要

CircleCIのmachine Executorを使用して「Dockerビルド〜デプロイ」を行なっているプロジェクトにおいて、build jobで生成したファイル/ディレクトリをdeploy jobに渡す手順をメモ書きします。

方法(結論)

job間にWorkspaceを介してdeployに必要なファイル/ディレクトリを共有します。

persist_to_workspace

後続のdeploy jobへ提供したいファイル/ディレクトリをWorkspaceへアップロードします。

具体的には、build jobの最後のstepでpersist_to_workspaceを実行します。

config.yml
      - persist_to_workspace:
          root: .
          paths:
            - ./app/build
            - ./app/deps
  • root:
    • ルートにしたいコンテナ上のディレクトリ。
    • 絶対パス(もしくはworking_directoryからの相対パス)の形で指定します。
  • paths:
    • 上記rootからの相対パスで、jobs間で共有したいファイル/ディレクトリを指定します。

attach_workspace

Workspaceに保存されたデータをattach_workspaceで取得します。

.circleci/config.yml
      - attach_workspace:
          at: .
  • at:
    • 絶対パス(もしくはworking_directoryからの相対パス)の形で指定します。

補足説明

CircleCIのjobs隔離されている個々の環境で実行される仕様になっています。

.circleci/config.yml
# 例:build jobで生成されたファイルは、そのままではdeploy jobには渡らない
jobs:
  build:
    ...: ...

  deploy:
    ...: ...

そのため、特定のjobの結果を別のjobで使うためには、こういった「Workspaceでデータ共有する」などの方法で受け渡しを行う処理が必要となります。

(画像引用:CircleCI / Jobs overview

実行環境

  • macOS
  • GitHub(CircleCIと連携済)

シチュエーション

.
├── .circleci/
│   └── config.yml
├── app
│   ├── Dockerfile
│   ├── (build/)
│   ├── (deps/)
│   └── moge.json
└── docker-compose.yml
  • (build)
    build job中、docker-compose buildにより生成されたビルドファイル群を格納しています
  • (deps)
    擬似コード moge deps.get の実行により、app/moge.jsonへ記述した依存パッケージ群が生成されてdepsディレクトリに格納します
    • npm installでpackage.json記述パッケージをnode_modules/に格納するのと同じイメージです

コード

.circleci/config.yml
version: 2.1

orbs:
  # 擬似Orb
  deploy-orb: deploy-orb/deploy-orb@latest

executors:
  machine-executor:
    machine:
      image: ubuntu-1604:202010-01

workflows:
  version: 2
  build-deploy:
    jobs:
      - build
      - deploy:
          requires:
            - build

jobs:
  build:
    executor:
      name: machine-executor
    steps:
      - checkout
      - run:
          name: Build Docker container
          command: |
            set -x
            docker-compose build
      - run:
          name: Moge deps.get
          command: |
            set -x
           # 擬似コード(依存パッケージ取得)
            docker-compose run --rm app bash -c "moge deps.get"
      - run:
          name: Up Docker container
          command: docker-compose up -d
      - run:
          name: Moge test
          command: |
            set -x
           # 擬似コード(テスト実行)
            docker-compose exec app bash -c "moge test"
      - persist_to_workspace:
          root: .
          paths:
            - ./app/build
            - ./app/deps
      - run:
          name: Finish build
          command: echo "Finish build"
  deploy:
    executor:
      name: machine-executor
    steps:
      - checkout
      - attach_workspace:
          at: .
      - run:
          name: Check files/directories
          command: |
            set -x
            pwd && ls -a && ls app
      - run:
          name: Container push and release
          working_directory: app
          command: |
         # 擬似コード(本番環境へビルドコンテナをデプロイ)
            deploy-orb/install-and-push-release -a $YOUR_APP_NAME
      - run:
          name: Finish deploy
          command: echo "Finish deploy"

(参考)