日本語だと継続的インテグレーションとも言われるContinuous Integrationについて。
Continuous Integrationとは
Continuous Integration(継続的インテグレーション)とは、従来のデベロッパがそれぞれ独立で開発を行い開発サイクルの最後にインテグレーションを行う方法ではなく、日に何度もそれぞれのデベロッパがmasterブランチにインテグレーションするやり方。
何をするの?
各デベロッパは書いたコードを一日のうちに何度でもシェアでき、コミットのたびに自動でビルドとテストが実行され、ビルドあるいはテストが失敗した場合は、それをすぐに修正する。
どうしてするの?
開発チームをより生産的に、より効率的に、よりハッピーになるため。問題を見つけてそれらを素早く解決する。高品質かつより安定したプロダクトをリリースするため。
CircleciのOverviewより引用でした。 Overview - CircleCI
プライベートプロジェクトで使ってみた
普段からちょくちょくいじってはアップデートしている自分のウェブサイトを題材にCircleciを使ってみる。プロジェクトで使用している技術はフロントがVue.jsでサーバにExpressを使っている。
.ymlファイルを追加
はじめに、プロジェクトのルートに.circleci
フォルダを作成し、そのフォルダにconfig.yml
というファイルを追加する。
.circleci/config.yml
次に、.ymlファイルにCircleciのための設定を記述する。この設定は、CircleciでGithubと連携し、利用するレポジトリを選択したあと、使用する言語を選択すると自動でサンプルが作られるのでそれを利用する。僕の環境だと以下の.ymlファイルが提供された。
# Javascript Node CircleCI 2.0 configuration file # # Check https://circleci.com/docs/2.0/language-javascript/ for more details # version: 2 jobs: build: docker: # specify the version you desire here - image: circleci/node:7.10 # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images # documented at https://circleci.com/docs/2.0/circleci-images/ # - image: circleci/mongo:3.4.4 working_directory: ~/repo steps: - checkout # Download and cache dependencies - restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }} # fallback to using the latest cache if no exact match is found - v1-dependencies- - run: yarn install - save_cache: paths: - node_modules key: v1-dependencies-{{ checksum "package.json" }} # run tests! - run: yarn test
というわけで、とりあえずpushしちゃえ!と思ってpushした。
初コミットで学んだこと
まずひとつ目はなぜか僕はCicleCI 1.0を使っていたようで警告がでていた。(公式の設定どおりにしたんだけど。。。) バージョン1.0のサポートは2018年8月31日までとのこと。それってつまり4日後。すばらしい100時間後にはゴミになる知識を一部吸収していたようだ。CircleCI 2.0に移行しよう。
CircleCIがしてくれること(の一部)
僕の人生初CircleCI体験で、確認できた工程は以下の通り。(失敗で終わってます)
インフラストラクチャ
- ビルドのjobをスタート
- コンテナを起動させる
- SSHを有効化する
チェックアウト
- ソースキャッシュの復元
- デプロイキーの確認
マシーン
- ビルドされたものの設定
- キャッシュの復元
依存関係
NODE_ENV
をexportする- PATHを通す
npm install
する
データベース
- キャッシュを保存
ティアダウン(取り壊し)
以上。
失敗してました💧
気軽にコミットしただけでconfig.ymlだってちゃんといじってないから、まぁそうよね。今回は「テストが見つからないよ〜〜><」って言われて作業が終了していました。(そういえばこのプロジェクト規模が小さすぎてテスト書いてない!)
正常終了するために
config.yml
にすべての答えがあるはずだ。でも、そもそもCircleCI 2.0じゃないよと怒られているので、上に貼ったconfig.yml
は忘れて、警告に載ってたリンク先にあったconfig.yml
を見てみよう。
version: 2 jobs: build: docker: - image: circleci/<language>:<version TAG> steps: - checkout - run: <command> test: docker: - image: circleci/<language>:<version TAG> steps: - checkout - run: <command> workflows: version: 2 build_and_test: jobs: - build - test
内容はなんの難しいこともない。(たぶん)version
指定から始まり、実行したい処理をjobs
のインデント下に書いていく。見て分かる通り、build
とtest
がある。
そのあとworkflows
に処理を行う流れを書いていくと。CircleCIはこの順番で処理を行うみたいだね。なるほど。つまり、今回の僕のばあい、本当はよくないけどテストが無いから💧テストの処理をここに書かなければ正常終了までたどり着けるはず。
テストを含まないContinuous Integrationって論外だけど、まぁまずはBuildだけうまくいってからテスト追加してもいいんじゃないかな!!
数時間後……
たどり着いた正常終了
なんとかちゃんと動くconfig.yml
が完成しました。$HEROKU_API_KEY
と $HEROKU_APP_NAME
はCircleCIのサイトから環境変数に追加できます。Herokuにデプロイするばあいは、チェックして設定しましょう。
最終的なconfig.yml
version: 2 jobs: build: docker: - image: circleci/node:10 working_directory: ~/repo steps: - checkout - restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }} - run: npm install - run: npm run build - persist_to_workspace: root: . paths: dist - save_cache: paths: - node_modules - dist key: v1-dependencies-{{ checksum "package.json" }} deploy: docker: - image: circleci/node:10 working_directory: ~/repo steps: - checkout - attach_workspace: at: ~/repo - restore_cache: key: v1-dependencies-{{ checksum "package.json" }} - run: git config user.name "ユーザ名" - run: git config user.email "メールアドレス" - run: git add . - run: git commit -m "from CircleCI" - run: name: Deploy Master to Heroku command: | git push https://heroku:$HEROKU_API_KEY@git.heroku.com/$HEROKU_APP_NAME.git master workflows: version: 2 build-deploy: jobs: - build - deploy: requires: - build filters: branches: only: master
jobs
にbuild
とdeploy
を設定してworkflow
でビルド後にデプロイするように設定。
大事な箇所はキャッシュ周りの記述。
- restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }}
ビルドする前に、前回のビルドしたときのキャッシュを復元している。このキャッシュを管理する際に、keys
を用いる。package.json
のchecksumを使って一意なkeyにしている。その後、依存関係を解消して、キャッシュを保存してビルドが行われる。
最後に
キャッシュ周りの設定は本来、ビルドファイルと依存関係を分けたほうがいいと思う。まだ雑な部分が多い。またdeploy
部分については、gitの箇所は多分調べればもっと良いやりかたがあるはず。
まぁ、何はともあれ、これでひとまずpushするだけで自動でbuildされてHerokuにpushされる環境が出来上がったのでよしとする。引き続き、CircleCIについて学んでいこうと決心した。