モチベーション
- CircleCIをもっと活用したい
- ドキュメント作成をプログラムちっくにしたい
- ER図を毎回更新したくない
- サーバレス(今回がサーバレスかは置いてといて)やりたい
- ソースコードとドキュメントをプルリクの中で見れたら幸せと思う
使用技術
- CircleCI 2.0
- Rails 5.1.5
- Mysql 5.7
- AWS S3
- AWS Lambda
- AWS CloudFront
- Gitbook
Railsアプリをサンプルにします。
全体構成
Githubにpushすると、それをフックにCircleCIがBuild & Deployを行います。
S3にアップロードしたものをCloudFront経由で配信します。
Lambdaにbasic認証のコードを書いて、リクエストがきたら認証を求めます。
これで限定されたドキュメント公開ができます。
実装
前提条件
- CircleCIのアカウントがある
- Gitbookが使える
- IAMユーザー作成済み
S3
- S3のbucketを作成する
-
<bucket-name>-docs
というプレフィックスを付ける(管理のため) - バケットポリシーやホスティング設定は不要なので何もしない(CloudFrontでやる)
CircleCI
- Buildするリポジトリを追加
- 追加したリポジトリの設定から「AWS Permissions」を選択してIAMのキーを設定する
Markdown
リポジトリのルートにdocs
フォルダを作ってその中でgitbookを使います。
$ mkdir docs
$ cd docs
$ gitbook init
$ echo /docs/_book >> .gitignore
あとはMarkdownでゴリゴリ書きます。
注意:名前はdocsじゃなくてもいいですが、CircleCIの設定ファイルで指定しているので合わせる必要があります。
設定ファイル
以下の要件で設定ファイルを作ってみました。
1. Rspec実行
2. rails-erdからER図を生成し、docs/img
に移動する
3. gitbookでdocs配下のmdファイルからhtmlファイルを生成
4. S3にアップロード
5. 3,4は特定のbranchのみ動作させたい
version: 2
workspace_root: &workspace_root
~/workspace
defaults: &defaults
docker:
- image: circleci/ruby:2.4.2-node-browsers
environment:
RAILS_ENV: test
BUNDLE_JOBS: 3
BUNDLE_RETRY: 3
BUNDLE_PATH: vendor/bundle
DB_HOST: 127.0.0.1
- image: circleci/mysql:5.7
working_directory: *workspace_root
attach_workspace: &attach_workspace
attach_workspace:
at: *workspace_root
jobs:
build:
<<: *defaults
steps:
- checkout
# Restore bundle cache
- restore_cache:
keys:
- bundle-{{ checksum "Gemfile.lock" }}
- bundle
- run:
name: Bundle Install
command: bundle check || bundle install
# Store bundle cache
- save_cache:
key: bundle-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
# Database setup
- run:
name: Database setup
command: |
bin/rails db:create
bin/rails db:schema:load
# Run rspec in parallel
- run:
name: Run tests
command: |
bundle exec rspec --profile 10 \
--format RspecJunitFormatter \
--out test_results/rspec.xml \
--format progress \
$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
# Save test results for timing analysis
- store_test_results:
path: test_results
- persist_to_workspace:
root: *workspace_root
paths:
- .
docs:
<<: *defaults
steps:
- <<: *attach_workspace
- run:
name: Install dependencies
command: |
sudo apt-get install graphviz
sudo npm install gitbook-cli -g
- run:
name: ER diagram
command: |
bin/rails db:create
bin/rails db:schema:load
bundle exec erd --attributes=foreign_keys,primary_keys,content,timestamp --filename=erd --filetype=png
mv -f erd.png docs/img/
- run:
name: Gitbook
command: gitbook build docs docs/_book
- persist_to_workspace:
root: *workspace_root
paths:
- docs
deploy_s3:
<<: *defaults
steps:
- <<: *attach_workspace
- run:
name: Install dependencies
command: sudo apt-get -y -qq install awscli
- run:
name: Deploy to S3 if tests pass and branch is Master
command: aws s3 sync docs/_book s3://$S3_BUCKET --delete
workflows:
version: 2
workflows:
jobs:
- build
- docs:
requires:
- build
filters:
branches:
only: develop
- deploy_s3:
requires:
- build
- docs
filters:
branches:
only: develop
Build
CircleCI2.0で追加されたworkflowsを使うと次のように複数のjobが連結された感じで実行されます。
何か気持ちいい。
Basic認証をかけて公開する
参考記事にあるこちらを参考にさせていただきました。
ありがとうございます!
ハマった点
awscliの使い方
S3にsyncするときにbucket名の指定にs3://
を付けないといけないところ
CircleCI 2.0の設定ファイルの書き方
1.0と2.0が書き方が全然違うので学習コストかかるところ
Build中にxxxx command not found
apt-get
しているはずが、コマンドがないと怒られました。
sudo
を付けたら解決しました。
Railsでmysqlを使う場合
config/database.yml
を変更する必要がありました。
test:
<<: *default
adapter: mysql2
database: yourapp_test
host: <%= ENV['DB_HOST'] || 'localhost' %> # 追加
このDB_HOST
にはCircleCIの設定ファイルで書いたDB_HOST: 127.0.0.1
が入ります。
localhost
だとエラーになるようです。
参考記事
gitbookで楽々ドキュメント作成
GitBook/GitHub/CircleCIでメンテ可能な仕様書を書く
CircleCIを使ってS3にブログをデプロイする
CircleCI 2.0 に移行しました
CloudfrontとS3でBasic認証をかける
Github, CircleCI, S3, CloudFront, Middlemanを活用して、https対応のサーバレスで自動deployなWEBサイト構築
成果物
CircleCIのデプロイ部分を一部コメントにしてるので、適宜変更してください。
erd生成はないです。
終わりに
これでソースコードと一緒にドキュメントも管理できて、クライアントにもbasic認証で共有できて
レビューもしやすくなる、そして幸せになるw