1
0
Fork 0
mirror of https://github.com/capistrano/capistrano synced 2023-03-27 23:21:18 -04:00

basic deployment - done

This commit is contained in:
seenmyfate 2013-03-12 21:22:49 +00:00
parent 454f46b829
commit 49a075427d
17 changed files with 452 additions and 117 deletions

View file

@ -0,0 +1 @@
import File.expand_path("../tasks/bundler.rake", __FILE__)

View file

@ -78,7 +78,7 @@ module Capistrano
private
def fetch(name)
roles.fetch(name) { "role #{name} is not defined" }
roles.fetch(name) { raise "role #{name} is not defined" }
end
def roles

View file

@ -1,2 +1,4 @@
import File.expand_path("../tasks/framework.rake", __FILE__)
import File.expand_path("../tasks/deploy.rake", __FILE__)
import File.expand_path("../tasks/git.rake", __FILE__)
require 'capistrano/install'

View file

@ -1,17 +1,16 @@
require 'capistrano/dsl/task_enhancements'
require 'capistrano/dsl/paths'
require 'capistrano/dsl/logger'
require 'capistrano/dsl/stages'
require 'capistrano/dsl/env'
module Capistrano
module DSL
def before(task, prerequisite, *args, &block)
prerequisite = Rake::Task.define_task(prerequisite, *args, &block) if block_given?
Rake::Task[task].enhance [prerequisite]
end
def after(task, post_task, *args, &block)
post_task = Rake::Task.define_task(post_task, *args, &block) if block_given?
Rake::Task[task].enhance do
invoke(post_task)
end
end
include TaskEnhancements
include Env
include Paths
include Logger
include Stages
def invoke(task)
Rake::Task[task].invoke
@ -21,88 +20,20 @@ module Capistrano
I18n.t(*args, scope: :capistrano)
end
def stages
Dir['config/deploy/*.rb'].map { |f| File.basename(f, '.rb') }
end
def stage_set?
!!fetch(:stage, false)
end
def configure_ssh_kit
env.configure_backend
end
def fetch(key, default=nil)
env.fetch(key, default)
end
def set(key, value)
env.set(key, value)
end
def role(name, servers)
env.role(name, servers)
end
def roles(*names)
env.roles_for(names)
end
def all
env.all_roles
end
def env
Configuration.env
end
def deploy_path
"#{fetch(:deploy_to)}"
end
def current_path
"#{deploy_path}/current"
end
def releases_path
"#{deploy_path}/releases"
end
def release_path
"#{releases_path}/#{timestamp}"
end
def release_timestamp
env.timestamp.strftime("%Y%m%d%H%M%S")
end
def asset_timestamp
env.timestamp.strftime("%Y%m%d%H%M.%S")
end
def repo_path
"#{deploy_path}/repo"
end
def shared_path
"#{deploy_path}/shared"
end
def revision_log
"#{deploy_path}/revisions.log"
end
def deploy_user
fetch(:user)
fetch(:deploy_user)
end
def info(message)
puts message
def scm
fetch(:scm)
end
def error(message)
puts message
def maintenance_page
fetch(:maintenance_page, 'public/system/maintenance.html')
end
def revision_log_message
%{Branch #{fetch(:branch)} deployed as release #{release_timestamp} by #{`whoami`}}
end
end
end

44
lib/capistrano/dsl/env.rb Normal file
View file

@ -0,0 +1,44 @@
module Capistrano
module DSL
module Env
def configure_backend
env.configure_backend
end
def fetch(key, default=nil)
env.fetch(key, default)
end
def set(key, value)
env.set(key, value)
end
def role(name, servers)
env.role(name, servers)
end
def roles(*names)
env.roles_for(names)
end
def all
env.all_roles
end
def env
Configuration.env
end
def release_timestamp
env.timestamp.strftime("%Y%m%d%H%M%S")
end
def asset_timestamp
env.timestamp.strftime("%Y%m%d%H%M.%S")
end
end
end
end

View file

@ -0,0 +1,13 @@
module Capistrano
module DSL
module Logger
def info(message)
puts message
end
def error(message)
puts message
end
end
end
end

View file

@ -0,0 +1,41 @@
module Capistrano
module DSL
module Paths
def deploy_path
fetch(:deploy_to)
end
def current_path
File.join(deploy_path, 'current')
end
def releases_path
File.join(deploy_path, 'releases')
end
def release_path
File.join(releases_path, release_timestamp)
end
def repo_path
File.join(deploy_path, 'repo')
end
def shared_path
File.join(deploy_path, 'shared')
end
def revision_log
File.join(deploy_path, 'revisions.log')
end
def release_timestamp
env.timestamp.strftime("%Y%m%d%H%M%S")
end
def asset_timestamp
env.timestamp.strftime("%Y%m%d%H%M.%S")
end
end
end
end

View file

@ -0,0 +1,15 @@
module Capistrano
module DSL
module Stages
def stages
Dir['config/deploy/*.rb'].map { |f| File.basename(f, '.rb') }
end
def stage_set?
!!fetch(:stage, false)
end
end
end
end

View file

@ -0,0 +1,15 @@
module Capistrano
module TaskEnhancements
def before(task, prerequisite, *args, &block)
prerequisite = Rake::Task.define_task(prerequisite, *args, &block) if block_given?
Rake::Task[task].enhance [prerequisite]
end
def after(task, post_task, *args, &block)
post_task = Rake::Task.define_task(post_task, *args, &block) if block_given?
Rake::Task[task].enhance do
invoke(post_task)
end
end
end
end

1
lib/capistrano/git.rb Normal file
View file

@ -0,0 +1 @@
import File.expand_path("../tasks/git.rake", __FILE__)

View file

@ -5,6 +5,6 @@ stages.each do |stage|
load "config/deploy.rb"
load "config/deploy/#{stage}.rb"
set(:stage, stage.to_sym)
configure_ssh_kit
configure_backend
end
end

View file

@ -0,0 +1,12 @@
namespace :deploy do
after :update, :bundle do
on all do
as deploy_user do
within release_path do
execute :bundle, "--gemfile #{release_path}/Gemfile --deployment --binstubs #{shared_path}/bin --path #{shared_path}/bundle --without development test cucumber"
end
end
end
end
end

View file

@ -1,45 +1,193 @@
namespace :deploy do
desc "starting"
task :starting do
end
desc "started"
task :started do
invoke 'deploy:check:user'
invoke 'deploy:check:permissions'
invoke 'deploy:ensure:directories'
invoke "#{scm}:prepare"
end
desc "update"
task :update do
invoke "#{scm}:update"
invoke 'deploy:symlink:shared'
end
desc "finalize"
task :finalize do
invoke 'deploy:symlink:release'
invoke 'deploy:normalise_assets'
end
desc "restart"
task :restart do
end
after :restart, 'deploy:web:ensure'
desc "finishing"
task :finishing do
invoke 'deploy:cleanup'
end
desc "finished"
task :finished do
invoke 'deploy:log_revision'
end
before :starting, :ensure_stage do
unless stage_set?
puts t(:stage_not_set)
exit 1
namespace :check do
task :user do
on all do
unless test("getent passwd \"#{deploy_user}\" > /dev/null")
error t('error.user.does_not_exist', user: deploy_user)
end
end
end
task :permissions do
on all do
unless test("sudo su #{deploy_user} -c whoami > /dev/null")
error t('error.user.cannot_switch', user: deploy_user)
end
end
end
end
namespace :ensure do
task :directories do
on all do
unless test "[ -d #{shared_path} ]"
as deploy_user do
execute :mkdir, '-p', shared_path
end
end
unless test "[ -d #{releases_path} ]"
as deploy_user do
execute :mkdir, '-p', releases_path
end
end
end
end
end
namespace :symlink do
task :release do
on all do
as deploy_user do
execute :rm, '-rf', current_path
execute :ln, '-s', release_path, current_path
end
end
end
task :shared do
# configuration exists
on all do
as deploy_user do
fetch(:linked_files).each do |file|
unless test "[ -f #{shared_path}/#{file} ]"
# create config file
end
end
end
end
# configuration is symlinked
on all do
as deploy_user do
fetch(:linked_files).each do |file|
target = File.join(release_path, file)
source = File.join(shared_path, file)
unless test "[ -L #{target} ]"
if test "[ -f #{target} ]"
execute :rm, target
end
execute :ln, '-s', source, target
end
end
end
end
# tmp/log/public folders exist in shared
on all do
as deploy_user do
fetch(:linked_dirs).each do |dir|
dir = File.join(shared_path, dir)
unless test "[ -d #{dir} ]"
execute :mkdir, '-p', dir
end
end
end
end
# tmp/log/public folders are symlinked
on all do
as deploy_user do
fetch(:linked_dirs).each do |dir|
target = File.join(release_path, dir)
source = File.join(shared_path, dir)
unless test "[ -L #{target} ]"
if test "[ -f #{target} ]"
execute :rm, '-rf', target
end
execute :ln, '-s', source, target
end
end
end
end
end
end
namespace :web do
task :ensure do
on roles(:web) do
as deploy_user do
within shared_path do
file = File.join(shared_path, maintenance_page)
if test "[ -f #{shared_path}/#{file} ]"
execute :rm, file
end
end
end
end
end
end
task :disable do
on all do
as deploy_user do
within shared_path do
execute :touch, maintenance_page
end
end
end
end
task :normalise_assets do
on roles(:web) do
as deploy_user do
within release_path do
assets = %{public/images public/javascripts public/stylesheets}
execute :find, "#{assets} -exec touch -t #{asset_timestamp} {} ';'; true"
end
end
end
end
task :cleanup do
on all do
as deploy_user do
count = fetch(:keep_releases, 5).to_i
releases = capture("ls -xt #{releases_path}").split.reverse
if releases.length >= count
info "keeping #{count} of #{releases.length} deployed releases"
directories = (releases - releases.last(count)).map { |release|
File.join(releases_path, release) }.join(" ")
execute :rm, '-rf', directories
end
end
end
end
task :log_revision do
on roles(:web) do
as deploy_user do
within releases_path do
execute %{echo "#{revision_log_message}" >> #{revision_log}}
end
end
end
end
end
desc "Deploy"
task :deploy do
%w{starting started update finalize restart finishing finished}.each do |stage|
invoke "deploy:#{stage}"
end
end
task default: :deploy

View file

@ -0,0 +1,45 @@
namespace :deploy do
desc 'Starting'
task :starting do
end
desc 'Started'
task :started do
end
desc 'Update'
task :update do
end
desc 'Finalize'
task :finalize do
end
desc 'Restart'
task :restart do
end
desc 'Finishing'
task :finishing do
end
desc 'Finished'
task :finished do
end
before :starting, :ensure_stage do
unless stage_set?
puts t(:stage_not_set)
exit 1
end
end
end
desc 'Deploy'
task :deploy do
%w{starting started update finalize restart finishing finished}.each do |task|
invoke "deploy:#{task}"
end
end
task default: :deploy

View file

@ -0,0 +1,37 @@
namespace :git do
task :prepare do
on all do
unless test "[ -d #{repo_path} ]"
within deploy_path do
as deploy_user do
execute :git, :clone, fetch(:repo), repo_path
end
end
end
end
end
task :update do
invoke 'git:reset_to_ref'
invoke 'git:create_release'
end
task :reset_to_ref do
on all do
as deploy_user do
within repo_path do
execute :git, 'fetch origin'
execute :git, "reset --hard origin/#{fetch(:branch)}"
end
end
end
end
task :create_release do
on all do
as deploy_user do
execute :cp, "-RPp", repo_path, release_path
end
end
end
end

View file

@ -9,9 +9,28 @@ require 'capistrano/console'
# remove to start from scratch
require 'capistrano/deploy'
# require tasks from contrib gems
require 'capistrano/bundler'
# require 'capistrano/rails'
# require 'capistrano/heroku'
# Loads any rake tasks from lib/deploy/tasks
Dir.glob('lib/deploy/tasks/*.rake').each { |r| import r }
desc "Restart"
task :restart do
on role(:app) do
as deploy_user do
# restart
end
end
end
after :restart, :clear_cache do
on role(:app) do
as deploy_user do
# clear cache
end
end
end

View file

@ -1,5 +1,16 @@
set :application, 'my app name'
set :deploy_to, '/var/www/my_app'
set :scm, :git
set :repo, 'git@example.com:me/my_repo.git'
set :migrations, :migrate
set :branch, :master
set :linked_files, %w{config/database.yml}
set :linked_dirs, %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}
set :format, :pretty # :dot
set :log_level, :debug # :info
set :pty, true