Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/Rails31'
Browse files Browse the repository at this point in the history
  • Loading branch information
Wilson Bilkovich committed Sep 27, 2011
2 parents 2878845 + cbef1a2 commit e91b182
Show file tree
Hide file tree
Showing 7 changed files with 185 additions and 3 deletions.
2 changes: 2 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ Due to the nature of --development, that gem install command can take a VERY lon
If you get tired of waiting, you can manually install the indicated versions of
rake and rspec. Check the gemspec for current requirements.
At the time of this writing, rspec 1.3.0 was the last version known to work on 1.8.6.

Set the 'VERBOSE' environment variable to something to get full output from failing commands.
8 changes: 6 additions & 2 deletions lib/engineyard-serverside/deploy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
require 'base64'
require 'fileutils'
require 'json'
require 'engineyard-serverside/rails_asset_support'

module EY
module Serverside
class DeployBase < Task
include LoggedOutput
include ::EY::Serverside::RailsAssetSupport

# default task
def deploy
Expand All @@ -29,7 +31,10 @@ def cached_deploy
symlink_configs
conditionally_enable_maintenance_page
run_with_callbacks(:migrate)
run_with_callbacks(:compile_assets) # defined in RailsAssetSupport
callback(:before_symlink)
# We don't use run_with_callbacks for symlink because we need
# to clean up manually if it fails.
symlink
end

Expand Down Expand Up @@ -160,7 +165,7 @@ def bundle
end
end

run "cd #{c.release_path} && bundle _#{bundler_installer.version}_ install #{bundler_installer.options}"
run "cd #{c.release_path} && ruby -S bundle _#{bundler_installer.version}_ install #{bundler_installer.options}"

run "mkdir -p #{bundled_gems_path} && ruby -v > #{ruby_version_file} && uname -m > #{system_version_file}"
end
Expand Down Expand Up @@ -364,6 +369,5 @@ def self.new(config)
super
end
end

end
end
68 changes: 68 additions & 0 deletions lib/engineyard-serverside/rails_asset_support.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
module EY
module Serverside
module RailsAssetSupport
def compile_assets
roles :app_master, :app, :solo do
rails_app = "#{c.release_path}/config/application.rb"
asset_dir = "#{c.release_path}/app/assets"
if File.exists?(rails_app) && File.directory?(asset_dir)
return if app_disables_assets?(rails_app)
if app_builds_own_assets?
info "~> public/assets already exists, skipping pre-compilation."
return
end
keep_existing_assets
cmd = "cd #{c.release_path} && PATH=#{c.binstubs_path}:$PATH #{c.framework_envs} rake assets:precompile"
info "~> Precompiling assets for Rails: #{cmd}"
run(cmd)
end
end
end

def app_disables_assets?(path)
disabled = nil
File.open(path) do |fd|
pattern = /^[^#].*config\.assets\.enabled\s+=\s+(false|nil)/
contents = fd.read
disabled = contents.match(pattern)
end
disabled
end

def app_builds_own_assets?
File.directory?(File.join(c.release_path, 'public', 'assets'))
end

# To support operations like Unicorn's hot reload, it is useful to have
# the prior release's assets as well. Otherwise, while a deploy is running,
# clients may request stale assets that you just deleted.
# Making use of this requires a properly-configured front-end HTTP server.
def keep_existing_assets
current = File.join(c.shared_path, 'assets')
last_asset_path = File.join(c.shared_path, 'last_assets')
# If there are current shared assets, move them under a 'last_assets' directory.
run <<-COMMAND
if [ -d #{current} ]; then
rm -rf #{last_asset_path} && mkdir #{last_asset_path} && mv #{current} #{last_asset_path} && mkdir -p #{current};
else
mkdir -p #{current} #{last_asset_path};
fi;
ln -nfs #{current} #{last_asset_path} #{c.release_path}/public
COMMAND
end

def bundled_rails_version(lockfile_path)
lockfile = File.open(lockfile_path) {|f| f.read}
lockfile.each_line do |line|
# scan for gemname (version) toplevel deps.
# Likely doesn't handle ancient Bundler versions, but
# we only call this when something looks like it is Rails 3.
next unless line =~ /^\s{4}([-\w_.0-9]+)\s*\((.*)\)/
return $2 if $1 == 'rails'
end
nil
end
end
end
end

2 changes: 2 additions & 0 deletions spec/basic_deploy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
File.exist?(File.join(@deploy_dir, 'current', 'after_bundle.ran' )).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'before_migrate.ran')).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'after_migrate.ran' )).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'before_compile_assets.ran')).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'after_compile_assets.ran' )).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'before_symlink.ran')).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'after_symlink.ran' )).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'before_restart.ran')).should be_true
Expand Down
2 changes: 2 additions & 0 deletions spec/custom_deploy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ def create_revision_file() @call_order << 'create_revision_fil
def bundle() @call_order << 'bundle' end
def symlink_configs() @call_order << 'symlink_configs' end
def migrate() @call_order << 'migrate' end
def compile_assets() @call_order << 'compile_assets' end
def symlink() @call_order << 'symlink' end
def restart() @call_order << 'restart' end
def cleanup_old_releases() @call_order << 'cleanup_old_releases' end
Expand All @@ -41,6 +42,7 @@ def disable_maintenance_page() @call_order << 'disable_maintenance
symlink_configs
conditionally_enable_maintenance_page
migrate
compile_assets
symlink
restart
disable_maintenance_page
Expand Down
104 changes: 104 additions & 0 deletions spec/rails31_deploy_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
require 'spec_helper'

