あらすじ
- ふだん無意識に読み飛ばしているが使おうと思ったときに出てこなかった
- YAML の anchor と alias を使うと色々 DRY に書ける
- DRYに書いた
Anchor/Alias
YAML では &name
(Anchor) で名前をつけて *name
(Alias) で参照することができる*1。
Example1: 重複排除
こんな感じの CircleCI 用の config.yml。
version: 2 jobs: bundle_npm_dependencies: docker: - image: circleci/node:8.7.0 steps: - checkout - restore_cache: # <= 1つめ keys: - key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - key-name-{{ arch }} - run: yarn install --pure-lockfile - save_cache: key: key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} paths: - node_modules test: docker: - image: circleci/node:8.7.0 steps: - checkout - restore_cache: # <= 2つめ keys: - key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - key-name-{{ arch }} deploy: docker: - image: circleci/node:8.7.0 steps: - checkout - restore_cache: # <= 3つめ keys: - key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - key-name-{{ arch }} - deploy: command: ./scripts/${CIRCLE_JOB}.sh
中身はともかく restore_cache
のステップが複数箇所存在する。キャッシュを invalidate するために key name を変える場合は3箇所漏れ無く更新しないといけない。
これを anchor & alias 使い、初出箇所で参照可能にする。
version: 2 jobs: bundle_npm_dependencies: docker: - image: circleci/node:8.7.0 steps: - checkout - restore_cache: &restore_cache # <= anchor 作成 keys: - key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - key-name-{{ arch }} - run: yarn install --pure-lockfile - save_cache: key: key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} paths: - node_modules test: docker: - image: circleci/node:8.7.0 steps: - checkout - *restore_cache # <= 参照 deploy: docker: - image: circleci/node:8.7.0 steps: - checkout - *restore_cache # <= 参照 - deploy: command: ./scripts/${CIRCLE_JOB}.sh
宣言箇所がわかりづらいのでファイルの先頭にまとめたりする。
version: 2 anchors: - cache_key: &cache_key key-name-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }} - restore_cache: &restore_cache keys: - *cache_key - key-name-{{ arch }} - image_name: &image_name circleci/node:8.7.0 jobs: bundle_npm_dependencies: docker: - image: *image_name steps: - checkout - *restore_cache - run: yarn install --pure-lockfile - save_cache: key: *cache_key paths: - node_modules test: docker: - image: *image_name steps: - checkout - *restore_cache deploy: docker: - image: *image_name steps: - checkout - *restore_cache - deploy: command: ./scripts/${CIRCLE_JOB}.sh
Example2: 環境変数として定義した値を参照
CircleCI の environment で設定した環境変数を使いまわしたいとき。
# NG例 version: 2 jobs: test: docker: - image: image_name environment: ARTIFACT_PATH: "/tmp/artifacts" steps: - run: mkdir -p ${ARTIFACT_PATH} - store_artifacts: path: ${ARTIFACT_PATH}
shell command の中に書かれた値は変数展開されるが、そうでない箇所は当然ながらただの文字列として解釈されてしまう。JSON に parse するとわかる。
{ "version": 2, "jobs": { "test": { "docker": [ { "environment": { "ARTIFACT_PATH": "/tmp/artifacts" }, "image": "image_name" } ], "steps": [ { "run": "mkdir -p ${ARTIFACT_PATH}" }, { "store_artifacts": { "path": "${ARTIFACT_PATH}" # <= ココ } } ] } } }
こういうときにも anchor & alias は使える。
version: 2 jobs: test: docker: - image: image_name environment: ARTIFACT_PATH: &artifact_path "/tmp/artifacts" steps: - run: mkdir -p ${ARTIFACT_PATH} - store_artifacts: path: *artifact_path
値の一部として展開することはできないので run: mkdir -p *artifact_path
はNG。
その他
- Online YAML Parser 便利
- そもそも YAML の仕様書ってどこにあるんだ => YAML™ Specification Index のようだが読む気が起きない
- DRYに書いたからといって読みやすくなるわけではないことも多いので留意