GitHubからGitLabに移行したので、GitLab-CI(Docker環境)でRails+MinitestをHeadlessChromeで回そうと思ったらめっちゃ大変だった

この記事を書いたひと: @t4traw 2018年6月7日

GitHubがMicrosoftに買収されて、GitLabに移行するのがブーム(🏄❓)になっています。

自分としては最近のMicrosoftなかなか良いので、まあGitHubも大丈夫なんじゃないの?とは思いますが、もともとGitLabは好印象なサービスだったので、いい機会だからプライベートリポジトリはGitLabに移行してみることにしてみました。

GitHubの時、CIはCircleCIを使っていたのですが、GitLabにはGitLab CIなるものが標準であるようなので、せっかくだからこちらを使ってみようと思ったら……めっちゃ大変だったので、ここに2018年6月7日時点で無事動いた内容を書いておきます😭

とりあえずRails+Minitestな環境で、簡単なE2Eテストを動かしてみたリポジトリがこちら。

https://gitlab.com/t4traw/hello-gitlab-ci pipeline status

最終的に.gitlab-ci.ymlはこんな感じになりました。

.gitlab-ci.yml
image: ruby:2.5

services:
  - postgres:latest

variables:
  POSTGRES_DB: test_db
  POSTGRES_USER: runner
  POSTGRES_PASSWORD: ""
  RUBYOPT: --encoding=UTF-8

stages:
  - test

before_script:
  - apt-get update -qy
  
  # Install nodejs
  - curl -sL https://deb.nodesource.com/setup_10.x | bash -
  - apt-get install -y nodejs

  - bundle install
  
  # Install yarn
  - curl -o- -L https://yarnpkg.com/install.sh | bash
  - export PATH="$HOME/.yarn/bin:$PATH"
  - yarn install --ignore-engines
  
  # Install Chrome
  - apt-get install -y gdebi
  - curl -O https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
  - gdebi -n -q google-chrome-stable_current_amd64.deb
  
  # Set up database.yml
  - cp config/gitlab-database.yml config/database.yml
  
  # Create databse
  - RAILS_ENV=test bundle exec rails db:create db:schema:load

test:
  stage: test
  script:
  - bundle exec brakeman -4 -A -w 1 -z
  - bundle exec rails test
  - bundle exec rails test:system

以下、大変だったことをつらつらと。

nodejsの最新版がapt-getで落ちてこない

GitLabのマニュアルにapt-get install -y nodejsとしか書いていないので、そのとおりにしたらapt-getで落ちてくるnodejsのバージョンが4.3という問題。2018年6月7日時点で最新のnodejsは10.4。全然違うじゃないと😢

具体的にはyarn周りでコケるので、yarn install --ignore-enginesすれば大丈夫?と思ったけど、やっぱりダメだった。ので、公式のcurl -sL https://deb.nodesource.com/setup_10.x | bash -してインストールして最新のnodejsを入れました。

yarnがうまく動かない

これはnodejsがそもそもまともにインストールしていない状態だったからかもしれませんが、yarnもapt-getではうまく動きませんでした💦

なので、こちらも公式のcurl -o- -L https://yarnpkg.com/install.sh | bashでインストールし、更にPATHを通すことでyarnが使えるようになりました。

Headless chromeが全然まともに動かない

ここが一番大変だった😫 そもそもインストールがdpkg -i google-chrome.debとかやっても全然うまくいかず、gdebiというパッケージがある事を初めて知り無事インストールできたものの、Selenium::WebDriver::Error::UnknownError: unknown error: DevToolsActivePort file doesn’t existというエラーが出て、何度もセッティングを書き直してトライ&エラーを繰り返しました。

正解かどうかはまだ不安なのですが、とりあえず自分の環境ではapplication_system_test_case.rbに、こんな具合に書けばうまくいきました。

test/application_system_test_case.rb
require "test_helper"

class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      args: %w(no-sandbox headless disable-gpu window-size=1280x800 disable-dev-shm-usage)
    }
  )

  driven_by :selenium, using: :chrome,
    options: { desired_capabilities: capabilities }
end

no-sandboxとDocker環境なのでdisable-dev-shm-usageというオプションが大事なのは分かってたんだけど、調べる先毎にオプションの書き方がバラバラで、かなり混乱しました💫

brakemanでinvalid byte sequence in US-ASCII While processingエラーが発生する

手元ではbrakemanのテスト通っているのに、CIだと落ちる。えー、と思って調べてみたら、どうやらDocker HubのRubyコンテナの文字コードがUS-ASCIIらしく、RUBYOPT=--encoding=UTF-8と環境変数に追加する必要がありました。

そして、ようやくテストが全部通る😭

毎セクションでコケて本当に大変だったorz んでもまあこういう経験で詳しくなっていく部分はありますよね。

GitLabですが、もともと違和感あった「プルリクエスト」という言葉が「マージリクエスト」だったり、テスト落ちたのをIssue作れたり、標準でIssueが管理しやすかったりと、こっちのほうが良くない?と思う部分がたくさんありました。

しばらくGitLabを使ってみようと思います。