describe "Deploying a Rails 3.1 application" do
def deploy_test_application(assets_enabled = true)
return # pending!
$DISABLE_GEMFILE = false
$DISABLE_LOCKFILE = false
@deploy_dir = File.join(Dir.tmpdir, "serverside-deploy-#{Time.now.to_i}-#{$$}")

# set up EY::Serverside::Server like we're on a solo
EY::Serverside::Server.reset
EY::Serverside::Server.add(:hostname => 'localhost', :roles => %w[solo])

# run a deploy
@config = EY::Serverside::Deploy::Configuration.new({
"strategy" => "IntegrationSpec",
"deploy_to" => @deploy_dir,
"group" => `id -gn`.strip,
"stack" => 'nginx_passenger',
"migrate" => "ruby -e 'puts ENV[\"PATH\"]' > #{@deploy_dir}/path-when-migrating",
'app' => 'rails31',
'framework_env' => 'staging'
})

# pretend there is a shared bundled_gems directory
FileUtils.mkdir_p(File.join(@deploy_dir, 'shared', 'bundled_gems'))
%w(RUBY_VERSION SYSTEM_VERSION).each do |name|
File.open(File.join(@deploy_dir, 'shared', 'bundled_gems', name), "w") { |f| f.write("old\n") }
end

# Set up the application directory to have the requested asset options.
prepare_rails31_app(assets_enabled)

@binpath = File.expand_path(File.join(File.dirname(__FILE__), '..', 'bin', 'engineyard-serverside'))
@deployer = FullTestDeploy.new(@config)
yield if block_given?
@deployer.deploy
end

def prepare_rails31_app(assets_enabled)
FileUtils.mkdir_p(File.join(@config.release_path, 'config'))
app_rb = File.join(@config.release_path, 'config', 'application.rb')
app_rb_contents = <<-EOF
module Rails31
class Application < Rails::Application
config.assets.enabled = #{assets_enabled ? 'true' : 'false'}
end
end
EOF
File.open(app_rb, 'w') {|f| f.write(app_rb_contents)}
rakefile = File.join(@config.release_path, 'Rakefile')
rakefile_contents = <<-EOF
task 'assets:precompile' do
sh 'touch precompiled'
end
EOF
File.open(rakefile, 'w') {|f| f.write(rakefile_contents)}
FileUtils.mkdir_p(File.join(@config.release_path, 'app', 'assets'))

@deployer = FullTestDeploy.new(@config)
@deployer.deploy
end

context "with default production settings" do
before(:all) do
deploy_test_application
end

it "precompiles assets" do
pending "Bundler is a party"
File.exist?(File.join(@deploy_dir, 'current', 'precompiled')).should be_true
end
end

context "with asset support disabled in its config" do
before(:all) do
deploy_test_application(with_assets = false)
end

it "does not precompile assets" do
pending "Bundler is a party"
File.exist?(File.join(@deploy_dir, 'current', 'precompiled')).should be_false
end
end

context "with existing precompilation in a deploy hook" do
before(:all) do
deploy_test_application do
hook = File.join(@config.release_path, 'deploy', 'before_migrate')
hook_contents = %Q[system 'touch custom_compiled && mkdir public/assets']
File.open(hook, 'w') {|f| f.puts(hook_contents) }
File.chmod(0755, hook)
end
end

it "does not replace the public/assets directory" do
pending "Bundler is a party"
File.exist?(File.join(@deploy_dir, 'current', 'custom_compiled')).should be_true
File.exist?(File.join(@deploy_dir, 'current', 'precompiled')).should be_false
File.directory?(File.join(@deploy_dir, 'current', 'public', 'assets')).should be_true
File.symlink?(File.join(@deploy_dir, 'current', 'public', 'assets')).should be_false
end
end
end
2 changes: 1 addition & 1 deletion spec/support/integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def update_repository_cache

deploy_hook_dir = File.join(cached_copy, 'deploy')
FileUtils.mkdir_p(deploy_hook_dir)
%w[bundle migrate symlink restart].each do |action|
%w[bundle compile_assets migrate symlink restart].each do |action|
%w[before after].each do |prefix|
hook = "#{prefix}_#{action}"
File.open(File.join(deploy_hook_dir, "#{hook}.rb"), 'w') do |f|
Expand Down

0 comments on commit e91b182

Please sign in to comment.