mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
basic deployment - done
This commit is contained in:
parent
454f46b829
commit
49a075427d
17 changed files with 452 additions and 117 deletions
1
lib/capistrano/bundler.rb
Normal file
1
lib/capistrano/bundler.rb
Normal file
|
@ -0,0 +1 @@
|
|||
import File.expand_path("../tasks/bundler.rake", __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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
44
lib/capistrano/dsl/env.rb
Normal 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
|
||||
|
13
lib/capistrano/dsl/logger.rb
Normal file
13
lib/capistrano/dsl/logger.rb
Normal 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
|
41
lib/capistrano/dsl/paths.rb
Normal file
41
lib/capistrano/dsl/paths.rb
Normal 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
|
15
lib/capistrano/dsl/stages.rb
Normal file
15
lib/capistrano/dsl/stages.rb
Normal 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
|
15
lib/capistrano/dsl/task_enhancements.rb
Normal file
15
lib/capistrano/dsl/task_enhancements.rb
Normal 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
1
lib/capistrano/git.rb
Normal file
|
@ -0,0 +1 @@
|
|||
import File.expand_path("../tasks/git.rake", __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
|
||||
|
|
12
lib/capistrano/tasks/bundler.rake
Normal file
12
lib/capistrano/tasks/bundler.rake
Normal 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
|
|
@ -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
|
||||
|
|
45
lib/capistrano/tasks/framework.rake
Normal file
45
lib/capistrano/tasks/framework.rake
Normal 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
|
37
lib/capistrano/tasks/git.rake
Normal file
37
lib/capistrano/tasks/git.rake
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue