はじめに
本来あってはならないのですが、syntaxエラーが含まれるRailsアプリをUnicornのGraceful Restartを使ってデプロイすると、アプリケーションは一見動き続けるのですが変更は反映されません。
一見デプロイそのものはエラーが出ないので成功した様に見えるのですが、ここでUnicornに通常の再起動かけたりすると当然のことながら起動すらしなくなります。
よってここでは、デプロイがちゃんと反映されているかCIで確認できるよう、cap deploy中にデプロイが反映されているか自動で確認する方法を示します。
仕組み
CapistranoではアプリケーションのトップディレクトリにREVISIONというファイルでデプロイしたコミットのsha1が出力されます。これをアプリケーションから返すようにし、デプロイしたコミットのsha1と比較することで、反映されているか確認します。
実装
1. 外部からsha1を読み出せるエンドポイントを追加
app/controllers/misc_controller.rb
def revision(token: nil)
raise ActiveRecord::RecordNotFound if token != 'password'
render text: (File.read(Rails.root.join('REVISION')) rescue 'FILE NOT EXIST')
end
config/routes.rb
get 'revision' => 'misc#revision'
2. デプロイ時、デプロイしたコミットのsha1が返されるか確認
config/deploy.rb
namespace :deploy do
task :verify do
require 'uri'
require 'net/http'
endpoint = 'http://example.com'
key = 'password'
reflect_revision = Net::HTTP.post_form(URI.parse(endpoint + '/revision'), 'token' => key).body.chomp
if reflect_revision != fetch(:current_revision)
fail "don't reflect revision. #{reflect_revision} (web) != #{fetch(:current_revision)} (deploy)"
else
puts "reflect #{reflect_revision} ok."
end
end
end
after 'deploy:finished', 'deploy:verify'
3. 動作確認
デプロイが反映されていないとCIが落ちます。