Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ require "capistrano/rsync"

Set some `rsync_options` to your liking:
```ruby
set :rsync_options, %w[--recursive --delete --delete-excluded --exclude .git*]
set :rsync_options, %w[--recursive --delete --delete-excluded --exclude=.git*]
```

Ensure to set `scm` to :rsync in your deploy.rb:
```ruby
set :scm, :rsync
```

And after setting regular Capistrano options, deploy as usual!
Expand All @@ -60,16 +65,23 @@ After that, Capistrano takes over and runs its usual tasks and symlinking.

### Exclude files from being deployed
If you don't want to deploy everything you've committed to your repository, pass
some `--exclude` options to Rsync:
some `--exclude` options to Rsync (note the equals signs):
```ruby
set :rsync_options, %w[
--recursive --delete --delete-excluded
--exclude .git*
--exclude /config/database.yml
--exclude /test/***
--exclude=.git*
--exclude=/config/database.yml
--exclude=/test/***
--include=/etc/folder
--exclude=/etc/*
]
```

The `=` is required in order for patterns to be properly read. Note the order of the
`--include` and `--exclude` params; if you wish to exclude an entire directory except
a certain folder, because of an Rsync quirk you must specify the include first.


### Precompile assets before deploy
Capistrano::Rsync runs `rsync:stage` before rsyncing. Hook to that like this:
```ruby
Expand Down
80 changes: 48 additions & 32 deletions lib/capistrano/rsync.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,48 +5,56 @@
# private API and internals of Capistrano::Rsync. If you think something should
# be public for extending and hooking, please let me know!

set :rsync_options, []
set :rsync_copy, "rsync --archive --acls --xattrs"

# Stage is used on your local machine for rsyncing from.
set :rsync_stage, "tmp/deploy"

# Cache is used on the server to copy files to from to the release directory.
# Saves you rsyncing your whole app folder each time. If you nil rsync_cache,
# Capistrano::Rsync will sync straight to the release path.
set :rsync_cache, "shared/deploy"

rsync_cache = lambda do
cache = fetch(:rsync_cache)
cache = deploy_to + "/" + cache if cache && cache !~ /^\//
cache
end

# Use cap3's load:defaults to set default vars so that they can be overridden.
namespace :load do
task :defaults do
set :rsync_options, []
set :rsync_copy, "rsync --archive --acls --xattrs"

# Stage is used on your local machine for rsyncing from.
set :rsync_stage, "tmp/deploy"

# Cache is used on the server to copy files to from to the release directory.
# Saves you rsyncing your whole app folder each time. If you nil rsync_cache,
# Capistrano::Rsync will sync straight to the release path.
set :rsync_cache, "shared/deploy"
end
end

Rake::Task["deploy:check"].enhance ["rsync:hook_scm"]
Rake::Task["deploy:updating"].enhance ["rsync:hook_scm"]

desc "Stage and rsync to the server (or its cache)."
task :rsync => %w[rsync:stage] do
roles(:all).each do |role|
user = role.user + "@" if !role.user.nil?

rsync = %w[rsync]
rsync.concat fetch(:rsync_options)
rsync << fetch(:rsync_stage) + "/"
rsync << "#{user}#{role.hostname}:#{rsync_cache.call || release_path}"

Kernel.system *rsync
on roles(:all), in: :parallel do |host|
user = host.user + "@" if !host.user.nil?
port = host.port

run_locally do
rsynccmd = []
rsynccmd.concat(fetch(:rsync_options))
rsynccmd << fetch(:rsync_stage) + "/"
rsynccmd << "-e \'ssh -p #{port}\'" if port
rsynccmd << "#{user}#{host.hostname}:#{rsync_cache.call || release_path}"
execute :rsync, rsynccmd.join(" ")
end
end
end

namespace :rsync do
task :hook_scm do
Rake::Task.define_task("#{scm}:check") do
invoke "rsync:check"
invoke "rsync:check"
end

Rake::Task.define_task("#{scm}:create_release") do
invoke "rsync:release"
invoke "rsync:release"
end
end

Expand All @@ -57,20 +65,18 @@
task :create_stage do
next if File.directory?(fetch(:rsync_stage))

clone = %W[git clone]
clone << fetch(:repo_url, ".")
clone << fetch(:rsync_stage)
Kernel.system *clone
run_locally do
execute :git, "clone #{fetch(:repo_url, '.')} #{fetch(:rsync_stage)}";
end
end

desc "Stage the repository in a local directory."
task :stage => %w[create_stage] do
Dir.chdir fetch(:rsync_stage) do
update = %W[git fetch --quiet --all --prune]
Kernel.system *update

checkout = %W[git reset --hard origin/#{fetch(:branch)}]
Kernel.system *checkout
run_locally do
within fetch(:rsync_stage) do
execute :git, "fetch --quiet --all --prune"
execute :git, "reset --hard origin/#{fetch(:branch)}"
end
end
end

Expand All @@ -86,4 +92,14 @@
# Matches the naming scheme of git tasks.
# Plus was part of the public API in Capistrano::Rsync <= v0.2.1.
task :create_release => %w[release]

desc "Set the current revision"
task :set_current_revision do
run_locally do
within fetch(:rsync_stage) do
rev = capture(:git, 'rev-parse', '--short', 'HEAD')
set :current_revision, rev
end
end
end
end