CircleCI
angular
Firebase
CircleCI2.0

Angular プロジェクトのビルド・テスト・デプロイ環境を構築する

はじめに

  • 継続的なデリバリーはプロジェクトの初期段階でビルド・テスト・デプロイを自動化しておくことが秘訣、みたいな記事をよく見るので new したての Angular プロジェクトでビルド・テスト・デプロイ環境を構築した
  • CI は CircleCI を使っている

動作環境

  • 環境は下記
$ ng -v

    _                      _                 ____ _     ___
   / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
  / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
 / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
/_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
               |___/

Angular CLI: 1.6.7
Node: 8.9.0
OS: darwin x64
Angular: 5.2.4
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

@angular/cli: 1.6.7
@angular-devkit/build-optimizer: 0.0.42
@angular-devkit/core: 0.0.29
@angular-devkit/schematics: 0.0.52
@ngtools/json-schema: 1.1.0
@ngtools/webpack: 1.9.7
@schematics/angular: 0.1.17
typescript: 2.5.3
webpack: 3.10.0

Angular プロジェクトの作成

  • まずは Angular プロジェクトを作成する
    • 以降、プロジェクトに対する変更は何もしない(笑)
$ ng new <sample-app>

ビルド・テストの実行

  • Angular はプロジェクトを作成した状態でテストが備わっている

Lint, 単体テスト, E2E テスト

  • 下記コマンドでそれぞれ実行できる
$ yarn lint # TSLint
$ yarn test # 単体テスト
$ yarn e2e  # E2E テスト

CircleCI 上でのビルド環境構築

  • CircleCI の Hello World を参考に CircleCI の設定ファイルを用意する
    • ver 2.0 からは circle.yml ではなく、 .circleci/config.yml になっている
.circleci/config.yml
version: 2
jobs:
   build:
     docker:
       - image: circleci/node:8.9.4-stretch-browsers
     steps:
       - checkout
       - run: echo "hello world"
  • Node.js の image のバージョンは LTS の stretch-browsers を使用

CircleCI 上でのビルド・テストの設定

  • ビルド・テストの設定は下記のようになった
.circleci/config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/node:8.9.4-stretch-browsers
    steps:
      - checkout
      - run: echo "Start build"
      - run: yarn install
      - run: yarn build
  lint:
    docker:
      - image: circleci/node:8.9.4-stretch-browsers
    steps:
      - checkout
      - run: echo "Start lint"
      - run: yarn install
      - run: yarn lint
  test:
    docker:
      - image: circleci/node:8.9.4-stretch-browsers
    steps:
      - checkout
      - run: echo "Start test"
      - run: yarn install
      - run: yarn test --single-run
  e2e:
    docker:
      - image: circleci/node:8.9.4-stretch-browsers
    steps:
      - checkout
      - run: echo "Start e2e"
      - run: yarn install
      - run: yarn e2e
workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - lint:
          requires:
            - build
      - test:
          requires:
            - build
      - e2e:
          requires:
            - build
  • test は --single-run モードで実行した
    • オプションを付けないと watch し続けるので、1 回のみ実行
  • Workflows を設定して job が並列に実行されるようにした
    • requires を指定して lint, test, e2e は build が終わってから実行
    • build 後は lint, test, e2e が並列で実行される
    • 余談だがインデントがズレていたりすると CI が動かない

CircleCI から Firebase へデプロイ

  • Firebase へ deploy するための設定をする
    • Firebase にプロジェクトを作成する手順は割愛
  • CircleCI から Firebase を操作できるように firebase-tools を devdependencies でインストールしておく
$ yarn add firebase-tools -D
  • プロジェクトに Firebase の設定ファイルを作成するために下記コマンドを実行
$ firebase init
  • 色々聞かれるのでよしなに進める

    • 使うサービスは Hosting
    • public directory は dist/
    • single-page app は yes
  • CircleCI のために Firebase CLI token を生成する

$ firebase login:ci
  • 生成された token を CircleCI の環境変数に設定
    • Setting → Environment Variables から環境変数を追加
.circleci/config.yml
前略
...
  deploy:
    docker:
      - image: circleci/node:8.9.4-stretch-browsers
    steps:
      - checkout
      - run: echo "Start deploy"
      - run: yarn install
      - run: yarn build
      - run: yarn deploy
workflows:
  version: 2
  build_and_test:
    jobs:
      - build
      - lint:
          requires:
            - build
      - test:
          requires:
            - build
      - e2e:
          requires:
            - build
      - deploy:
          requires:
            - lint
            - test
            - e2e
          filters:
            branches:
              only: release
  • deploy は lint, test, e2e が全て終わってから実行される
  • また、branch が release のときだけ実行

GitHub 上から master ブランチに protection をかける

  • Settings → Branches から protection をかけ、CI が通らないと master にマージできないようにする

master_protection.png

最後に

  • README に Status Badge をつける!

まとめ

  • Pull Request 作成時に CircleCI でビルド・テストを走るようにした
    • lint, test, e2e すべてが SUCCESS にならないとマージできない
  • release ブランチへマージすると Firebase へデプロイするようにした