JenkinsでRailsアプリをテストする。

環境

Jenkinsのインストール

さくらのVPSにDebian squeezeをインストールする方法はこちら

$ wget -q -O - http://pkg.jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
$ sudo vi /etc/apt/sources.list
deb http://pkg.jenkins-ci.org/debian binary
$ sudo apt-get update
$ sudo apt-get install jenkins

jenkinsユーザーが作成されて8080にjenkinsが立ち上がる。

nginxでのReverse proxyの設定

example.com:8080では味気無いのでci.example.comでアクセス出来るようにする。

$ sudo apt-get install nginx
$ sudo vi /etc/nginx/sites-available/ci.example.com
server {
  listen 80;
  server_name ci.example.com;
  location / { proxy_pass http://localhost:8080; }
}
$ ln -s /etc/nginx/sites-available/ci.example.com /etc/nginx/sites-enable/ci.example.com

rvmのインストール

rvmをsystem wideにインストールするのは大変なので単にjenkinsユーザーにインストールする。

$ sudo su - jenkins
$ bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )

大体nokogiriを使う段になって困るので下記をちゃんとインストールしておく。

$ rvm package install readline openssl zlib
$ rvm install 1.8.7 -C --with-openssl-dir=$HOME/.rvm/usr --with-readline-dir=$HOME/.rvm/usr --with-zlib-dir=$HOME/.rvm/usr

アプリ名でgemsetを作っておき、bundlerをインストールしておく。(jenkinsのタスクでやっても構わないと思う)

$ rvm use ruby-1.8.7-p334
$ rvm gemset create rails-example-app
$ rvm use ruby-1.8.7-p334@rails-example-app
$ gem install bundler

ユーザー認証

LAN内でない場合はユーザー認証をかける。"Manage Jenkins"の"Access Control"で"Secure Realm"を"Jenkins's own user database"にして"Allow users to sign up"にチェックを入れる。"Authorization"は"Matrix-based security"を選び、管理者ユーザーとなる予定のユーザー名を追加しておく。少し分かりづらいがここで設定した後、同じ名前でsign upをすれば良い。(間違って管理画面にはいれなくなってしまった場合はここを参考にしてリセットする。)

Configure System [Jenkins]

gitプラグインのインストール

大体が社内のgitやgithubから持ってくることになるのでgitプラグインをインストールする。"Manage Jenkins" > "Plugin Manager" > "Available"から"Git Plugin"を選択してインストールする。"Github Plugin"もついでに入れておくと良いかもしれない。

ビルドの設定

"Source Code Management"から"Git"を選択し、"Repositories" > "URL of repository"にリポジトリのURLを入れる。(githubのプライベートリポジトリを使っている場合はjenkinsユーザーで鍵を作り、githubの"Admin" > "Deploy Keys"から登録しておけばいい。)ビルドトリガーは好きに設定する。右側の"?"に親切な説明があるので迷わないだろう。ビルドはrailsなので"Execute shell"を選択する。rvmにはrvm-shellという指定の環境でshellを実行するうってつけのコマンドがあるのでそれをshebangに設定すればいい。

u2plus Config [Jenkins]

"Post-build Actions"で"E-mail Notification"を設定しておく。Debianデフォルトのexim4はメールが飛ぶようになってないのでいっそのことpostfixを入れた方が楽。

$ sudo apt-get install postfix

関連:Debian Squeeze install to Sakura VPS - komagata

CUIコマンドのend to endテストとはこんな感じだろうか?

spec/css_selector_command_spec.rb at master from komagata/css_selector - GitHub

# spec/css_selector_command_spec.rb:
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')

describe "css_selector" do
  it "get title" do
    result = `echo '<html><head><title>foo</title></head><body><h1>bar</h1></body></html>' | bin/css_selector title`
    result.should == "foo\n"
  end

  it "get h1" do
    result = `echo '<html><head><title>foo</title></head><body><h1>bar</h1></body></html>' | bin/css_selector h1`
    result.should == "bar\n"
  end
end

どっかに参考になるプロジェクトがないかしら。

TerminalでちょこっとWeb上のテキストが欲しい時が結構あるのでcss_selector.gemというのを作りました。

標準入力からCSS Selectorで指定した物の結果を改行繋ぎで出すだけのコマンドです。

MiniMagickを使ってRMagickと決別する。

