circleci config pack で分割したymlから設定ファイル(config.yml)を作成してみた
概要
最近CircleCIに入門しました。config.ymlを書いているうちに記述量は少ないもののそれでもSlack通知のテンプレなど記述すると見通しが悪くなるので、なんとかしたいと思って調べてみるとCircleCI CLI
にcircleci config pack
というコマンドがありそれで、分割されたymlをパッケージ化できることを知ったので使ってみました。
因みにCircleCI2.1の想定です。
サンプルリポジトリ
サンプルとなるソースをリポジトリにまとめてみたのでこれを参考に紹介していきます。
CircleCI CLI
なにわともわれこれがないと進まないので以下のリンクを参照してcircleci
コマンドを使えるようにします。
因みに自分はbrew
を使ってインストールしました。
brew install circleci
# Mac 版の Docker を既にインストールしている場合は、
brew install --ignore-dependencies circleci
circleci config pack
コマンドは
circleci config pack <ディレクトリ名>
となります。
分割したymlを格納しているディレクトリを指定します。
以下のドキュメントに詳しく書かれています。
CLI の pack コマンドを使用すると、複数のファイルをまとめて 1 つの YAML ファイルを作成できます。 pack コマンドには、ディレクトリ ツリー内の複数ファイルにまたがる YAML ドキュメントを解析する FYAML が実装されています。 これは、容量の大きな Orbs のソース コードを分割している場合に特に利便性が高く、Orbs の YAML 構成のカスタム編成を行うことができます。 circleci config pack は、ディレクトリ構造とファイルの内容に基づいて、ファイル システム ツリーを 1 つの YAML ファイルに変換します。 pack コマンドを使用するときのファイルの名前や編成に応じて、最終的にどのような orb.yml が出力されるかが決まります。 以下のフォルダー構造を例に考えます。
以上、ドキュメントに書かれているように、ファイル名やディレクトリ構成などの制約が結構強いです。
また、CircleCI2.0で使用していたエイリアス・アンカーを別ファイルに分離して扱うのはサポートされていません。
完成予定のconfig.yml
見ての通りSlackのテンプレートが幅をきかせてます。
onfig.yml
version: 2.1
orbs:
aws-cli: circleci/[email protected]
aws-s3: circleci/[email protected]
slack: circleci/[email protected]
commands:
install_yarn_version:
description: Install specific Yarn version
steps:
- run:
command: |
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.10
echo 'export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"' >> $BASH_ENV
name: Install specific Yarn version
notify_slack_fail:
steps:
- slack/notify:
custom: |
{
"text": "CircleCI job failed.",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Job Failed. :red_circle:",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Job*: ${CIRCLE_JOB}"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Project*:\\n$CIRCLE_PROJECT_REPONAME"
},
{
"type": "mrkdwn",
"text": "*Branch*:\\n$CIRCLE_BRANCH"
},
{
"type": "mrkdwn",
"text": "*Author*:\\n$CIRCLE_USERNAME"
}
],
"accessory": {
"type": "image",
"image_url": "https://assets.brandfolder.com/otz5mn-bw4j2w-6jzqo8/original/circle-logo-badge-black.png",
"alt_text": "CircleCI logo"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Mentions*:\\n$SLACK_PARAM_MENTIONS"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
event: fail
notify_slack_pass:
steps:
- slack/notify:
custom: |
{
"text": "CircleCI job succeeded!",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Job Succeeded. :white_check_mark:",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Job*: ${CIRCLE_JOB}"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Project*:\\n$CIRCLE_PROJECT_REPONAME"
},
{
"type": "mrkdwn",
"text": "*Branch*:\\n$CIRCLE_BRANCH"
},
{
"type": "mrkdwn",
"text": "*Commit*:\\n$CIRCLE_SHA1"
},
{
"type": "mrkdwn",
"text": "*Author*:\\n$CIRCLE_USERNAME"
}
],
"accessory": {
"type": "image",
"image_url": "https://assets.brandfolder.com/otz5mn-bw4j2w-6jzqo8/original/circle-logo-badge-black.png",
"alt_text": "CircleCI logo"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
event: pass
restore_node_modules_cache:
steps:
- restore_cache:
keys:
- node_modules-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
name: Restore node_modules cache
restore_yarn_cache:
steps:
- restore_cache:
keys:
- yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
name: Restore Yarn cache
run_yarn_install:
description: Install dependencies
steps:
- run:
command: yarn install --frozen-lockfile
name: Install dependencies
save_node_modules_cache:
description: Save node_modules cache
steps:
- save_cache:
key: node_modules-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
name: Save node_modules cache
paths:
- node_modules
save_yarn_cache:
description: Save Yarn cache
steps:
- save_cache:
key: yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
name: Save Yarn cache
paths:
- ~/.cache/yarn
executors:
default:
docker:
- environment:
TZ: Asia/Tokyo
image: circleci/node:14.15.5
working_directory: ~/repo
jobs:
deploy_dev:
executor: default
steps:
- checkout
- attach_workspace:
at: .
- aws-s3/sync:
arguments: --delete
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-region: AWS_DEFAULT_REGION
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
from: ./dist/
to: s3://dev.7890987.xyz
- aws-cli/setup:
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-region: AWS_DEFAULT_REGION
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
profile-name: default
- run:
command: |
aws cloudfront create-invalidation --distribution-id "$CLOUDFRONT_DISTRIBUTION_ID" --paths '/*'
name: Restore CloudFront cache
- notify_slack_fail
- notify_slack_pass
prepare:
executor: default
steps:
- checkout
- install_yarn_version
- restore_yarn_cache
- restore_node_modules_cache
- run_yarn_install
- save_yarn_cache
- save_node_modules_cache
- run:
command: yarn build
name: Build
- persist_to_workspace:
paths:
- node_modules
- dist
root: .
- notify_slack_fail
slack:
executor: default
steps:
- run:
command: echo test
name: Send Notification to Slack
- notify_slack_pass
workflows:
version: 2
deploy_dev:
jobs:
- prepare:
filters:
branches:
only:
- develop
- deploy_dev:
filters:
branches:
only:
- develop
requires:
- prepare
release:
jobs:
- prepare:
filters:
branches:
only:
- main
tags:
only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
- slack:
filters:
branches:
only:
- main
tags:
only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
requires:
- prepare
ディレクトリ構成とマッピング
.circleci
ディレクトリとは別に分割したファイルだけ管理するcircleci
ディレクトリを作成しています。
$ tree
.
└── circleci
├── @orb.yml
├── commands
│ ├── @commands.yml
│ └── @slack.yml
├── executors
│ └── default.yml
├── jobs
│ ├── deploy_dev.yml
│ ├── deploy_prod.yml
│ └── prepare.yml
└── workflows
├── @workflows.yml
├── develop.yml
└── release.yml
上記のディレクトリ構成の場合、以下のようにマッピングされます。
@ で始まるファイルの内容は、その親フォルダーのレベルにマージされます。
# ここに @orb.yml の内容が表示されます
commands:
# ここに @commands.yml の内容が表示されます
# ここに @slack.yml の内容が表示されます
executors:
default: # この default フォルダーは default.ymlに @ が付いていない為です。
# ここに default.yml の内容が表示されます
jobs:
deploy_dev:
# ここに deploy_dev.yml の内容が表示されます
deploy_prod:
# ここに deploy_prod.yml の内容が表示されます
prepare:
# ここに prepare.yml の内容が表示されます
workflows:
# ここに @workflows.yml の内容が表示されます
develop:
# ここに develop.yml の内容が表示されます
release:
# ここに release.yml の内容が表示されます
ファイルの中身
circleci/@orb.yml
version: 2.1
orbs:
aws-cli: circleci/[email protected]
aws-s3: circleci/[email protected]
slack: circleci/[email protected]
circleciのバージョンとorbの宣言のみにしてます。
circleci/commands/@commands.yml
install_yarn_version:
description: 'Install specific Yarn version'
steps:
- run:
name: Install specific Yarn version
command: |
curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.22.10
echo 'export PATH="$HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH"' >> $BASH_ENV
restore_yarn_cache:
steps:
- restore_cache:
name: Restore Yarn cache
keys:
- yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
save_yarn_cache:
description: 'Save Yarn cache'
steps:
- save_cache:
name: Save Yarn cache
key: yarn-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache/yarn
run_yarn_install:
description: 'Install dependencies'
steps:
- run:
name: Install dependencies
command: yarn install --frozen-lockfile
restore_node_modules_cache:
steps:
- restore_cache:
name: Restore node_modules cache
keys:
- node_modules-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
save_node_modules_cache:
description: 'Save node_modules cache'
steps:
- save_cache:
name: Save node_modules cache
key: node_modules-{{ .Branch }}-packages-{{ checksum "yarn.lock" }}
paths:
- node_modules
yarnのインストールやキャッシュ周りのコマンドを集約してます。
circleci/commands/@slack.yml
notify_slack_pass:
steps:
- slack/notify:
event: pass
custom: |
{
"text": "CircleCI job succeeded!",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Job Succeeded. :white_check_mark:",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Job*: ${CIRCLE_JOB}"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Project*:\\n$CIRCLE_PROJECT_REPONAME"
},
{
"type": "mrkdwn",
"text": "*Branch*:\\n$CIRCLE_BRANCH"
},
{
"type": "mrkdwn",
"text": "*Commit*:\\n$CIRCLE_SHA1"
},
{
"type": "mrkdwn",
"text": "*Author*:\\n$CIRCLE_USERNAME"
}
],
"accessory": {
"type": "image",
"image_url": "https://assets.brandfolder.com/otz5mn-bw4j2w-6jzqo8/original/circle-logo-badge-black.png",
"alt_text": "CircleCI logo"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
notify_slack_fail:
steps:
- slack/notify:
event: fail
custom: |
{
"text": "CircleCI job failed.",
"blocks": [
{
"type": "header",
"text": {
"type": "plain_text",
"text": "Job Failed. :red_circle:",
"emoji": true
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Job*: ${CIRCLE_JOB}"
}
]
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Project*:\\n$CIRCLE_PROJECT_REPONAME"
},
{
"type": "mrkdwn",
"text": "*Branch*:\\n$CIRCLE_BRANCH"
},
{
"type": "mrkdwn",
"text": "*Author*:\\n$CIRCLE_USERNAME"
}
],
"accessory": {
"type": "image",
"image_url": "https://assets.brandfolder.com/otz5mn-bw4j2w-6jzqo8/original/circle-logo-badge-black.png",
"alt_text": "CircleCI logo"
}
},
{
"type": "section",
"fields": [
{
"type": "mrkdwn",
"text": "*Mentions*:\\n$SLACK_PARAM_MENTIONS"
}
]
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": {
"type": "plain_text",
"text": "View Job"
},
"url": "${CIRCLE_BUILD_URL}"
}
]
}
]
}
Slack周りをここに集約してます。これが一番邪魔だったんでスッキリしました。
circleci/executors/default.yml
working_directory: ~/repo
docker:
- image: circleci/node:14.15.5
environment:
TZ: Asia/Tokyo
今はdefaultだけですが、環境毎のExecutorファイルをこのディレクトリで管理。
circleci/jobs/prepare.yml
executor: default
steps:
- checkout
- install_yarn_version
- restore_yarn_cache
- restore_node_modules_cache
- run_yarn_install
- save_yarn_cache
- save_node_modules_cache
- run:
name: Build
command: yarn build
- persist_to_workspace:
root: .
paths:
- node_modules
- dist
- notify_slack_fail
circleci/jobs/deploy_dev.ymlとcircleci/jobs/deploy_prod.yml
executor: default
steps:
- checkout
- attach_workspace:
at: .
- aws-s3/sync:
from: ./dist/
to: "s3://buecketname"
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
aws-region: AWS_DEFAULT_REGION
arguments: --delete
- aws-cli/setup:
profile-name: default
aws-access-key-id: AWS_ACCESS_KEY_ID
aws-secret-access-key: AWS_SECRET_ACCESS_KEY
aws-region: AWS_DEFAULT_REGION
- run:
name: Restore CloudFront cache
command: |
aws cloudfront create-invalidation --distribution-id "$CLOUDFRONT_DISTRIBUTION_ID" --paths '/*'
- notify_slack_fail
- notify_slack_pass
circleci/workflows/@workflows.yml
version: 2
Workflowのバージョンだけの為のファイル
circleci/workflows/develop.yml
jobs:
- prepare:
filters:
branches:
only:
- develop
- deploy_dev:
requires:
- prepare
filters:
branches:
only:
- develop
circleci/workflows/release.yml
jobs:
- prepare:
filters:
tags:
only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
branches:
only:
- main
- deploy_prod:
requires:
- prepare
filters:
tags:
only: /^v[0-9]+\.[0-9]+\.[0-9]+$/
branches:
only:
- main
config.ymlの作成
以下のコマンドを実行します。
# circleci config pack <ディレクトリ名>
circleci config pack circleci
すると統合された結果が出力されます。
ただ、出力される内容はお世辞にも綺麗ではないです。。。
なのでリダイレクトを使うなどしてconfig.yml
に直接上書きしてしまうのが手っ取り早いかと思います。
circleci config pack circleci >| .circleci/config.yml
また、config.ymlを作成後はconfig.yml
のバリデーションをお勧めします。
自分の場合、インデント周りでエラーがでまくりでした。
circleci validate
Author And Source
この問題について(circleci config pack で分割したymlから設定ファイル(config.yml)を作成してみた), 我々は、より多くの情報をここで見つけました https://qiita.com/grasswake/items/69c0f639e9f16e58c1dc著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .