now を使ってデプロイするワークフロー

version: 2

references:
  config: &config
    working_directory: ~/repo
    docker:
      - image: circleci/node:8
  commands:
    print_pkg: &print_pkg
      run:
        name: Print package.json
        command: cat package.json
    restore_cache: &restore_cache
      restore_cache:
        keys:
          - v1-dependencies-{{ checksum "package.json" }}
          - v1-dependencies-
    save_cache: &save_cache
      save_cache:
        paths:
          - node_modules
        key: v1-dependencies-{{ checksum "package.json" }}
  scripts:
    yarn_install: &yarn_install
      run:
        name: Yarn install
        command: yarn --ignore-scripts
    yarn_install_now: &yarn_install_now
      run:
        name: Yarn install now
        command: yarn add -D now
    yarn_test: &yarn_test
      run:
        name: Yarn test
        command: yarn test
    yarn_now_deploy: &yarn_deploy
      run:
        name: Yarn deploy to now
        command: yarn deploy

jobs:
  setup:
    <<: *config
    steps:
      - checkout
      - *print_pkg
      - *restore_cache
      - *yarn_install
      - *save_cache
  test:
    <<: *config
    steps:
      - checkout
      - *print_pkg
      - *restore_cache
      - *yarn_install
      - *save_cache
      - *yarn_test
  deploy:
    <<: *config
    steps:
      - checkout
      - *print_pkg
      - *restore_cache
      - *yarn_install
      - *save_cache
      - *yarn_install_now
      - *yarn_deploy

workflows:
  version: 2
  deploy:
    jobs:
      - setup:
          filters:
            branches:
              only:
                - master
      - test:
          requires:
            - setup
      - deploy:
          requires:
            - test

基本複雑になりそうな部分はリファレンスブロックで細分化して管理しています。ワークフローの流れは以下のような感じです。

setup

masterブランチがgit pushで更新されると、まずこれが走ります。これは単に後の共通フローの高速化のためです。ここではyarnした時の結果をキャッシュして、後のフローでのyarnが早く終わるようにしています。

test

setupが無事に終わったのを確認してから走ります。主にテストを行い、それが正常に終了したらdeployにバトンタッチします。

deploy

testが無事に終わったのを確認してから走ります。ここでは now でのデプロイを行います。

- *yarn_install_now
- *yarn_deploy

がここ固有のステップでこれらは展開すると以下のようになります。

- run:
    name: Yarn install now
    command: yarn add -D now
- run:
    name: Yarn deploy to now
    command: yarn deploy
  1. nowをインストール
  2. now でデプロイ

now をインストール

nowを依存に含めないかと思うかもしれないですが、含めています。ただ依存のインストールを(環境によっては)もっと時間短縮になるyarn --ignore-scriptsを使ってインストールしていて、これだと now のインストールが完全に行われないため再度インストールしています。--ignore-scriptsというのはフックスクリプトを実行しないというオプションフラグです。

now でデプロイ

この run-scripts の中はこのように定義しています。(npm-run-allの中のrun-sという並行実行の記述をちょっと短縮できるコマンドを使ってます)

  1. デプロイ
  2. エイリアス設定
  3. エイリアス付けた環境以外削除

といういつものプロセスを行っています。

{
  "scripts": {
    "now.deploy": "now --team $NOW_TEAM --token $NOW_TOKEN",
    "now.alias": "now alias --team $NOW_TEAM --token $NOW_TOKEN",
    "now.rm": "now rm smilesumai-sindan.now.sh --team $NOW_TEAM --token $NOW_TOKEN",
    "deploy": "run-s now.deploy now.alias now.rm"
  }
}

$NOW_TEAMにはデプロイしたいチーム名、$NOW_TOKENには個人トークンを発行して設定します。これはら CircleCI の「 Environment Variables 」へ設定します。

結果

git pushして、うまくいけば以下のように完了するはずです。