初投稿になります。
Bitbucket pilelinesって?
Atlassian製のCIツールです。
BitbucketへのアクションをトリガーとしてDockerコンテナ上でタスクを実行してくれます。
当然ながらBitbucketをリポジトリとして利用していないと意味ないです。
元々の悩み
- Bitbucketでプルリク送ったけど、これテスト通ってんの?とかいちいち確認したくない
- developにマージしてから確認だとプルリク閉じちゃっている場合あるし、そもそもテスト通ってからプルリク送れや( ゚д゚ )とか荒ぶることになってしまう。
やりたいこと
タイトルの通り、Bitbucket Pilelines使ってbranchへpushした時にユニットテストを動かしてしまおう作戦
問題
- push単位だとジョブが割と頻繁に動作してしまう → とりあえずpipelinesは今の所タダだし良いか( ´∀`)
設定
Bitbucket Pipelinesを開始するには、まず以下の手順で有効にする必要があります。
リポジトリの設定 > PIPELINESのSettings > Enable Pipelinesをクリック
これで有効になるので、プロジェクトのルートにbitbucket-pipelines.ymlを設置することでタスクを実行させることが出来ます。
bitbucket-pipelines.yml
とりあえず、今回やった対応を載せちゃいます。
image: ruby:2.3.0
pipelines:
default: # ブランチの指定。defaultの場合は全てのブランチが対象になります。
- step: # 実行単位
script: # 実行するコマンドを登録していきます。
# expect install
- apt-get update
- apt-get install -y expect
# mysql install
- wget -O mysql-apt-config.deb http://dev.mysql.com/get/mysql-apt-config_0.3.5-1debian8_all.deb
- expect -c "set timeout -1; spawn dpkg -i mysql-apt-config.deb; expect \"Which MySQL product do you wish to configure?\"; send \"2\n\"; expect \"$\""
- apt-get update
- expect -c "set timeout -1; spawn apt-get install -y mysql-server-5.6 -y --force-yes; expect \"Enter root password:\"; send \"\n\"; expect \"$\""
- cp -p deployment/etc/mysql/test.cnf /etc/mysql/conf.d/
- chmod 644 /etc/mysql/conf.d/test.cnf
- /etc/init.d/mysql start
- mysql -uroot -e 'create database sample_test DEFAULT CHARACTER SET utf8mb4'
# project setting & exec rspec
- bundle install
- bundle exec rake db:migrate RAILS_ENV=test
- bundle exec rspec spec
全てのbranchでpushしたらテストコードを実行するので、対象はdefaultにします。
もしbranch名で対象を広げたいのであれば、defaultと記述している箇所をブランチ名に変更します。
stepは配列ですが、現状は1つしか登録出来ないようです。
scriptに実際に実行するコマンドを記述していくことになります。
今回はテストだけ実行させるので、RubyのコンテナイメージにMySQLをインストールしてrspecを実行します。
Ruby + MySQLのコンテナイメージもあったのですが、MySQLのバージョンが利用したいものとは違ったので、仕方なく手動で導入することにしました。
自分でコンテナイメージ作って、Docker Hubに上げればいいのですが、今回は検証も兼ねてpipelines上のコマンドでインストールしていきます。
ちなみに rubyのコンテナイメージのOSはdebian8でした。
MySQLインストール & DB作成
MySQL自体はOracleからリポジトリ情報取得して、aptでインストールすることになるのですが、その際に対話式で設定を行います。
そこで、expectで自動入力させることにしました。
コマンドが見難いので、ファイルに移してシェルスクリプトで実行した方が良いかもしれません。
もし、apt-get installでこの対話式の設定を行わないやり方知っている人教えてください(´・ω・`)
DBの作成はmysqlコマンドで行っています。
テスト実行のみなので、DBのユーザーはrootにしちゃっています。
テスト実行
Gemfileが更新されている可能性があるのでbundle installを実行し、db:migrateでDBを作成してからrspecを実行します。
この状態でbitbucket-pipelines.ymlファイルをプロジェクトルートに設置した状態で、Bitbucketにpushすると自動的にpipelinesが起動します。
rspecまで無事完了すればpipelinesのステータスがSuccessfulになります。
今後の課題
- テストだけじゃなくてデプロイもしたいので、AWSのcodedeploy + capistranoで実現する
- ジョブの成功可否をチャットで通知する
- 静的解析やカバレッジレポートのアップロードをする
とかですかね。
プルリクエストを送る前にユニットテストの実行可否を確認出来るので、テスト通った?とか自分の環境にpullしてきてテスト動かしてみるとかしなくて良いのは素晴らしいです。
コンテナでgitからソースを持ってくる必要もないので、gitの認証情報の管理もしなくていいですし、そもそも動かすの簡単なので割とおすすめですよ。