MiniMagickはImageMagickのRuby bindingじゃなくて、ImageMagickのCommand Line InterfaceのWrapper。Paperclipのアプローチに関心してたけど本来はこういうのをPaperclipが使うべきですね。

関連:RailsからImageMagick(convert)に自由にオプションを渡せると聞いて飛んできました - komagata

Railsでguardを使う。(rspec)

# Gemfile:
group :test do
  gem 'rspec-rails'
  gem 'guard-rspec'

  # for Mac
  gem 'rb-fsevent'
  gem 'growl'
end
$ guard init rspec
$ guard start

deviseでログイン後のURLを設定する方法。

deviseではログイン後にはデフォルトでroot_pathに移動するようになってる。それを変えたい。

devise / lib / devise / controllers / helpers.rb

def after_sign_in_path_for(resource_or_scope)
  scope = Devise::Mapping.find_scope!(resource_or_scope)
  home_path = "#{scope}_root_path"
  respond_to?(home_path, true) ? send(home_path) : root_path
end

上記の様にresource(普通はUser)のroot_pathが設定されてればそっちに行くようになってるので下記の様にuser_root_pathに何かを設定すればいい。

# config/routes.rb:
Foo::Application.routes.draw do
  match '/snippets' => 'snippets#index', :as => :user_root
end

ログイン後に/snippetsに行くようになった。

% gem install haml2slim
% ls app/views/emotions 
_form.html.haml edit.html.haml  index.html.haml new.html.haml   show.html.haml
% haml2slim app/views/emotions 
% ls app/views/emotions 
_form.html.haml _form.html.slim edit.html.haml  edit.html.slim  index.html.haml index.html.slim new.html.haml   new.html.slim   show.html.haml  show.html.slim
# app/views/emotions/show.html.slim: 
p#notice= notice
p
  b Body:
  = @emotion.body
p
  b Kind:
  = @emotion.kind
= link_to 'Edit', edit_emotion_path(@emotion)
= link_to 'Back', emotions_path

OMG!

Gmailのロックを外す方法。

Gmailでは短期間に何度もログインしたりするとアカウントにロックがかかるらしい。下記の方法でロックを解除できる。

クライアントでユーザー名とパスワードが受け入れられません - Gmail ヘルプ

[PASSWORD]:535-5.7.1 Username and Password not accepted. Learn more at
[PASSWORD]:535 5.7.1 http://mail.google.com/support/bin/answer.py?answer=14257

MUAのログには上記のように出るが、Railsのエラーでは1行目しか出ないのでロックがかかっていることに気付くのが難しい・・・。

RailsでGmailを使ってメールを送る。(Google Appsも可)

# config/environments/development.rb:
(...)
  config.action_mailer.smtp_settings = {
    :address              => 'smtp.gmail.com',
    :port                 => 587,
    :domain               => 'example.com',
    :user_name            => 'foo@example.com',
    :password             => 'password',
    :authentication       => 'plain',
    :enable_starttls_auto => true
  }
(...)

下記を設定しないとエラーを表示してくれないところに注意する。

config.action_mailer.raise_delivery_errors = true

Send email with Rails by using Gmail. (Google Apps too)

If the following are not set, the error is not displayed.

Generators Slim - Issues - plataformatec/devise - GitHub

I'm exec this generate for slim, but the code created is erb...

$ rails g devise:views usuarios -e slim
  create  app/views/usuarios
  create  app/views/usuarios/confirmations/new.html.erb
  create  app/views/usuarios/mailer/confirmation_instructions.html.erb
  create  app/views/usuarios/mailer/reset_password_instructions.html.erb
  create  app/views/usuarios/mailer/unlock_instructions.html.erb
  create  app/views/usuarios/passwords/edit.html.erb
  create  app/views/usuarios/passwords/new.html.erb
  create  app/views/usuarios/registrations/edit.html.erb
  create  app/views/usuarios/registrations/new.html.erb
  create  app/views/usuarios/sessions/new.html.erb
  create  app/views/usuarios/shared/_links.erb
  create  app/views/usuarios/unlocks/new.html.erb

josevalim February 11, 2011 | link

You need devise master to do that.

READMEに書いてあるけど、deviseでhaml or slim(-eオプション)使いたかったら1.1.7じゃ駄目でmaster使えとのこと。1.2rcが正式になったら使えるようになるかも。