LoginSignup
10
7

More than 5 years have passed since last update.

Google Cloud BuildでRSpecのテストを行う

Last updated at Posted at 2018-08-05

先日、Google Cloud BuildとGithubの連携が発表され、CIの実現がより簡単になりました。

この記事では、簡単なRailsアプリケーションを用意して、GithubのPull Request時にRSpecでテストを実行し、パスした場合にContainer RegistryにPushするまでの流れをまとめてみました。

前提

以下のコマンドを使用します。

  • docker (18.06.0-ce)
  • gcloud (Google Cloud SDK 210.0.0)

RailsアプリのDocker化

まずはRailsアプリケーションをDocker環境で準備します。
普段はDocker Composeを使って、アプリケーションとDB、KVSなどをそれぞれのコンテナで準備するのですが、今回はCI上で実行しやすいよう、1イメージにRubyとMySQLを含めます。

なお、各バージョンについては以下の通りです。

bash-4.4# ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-musl]
bash-4.4# mysql -V
mysql  Ver 15.1 Distrib 10.1.32-MariaDB, for Linux (x86_64) using readline 5.1
bash-4.4# rails -v
Rails 5.2.0

※ mysqlがMariaDBになっている部分については、後ほど説明します。

Dockerfile

Railsアプリを新規作成後、以下のDockerfileを作成しました。

FROM ruby:2.5.1-alpine3.7

RUN set -ex \
        && apk update \
        && apk upgrade \
        && apk add --no-cache  \
            build-base \
            bash \
            curl \
            nodejs \
            tzdata \
            mariadb \
            mariadb-client \
            mariadb-dev \
            openrc \
        # Setup mariadb (mysql)
        && mkdir -p /run/openrc \
        && touch /run/openrc/softlevel \
        && rc-status \
        && /etc/init.d/mariadb setup \
        && gem install bundler

WORKDIR /web

COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install

ADD . .
RUN chmod +x /web/rspec.sh

Rubyの公式イメージを土台にしています。
軽量化を図ってalpineにしたものの、前述したDBが同一イメージに入っているため、 943MB となりました。
この辺りはもう少し見直したいと思います…

接続先のDBですが、現在、alpineのパッケージマネージャでMySQLをインストールするとMariaDBが入ります。
MariaDBとは、MySQLから派生したオープンソースのRDBだそうで、パフォーマンスも良いらしいです。
細かい違いはあるものの、今回の動作確認では問題ないのでこのまま進めます。

rspec.sh は、以下のような内容が入っています。

rspec.sh
#!/bin/bash

# MariaDBの起動
rc-service mariadb start

rails db:create db:migrate
bundle exec rspec

MariaDBの起動後、Railsのいつものやつと、RSpecの実行コマンドです。
最終的には、CI上でこのシェルスクリプトが実行されます。

動作確認

ここまで一旦、動作確認が出来るか試してみましょう。
なにはともあれビルドします。今回はcloud-build-railsというイメージ名にしました。

$ docker build -t cloud-build-rails:v1 .

コンテナ内に入ります。

$ docker run -it -p 3000:3000 cloud-build-rails:v1 bash

MariaDBの起動、DBの準備、サーバーの起動をします。

# コンテナ内
$ rc-service mariadb start
$ rails db:create db:migrate
$ rails s

ブラウザから http://localhost:3000/ にアクセスして、Railsのオリジナルページが表示されればOKです。

モデルのテスト

本題ではないので、さくっと最小限のUserモデルを作っておきます。

$ rails g model user name:string age:integer
$ rails db:migrate

RSpecを導入して、Userモデルのテストを準備します。
ユーザが成人かどうかの簡単なテストです。

app/models/user.rb
class User < ApplicationRecord
  def adult?
    age >= 20
  end
end
spec/models/user_spec.rb
require "rails_helper"

RSpec.describe User, type: :model do
  it "成人かどうかが分かること" do
    user = User.new(name: "enta", age: 25)
    expect(user.adult?).to eq true
  end
end

問題なく通りますね。

Cloud Build

本題です。

プロジェクトの作成

まずは、GCPのコンソールからプロジェクトを作成し、Cloud Build APIを有効にします。
サンプルとしてcloud-build-railsというプロジェクト名にしました。

コマンドライン上でプロジェクトの設定

Cloudリソースへのアクセスを承認後、コマンドライン上でプロジェクトの設定を行います。
PROJECT_ID には、作成したプロジェクトのIDを指定します。

$ gcloud auth login
$ gcloud config set project PROJECT_ID

ビルドリクエストの作成

ビルドイメージの作成やテストの実行、デプロイの設定などをYAMLファイルで管理します。
今回はアプリケーション直下へ以下のファイルを準備しました。

cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-build-rails', '.']
- name: 'gcr.io/$PROJECT_ID/cloud-build-rails'
  args: ['/bin/bash', '/web/rspec.sh']

images: ['gcr.io/$PROJECT_ID/cloud-build-rails']

Cloud Buildは、stepsに書かれている内容を上から順に実行していきます。
ここでは、大きく2つのステップがあります。

1つはイメージのビルドです。
gcr.io/cloud-builders/docker は、すでにGoogleが用意している環境を使用する宣言です。
他にも git や 言語の go まで用意されており、詳しくはこちらで確認できます。

2つ目に実行しているのは、RSpecのテストです。
序盤で準備したシェルスクリプトを、先程ビルドした環境内で行います。

テストが終わると、最後に imagesにある、ビルドしたイメージがContainer RegistryにPushされます。

次のコマンドで動作確認をしてみます。

$ gcloud builds submit . --config=cloudbuild.yaml

STATUSSUCCESS になれば、Container Registryにイメージがあるはずです。

Container_Registry_-_cloud-build-rails.png

Pull Request時に実行する

最後に、GithubでPull Requestを作成したときに、CIを実行するようにしてみます。
といっても難しい設定は特になく、Github appで Google Cloud Buildをインストールします。

スクリーンショット 2018-08-05 22.51.24.png

All repositories にすると、他のリポジトリでも特別な設定が必要なく、Cloud buildが使えるようになります。

スクリーンショット 2018-08-05 22.51.51.png

Cloud Buildへのアクセスが許可されると、GCPのコンソール上でプロジェクトの作成or選択が必要になるので、既存のプロジェクトを選択 -> cloud-build-rails(作成したプロジェクト)を選択します。

スクリーンショット 2018-08-05 22.53.26.png

スクリーンショット 2018-08-05 22.53.48.png

同意して、接続すれば完了です。

動作確認

試しに、テストの内容を変えて、PRを作成してみます。

スクリーンショット 2018-08-06 2.37.53.png

CI実行中...

スクリーンショット 2018-08-06 2.39.11.png

ちゃんと止まってくれました。

それでは、テストを通すためにコードの修正と、ビルドしたイメージタグが現在は latest なので、コミットのSHAにするよう修正してみます。

コミットのSHA(先頭7文字)は $SHORT_SHA で取得が可能です。

cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloud-build-rails:$SHORT_SHA', '.']
- name: 'gcr.io/$PROJECT_ID/cloud-build-rails:$SHORT_SHA'
  args: ['/bin/bash', '/web/rspec.sh']

images: ['gcr.io/$PROJECT_ID/cloud-build-rails:$SHORT_SHA']

追加コミットをすると、テストが通り、Pushされたイメージのタグには、最新のSHAがつくようになりました。

スクリーンショット 2018-08-06 2.55.53.png

Container_Registry_-_cloud-build-rails 3.png

まとめ

既存のプロジェクトが既にDocker化されていれば、Cloud Build上でのビルド/テストなどは、比較的短時間で行えそうだと感触でした。秘匿情報の取り扱いもKMS(Cloud Key Management Service)が使えますし、ビルドトリガーを使用して指定ブランチへのPush時にGAEへデプロイする、といったことも簡単にできそうなので、もう少しいじってみたいと思います。

気になる料金ですが、CIの実行時間1分あたり、$0.003となっているものの、1日120分までは無料です。
現在使用しているCIサービスに不満を抱えている方は、試してみてはいかがでしょうか。

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7