mirror of
https://github.com/capistrano/capistrano
synced 2023-03-27 23:21:18 -04:00
Merge remote-tracking branch 'upstream/master' into scm_subtree
Conflicts: CHANGELOG.md
This commit is contained in:
commit
08d4d90ac6
22 changed files with 111 additions and 60 deletions
|
@ -5,6 +5,7 @@ rvm:
|
|||
- 1.9.3
|
||||
- rbx-2
|
||||
script: bundle exec rake spec
|
||||
install: bundle install --jobs=1
|
||||
cache: bundler
|
||||
branches:
|
||||
except:
|
||||
|
|
20
CHANGELOG.md
20
CHANGELOG.md
|
@ -14,6 +14,21 @@ https://github.com/capistrano/capistrano/compare/v3.2.1...HEAD
|
|||
If not defined then the behaviour is as previously and the whole repository is
|
||||
extracted (subject to git-archive `.gitattributes` of course).
|
||||
|
||||
* Enhancement (@townsen): Remove unnecessary entries from default backtrace
|
||||
|
||||
When the `--backtrace` (or `--trace`) command line option is not supplied
|
||||
Rake lowers the noise level in exception backtraces by building
|
||||
a regular expression containing all the system library paths and
|
||||
using it to exclude backtrace entries that match.
|
||||
|
||||
This does not always go far enough, particularly in RVM environments when
|
||||
many gem paths are added. This commit reverses that approach and _only_
|
||||
include backtrace entries that fall within the Capfile and list of tasks
|
||||
imported thereafter. This makes reading exceptions much easier on the eye.
|
||||
|
||||
If the full unexpurgated backtrace is required then the --backtrace
|
||||
and --trace options supply it as before.
|
||||
|
||||
* Disable loading stages configs on `cap -T`
|
||||
|
||||
* Enhancements (@townsen)
|
||||
|
@ -40,7 +55,6 @@ https://github.com/capistrano/capistrano/compare/v3.2.1...HEAD
|
|||
|
||||
* See the documentation in the README.md file
|
||||
|
||||
* Pushing again to trigger another build (I have a seemingly random build fail) (@townsen)
|
||||
* Enhancements (@townsen)
|
||||
* Added set_if_empty method to DSL to allow conditional setting
|
||||
* Altered standard Capistrano defaults so that they are not set
|
||||
|
@ -64,11 +78,14 @@ Breaking Changes:
|
|||
* Remove -v flag from mkdir call. (@caligo-mentis)
|
||||
* Capistrano now allows to customize `local_user` for revision log. (@sauliusgrigaitis)
|
||||
* Added tests for after/before hooks features (@juanibiapina, @miry)
|
||||
* Added `--force` flag to `svn export` command to fix errors when the release directory already exists.
|
||||
* Improved the output of `cap --help`. (@mbrictson)
|
||||
* Cucumber suite now runs on the latest version of Vagrant (@tpett)
|
||||
* The `ask` method now supports the `echo: false` option. (@mbrictson, @kaikuchn)
|
||||
* Cucumber scenario improvements (@bruno-)
|
||||
* Added suggestion to Capfile to use 'capistrano-passenger' gem, replacing suggestion in config/deploy.rb to re-implement 'deploy:restart' (@betesh)
|
||||
* Updated svn fetch_revision method to use `svnversion`
|
||||
* `cap install` no longer overwrites existing files. (@dmarkow)
|
||||
|
||||
## `3.2.1`
|
||||
|
||||
|
@ -85,6 +102,7 @@ https://github.com/capistrano/capistrano/compare/v3.2.0...v3.2.1
|
|||
* Changed asking question to more standard format (like common unix commandline tools) (@sponomarev)
|
||||
* Fixed typos in the README. (@sponomarev)
|
||||
* Added `keys` method to Configuration to allow introspection of configuration options. (@juanibiapina)
|
||||
* Improve error message when git:check fails (raise instead of silently `exit 1`) (@mbrictson)
|
||||
|
||||
## `3.2.0`
|
||||
|
||||
|
|
4
Gemfile
4
Gemfile
|
@ -7,7 +7,3 @@ group :cucumber do
|
|||
gem 'cucumber'
|
||||
gem 'rspec', '~> 3.0.0'
|
||||
end
|
||||
|
||||
platforms :rbx do
|
||||
gem 'rubysl', '~> 2.0'
|
||||
end
|
||||
|
|
11
README.md
11
README.md
|
@ -229,6 +229,13 @@ DEBUG [9ce34809] leehambley pts/0 2013-06-13 17:11 (port-11262.pppoe.wtn
|
|||
INFO [9ce34809] Finished in 0.420 seconds command successful.
|
||||
```
|
||||
|
||||
## VCS Requirements
|
||||
|
||||
Capistano requires modern versions of Git, Mercurial and Subversion
|
||||
respectively (if you are using that particular VCS). Git Git requirement is at
|
||||
least version 1.8.x. Mercurial and Subversion, any modern version should
|
||||
suffice.
|
||||
|
||||
## A word about PTYs
|
||||
|
||||
There is a configuration option which asks the backend driver to ask the remote host
|
||||
|
@ -278,7 +285,7 @@ associated with them. Tasks are then able to use these definitions in two disti
|
|||
|
||||
* To _interact_ with remote hosts using the `on()` method
|
||||
|
||||
An example of the two would be to create a `/etc/krb5.conf' file containing the list of
|
||||
An example of the two would be to create a `/etc/krb5.conf` file containing the list of
|
||||
available KDC's by using the list of servers returned by `roles(:kdc)` and then uploading
|
||||
it to all client machines using `on(roles(:all)) do upload!(file) end`
|
||||
|
||||
|
@ -313,7 +320,7 @@ To increase the utility of On-Filters they can use regular expressions:
|
|||
|
||||
When filters are specified using comma separated lists, the final filter is the _union_ of
|
||||
all of the components. However when multiple filters are declared the result is the
|
||||
_intersection_.
|
||||
_intersection_.
|
||||
|
||||
## SSHKit
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ Feature: Deploy
|
|||
|
||||
Scenario: Creating the repo
|
||||
When I run cap "git:check"
|
||||
Then references in the remote repo are listed
|
||||
Then the task is successful
|
||||
And references in the remote repo are listed
|
||||
|
||||
Scenario: Creating the directory structure
|
||||
When I run cap "deploy:check:directories"
|
||||
|
@ -22,16 +23,16 @@ Feature: Deploy
|
|||
Then directories referenced in :linked_files are created in shared
|
||||
|
||||
Scenario: Checking linked files - missing file
|
||||
Given a required file
|
||||
But the file does not exist
|
||||
Given a linked file "missing_file.txt"
|
||||
But file "missing_file.txt" does not exist in shared path
|
||||
When I run cap "deploy:check:linked_files"
|
||||
Then the task will exit
|
||||
Then the task fails
|
||||
|
||||
Scenario: Checking linked files - file exists
|
||||
Given a required file
|
||||
And that file exists
|
||||
Given a linked file "existing_file.txt"
|
||||
And file "existing_file.txt" exists in shared path
|
||||
When I run cap "deploy:check:linked_files"
|
||||
Then the task will be successful
|
||||
Then the task is successful
|
||||
|
||||
Scenario: Creating a release
|
||||
Given I run cap "deploy:check:directories"
|
||||
|
@ -40,7 +41,7 @@ Feature: Deploy
|
|||
And the release is created
|
||||
|
||||
Scenario: Symlink linked files
|
||||
When I run cap "deploy:symlink:linked_files" as part of a release
|
||||
When I run cap "deploy:symlink:linked_files deploy:symlink:release" as part of a release
|
||||
Then file symlinks are created in the new release
|
||||
|
||||
Scenario: Symlink linked dirs
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Then(/^references in the remote repo are listed$/) do
|
||||
expect(@output).to include('refs/heads/master')
|
||||
end
|
||||
|
||||
Then(/^the shared path is created$/) do
|
||||
|
@ -22,13 +23,6 @@ Then(/^directories referenced in :linked_files are created in shared$/) do
|
|||
end
|
||||
end
|
||||
|
||||
Then(/^the task will be successful$/) do
|
||||
end
|
||||
|
||||
|
||||
Then(/^the task will exit$/) do
|
||||
end
|
||||
|
||||
Then(/^the repo is cloned$/) do
|
||||
run_vagrant_command(test_dir_exists(TestApp.repo_path))
|
||||
end
|
||||
|
@ -38,9 +32,8 @@ Then(/^the release is created$/) do
|
|||
end
|
||||
|
||||
Then(/^file symlinks are created in the new release$/) do
|
||||
pending
|
||||
TestApp.linked_files.each do |file|
|
||||
run_vagrant_command(test_symlink_exists(TestApp.release_path.join(file)))
|
||||
run_vagrant_command(test_symlink_exists(TestApp.current_path.join(file)))
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -93,6 +86,10 @@ Then(/^the task is successful$/) do
|
|||
expect(@success).to be true
|
||||
end
|
||||
|
||||
Then(/^the task fails$/) do
|
||||
expect(@success).to be_false
|
||||
end
|
||||
|
||||
Then(/^the failure task will run$/) do
|
||||
failed = TestApp.shared_path.join('failed')
|
||||
run_vagrant_command(test_file_exists(failed))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
When(/^I run cap "(.*?)"$/) do |task|
|
||||
@success = TestApp.cap(task)
|
||||
@success, @output = TestApp.cap(task)
|
||||
end
|
||||
|
||||
When(/^I run cap "(.*?)" as part of a release$/) do |task|
|
||||
|
|
|
@ -6,17 +6,21 @@ Given(/^servers with the roles app and web$/) do
|
|||
vagrant_cli_command('up') rescue nil
|
||||
end
|
||||
|
||||
Given(/^a required file$/) do
|
||||
Given(/^a linked file "(.*?)"$/) do |file|
|
||||
# ignoring other linked files
|
||||
TestApp.append_to_deploy_file("set :linked_files, ['#{file}']")
|
||||
end
|
||||
|
||||
Given(/^that file exists$/) do
|
||||
run_vagrant_command("touch #{TestApp.linked_file}")
|
||||
Given(/^file "(.*?)" exists in shared path$/) do |file|
|
||||
file_shared_path = TestApp.shared_path.join(file)
|
||||
run_vagrant_command("mkdir -p #{TestApp.shared_path}")
|
||||
run_vagrant_command("touch #{file_shared_path}")
|
||||
end
|
||||
|
||||
Given(/^the file does not exist$/) do
|
||||
pending
|
||||
file = TestApp.linked_file
|
||||
run_vagrant_command("[ -f #{file} ] && rm #{file}")
|
||||
Given(/^file "(.*?)" does not exist in shared path$/) do |file|
|
||||
file_shared_path = TestApp.shared_path.join(file)
|
||||
run_vagrant_command("mkdir -p #{TestApp.shared_path}")
|
||||
run_vagrant_command("touch #{file_shared_path} && rm #{file_shared_path}")
|
||||
end
|
||||
|
||||
Given(/^a custom task to generate a file$/) do
|
||||
|
|
|
@ -61,6 +61,18 @@ module Capistrano
|
|||
end
|
||||
end
|
||||
|
||||
def display_error_message(ex)
|
||||
unless options.backtrace
|
||||
if loc = Rake.application.find_rakefile_location
|
||||
whitelist = (@imported.dup << loc[0]).map{|f| File.absolute_path(f, loc[1])}
|
||||
pattern = %r@^(?!#{whitelist.map{|p| Regexp.quote(p)}.join('|')})@
|
||||
Rake.application.options.suppress_backtrace_pattern = pattern
|
||||
end
|
||||
trace "(Backtrace restricted to imported tasks)"
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def exit_because_of_exception(ex)
|
||||
if respond_to?(:deploying?) && deploying?
|
||||
exit_deploy_because_of_exception(ex)
|
||||
|
|
|
@ -6,6 +6,10 @@ require_relative 'configuration/servers'
|
|||
module Capistrano
|
||||
class Configuration
|
||||
|
||||
def initialize(config = nil)
|
||||
@config ||= config
|
||||
end
|
||||
|
||||
def self.env
|
||||
@env ||= new
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module Capistrano
|
|||
end
|
||||
end
|
||||
end
|
||||
@rex = Regexp.union av
|
||||
@rex = Regexp.union av.collect { |avi| avi.class == Symbol ? avi.to_s : avi }
|
||||
end
|
||||
def filter servers
|
||||
as = Array(servers)
|
||||
|
|
|
@ -34,7 +34,7 @@ module Capistrano
|
|||
branch: fetch(:branch),
|
||||
user: local_user,
|
||||
sha: fetch(:current_revision),
|
||||
release: release_timestamp)
|
||||
release: fetch(:release_timestamp))
|
||||
)
|
||||
end
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ module Capistrano
|
|||
file = shared_path.join(t.name)
|
||||
|
||||
on roles(target_roles) do
|
||||
unless test "[ -f #{file} ]"
|
||||
unless test "[ -f #{file.to_s.shellescape} ]"
|
||||
info "Uploading #{prerequisite_file} to #{file}"
|
||||
upload! File.open(prerequisite_file), file
|
||||
end
|
||||
|
@ -53,7 +53,7 @@ module Capistrano
|
|||
end
|
||||
|
||||
def exit_deploy_because_of_exception(ex)
|
||||
warn t(:deploy_failed, ex: ex.inspect)
|
||||
warn t(:deploy_failed, ex: ex.message)
|
||||
invoke 'deploy:failed'
|
||||
exit(false)
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ class Capistrano::Git < Capistrano::SCM
|
|||
end
|
||||
|
||||
def check
|
||||
test! :git, :'ls-remote -h', repo_url
|
||||
git :'ls-remote -h', repo_url
|
||||
end
|
||||
|
||||
def clone
|
||||
|
|
|
@ -28,7 +28,7 @@ class Capistrano::Svn < Capistrano::SCM
|
|||
end
|
||||
|
||||
def release
|
||||
svn :export, '.', release_path
|
||||
svn :export, '--force', '.', release_path
|
||||
end
|
||||
|
||||
def fetch_revision
|
||||
|
|
|
@ -82,8 +82,9 @@ namespace :deploy do
|
|||
desc 'Symlink release to current'
|
||||
task :release do
|
||||
on release_roles :all do
|
||||
execute :rm, '-rf', current_path
|
||||
execute :ln, '-s', release_path, current_path
|
||||
tmp_current_path = release_path.parent.join(current_path.basename)
|
||||
execute :ln, '-s', release_path, tmp_current_path
|
||||
execute :mv, tmp_current_path, current_path.parent
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -135,7 +136,7 @@ namespace :deploy do
|
|||
desc 'Clean up old releases'
|
||||
task :cleanup do
|
||||
on release_roles :all do |host|
|
||||
releases = capture(:ls, '-x', releases_path).split
|
||||
releases = capture(:ls, '-xtr', releases_path).split
|
||||
if releases.count >= fetch(:keep_releases)
|
||||
info t(:keeping_releases, host: host.to_s, keep_releases: fetch(:keep_releases), releases: releases.count)
|
||||
directories = (releases - releases.last(fetch(:keep_releases)))
|
||||
|
@ -154,7 +155,7 @@ namespace :deploy do
|
|||
desc 'Remove and archive rolled-back release.'
|
||||
task :cleanup_rollback do
|
||||
on release_roles(:all) do
|
||||
last_release = capture(:ls, '-xr', releases_path).split.first
|
||||
last_release = capture(:ls, '-xt', releases_path).split.first
|
||||
last_release_path = releases_path.join(last_release)
|
||||
if test "[ `readlink #{current_path}` != #{last_release_path} ]"
|
||||
execute :tar, '-czf',
|
||||
|
@ -189,7 +190,7 @@ namespace :deploy do
|
|||
|
||||
task :rollback_release_path do
|
||||
on release_roles(:all) do
|
||||
releases = capture(:ls, '-xr', releases_path).split
|
||||
releases = capture(:ls, '-xt', releases_path).split
|
||||
if releases.count < 2
|
||||
error t(:cannot_rollback)
|
||||
exit 1
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace :git do
|
|||
fetch(:branch)
|
||||
on release_roles :all do
|
||||
with fetch(:git_environmental_variables) do
|
||||
exit 1 unless strategy.check
|
||||
strategy.check
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,25 +14,28 @@ task :install do
|
|||
|
||||
mkdir_p deploy_dir
|
||||
|
||||
template = File.read(deploy_rb)
|
||||
file = config_dir.join('deploy.rb')
|
||||
File.open(file, 'w+') do |f|
|
||||
f.write(ERB.new(template).result(binding))
|
||||
puts I18n.t(:written_file, scope: :capistrano, file: file)
|
||||
end
|
||||
entries = [{template: deploy_rb, file: config_dir.join('deploy.rb')}]
|
||||
entries += envs.split(',').map { |stage| {template: stage_rb, file: deploy_dir.join("#{stage}.rb")} }
|
||||
|
||||
template = File.read(stage_rb)
|
||||
envs.split(',').each do |stage|
|
||||
file = deploy_dir.join("#{stage}.rb")
|
||||
File.open(file, 'w+') do |f|
|
||||
f.write(ERB.new(template).result(binding))
|
||||
puts I18n.t(:written_file, scope: :capistrano, file: file)
|
||||
entries.each do |entry|
|
||||
if File.exists?(entry[:file])
|
||||
warn "[skip] #{entry[:file]} already exists"
|
||||
else
|
||||
File.open(entry[:file], 'w+') do |f|
|
||||
f.write(ERB.new(File.read(entry[:template])).result(binding))
|
||||
puts I18n.t(:written_file, scope: :capistrano, file: entry[:file])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mkdir_p tasks_dir
|
||||
|
||||
FileUtils.cp(capfile, 'Capfile')
|
||||
if File.exists?('Capfile')
|
||||
warn "[skip] Capfile already exists"
|
||||
else
|
||||
FileUtils.cp(capfile, 'Capfile')
|
||||
puts I18n.t(:written_file, scope: :capistrano, file: 'Capfile')
|
||||
end
|
||||
|
||||
|
||||
puts I18n.t :capified, scope: :capistrano
|
||||
|
|
|
@ -5,6 +5,13 @@ module Capistrano
|
|||
let(:config) { Configuration.new }
|
||||
let(:servers) { stub }
|
||||
|
||||
describe '.new' do
|
||||
it 'accepts initial hash' do
|
||||
configuration = described_class.new(custom: 'value')
|
||||
expect(configuration.fetch(:custom)).to eq('value')
|
||||
end
|
||||
end
|
||||
|
||||
describe '.env' do
|
||||
it 'is a global accessor to a single instance' do
|
||||
Configuration.env.set(:test, true)
|
||||
|
|
|
@ -31,7 +31,7 @@ module Capistrano
|
|||
describe "#check" do
|
||||
it "should test the repo url" do
|
||||
context.expects(:repo_url).returns(:url)
|
||||
context.expects(:test).with(:git, :'ls-remote -h', :url).returns(true)
|
||||
context.expects(:execute).with(:git, :'ls-remote -h', :url).returns(true)
|
||||
|
||||
subject.check
|
||||
end
|
||||
|
|
|
@ -60,7 +60,7 @@ module Capistrano
|
|||
it "should run svn export" do
|
||||
context.expects(:release_path).returns(:path)
|
||||
|
||||
context.expects(:execute).with(:svn, :export, '.', :path)
|
||||
context.expects(:execute).with(:svn, :export, '--force', '.', :path)
|
||||
|
||||
subject.release
|
||||
end
|
||||
|
|
2
spec/support/Vagrantfile
vendored
2
spec/support/Vagrantfile
vendored
|
@ -6,7 +6,7 @@ Vagrant::Config.run do |config|
|
|||
config.vm.box = 'precise64'
|
||||
config.vm.box_url = 'http://files.vagrantup.com/precise64.box'
|
||||
config.vm.forward_port 22, "222#{i}".to_i
|
||||
config.vm.provision :shell, inline: 'yes | sudo apt-get install git-core'
|
||||
config.vm.provision :shell, inline: 'sudo apt-get -y install git-core'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue