bard 0.6.10 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/bard.gemspec +3 -2
- data/features/bard_check.feature +0 -28
- data/features/bard_deploy.feature +2 -1
- data/features/bard_pull.feature +30 -19
- data/features/bard_push.feature +13 -6
- data/features/step_definitions/check_steps.rb +0 -29
- data/features/step_definitions/git_steps.rb +13 -5
- data/features/step_definitions/global_steps.rb +21 -5
- data/features/step_definitions/submodule_steps.rb +6 -11
- data/features/support/env.rb +18 -22
- data/lib/bard.rb +17 -32
- data/lib/bard/check.rb +0 -10
- data/lib/bard/ssh_delegation.rb +36 -0
- metadata +3 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.7.0
|
data/bard.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bard}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.7.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Micah Geisel", "Nick Hogle"]
|
12
|
-
s.date = %q{2009-12-
|
12
|
+
s.date = %q{2009-12-23}
|
13
13
|
s.default_executable = %q{bard}
|
14
14
|
s.description = %q{This immaculate work of engineering genius allows mere mortals to collaborate with beings of transcendent intelligence like Micah, Michael, and Nick.}
|
15
15
|
s.email = %q{info@botandrose.com}
|
@@ -45,6 +45,7 @@ Gem::Specification.new do |s|
|
|
45
45
|
"lib/bard/error.rb",
|
46
46
|
"lib/bard/git.rb",
|
47
47
|
"lib/bard/io.rb",
|
48
|
+
"lib/bard/ssh_delegation.rb",
|
48
49
|
"spec/bard_spec.rb",
|
49
50
|
"spec/spec_helper.rb"
|
50
51
|
]
|
data/features/bard_check.feature
CHANGED
@@ -68,31 +68,3 @@ Feature: Bard can check its environment for missing dependencies and potential p
|
|
68
68
|
And the integration branch isnt tracking origin/integration
|
69
69
|
When I type "bard check"
|
70
70
|
Then I should see the fatal error "tracking"
|
71
|
-
|
72
|
-
Scenario: Bard check detects missing staging hook
|
73
|
-
Given a shared rails project
|
74
|
-
And my "RAILS_ENV" environment variable is "staging"
|
75
|
-
And there is no git hook on the staging server
|
76
|
-
When on staging, I type "bard check"
|
77
|
-
Then I should see the fatal error "missing git hook"
|
78
|
-
|
79
|
-
Scenario: Bard check detects unexecutable staging hook
|
80
|
-
Given a shared rails project
|
81
|
-
And my "RAILS_ENV" environment variable is "staging"
|
82
|
-
And the git hook on the staging server is not executable
|
83
|
-
When on staging, I type "bard check"
|
84
|
-
Then I should see the fatal error "unexecutable git hook"
|
85
|
-
|
86
|
-
Scenario: Bard check detects improper staging hook
|
87
|
-
Given a shared rails project
|
88
|
-
And my "RAILS_ENV" environment variable is "staging"
|
89
|
-
And the git hook on the staging server is bad
|
90
|
-
When on staging, I type "bard check"
|
91
|
-
Then I should see the fatal error "improper git hook"
|
92
|
-
|
93
|
-
Scenario: Bard check detects missing receive.denyCurrentBranch git variable on staging
|
94
|
-
Given a shared rails project
|
95
|
-
And my "RAILS_ENV" environment variable is "staging"
|
96
|
-
And the staging server git config for receive.denyCurrentBranch is not "ignore"
|
97
|
-
When on staging, I type "bard check"
|
98
|
-
Then I should see the fatal error "denyCurrentBranch"
|
@@ -2,7 +2,8 @@ Feature: Bard deploy should fold the integration branch into master and perform
|
|
2
2
|
|
3
3
|
Scenario: Bard deploy detects non-fast-forward merge from integration to master
|
4
4
|
Given a shared rails project
|
5
|
-
And on
|
5
|
+
And on development_b, a commit to the master branch
|
6
|
+
And on development_b, I type "git push origin master"
|
6
7
|
And a commit
|
7
8
|
When I type "bard deploy"
|
8
9
|
Then I should see the fatal error "Rebase"
|
data/features/bard_pull.feature
CHANGED
@@ -3,31 +3,35 @@ Feature: bard pull
|
|
3
3
|
Given a shared rails project
|
4
4
|
|
5
5
|
Scenario: Pulling down the latest changes from the remote integration branch
|
6
|
-
Given on
|
6
|
+
Given on development_b, a commit
|
7
|
+
And on development_b, I type "bard push"
|
7
8
|
When I type "bard pull"
|
8
|
-
Then the "integration" branch should match the "
|
9
|
+
Then the "integration" branch should match the "development_b:integration" branch
|
9
10
|
|
10
11
|
Scenario: Pulling down when the latest changes include a submodule addition
|
11
|
-
Given on
|
12
|
+
Given on development_b, a commit with a new submodule
|
13
|
+
And on development_b, I type "bard push"
|
12
14
|
When I type "bard pull"
|
13
|
-
Then the "integration" branch should match the "
|
15
|
+
Then the "integration" branch should match the "development_b:integration" branch
|
14
16
|
And there should be one new submodule
|
15
|
-
|
17
|
+
And the submodule branch should match the submodule origin branch
|
16
18
|
And the submodule working directory should be clean
|
17
19
|
|
18
20
|
Scenario: Pulling down when the latest changes include a submodule update
|
19
21
|
Given a submodule
|
20
|
-
And on
|
22
|
+
And on development_b, a commit with a submodule update
|
23
|
+
And on development_b, I type "bard push"
|
21
24
|
When I type "bard pull"
|
22
|
-
Then the "integration" branch should match the "
|
25
|
+
Then the "integration" branch should match the "development_b:integration" branch
|
23
26
|
And the submodule branch should match the submodule origin branch
|
24
27
|
And the submodule working directory should be clean
|
25
28
|
|
26
29
|
Scenario: Pulling down when the latest changes include a submodule url change
|
27
30
|
Given a submodule
|
28
|
-
And on
|
31
|
+
And on development_b, a commit with a submodule url change
|
32
|
+
And on development_b, I type "bard push"
|
29
33
|
When I type "bard pull"
|
30
|
-
Then the "integration" branch should match the "
|
34
|
+
Then the "integration" branch should match the "development_b:integration" branch
|
31
35
|
And the submodule url should be changed
|
32
36
|
And the submodule branch should match the submodule origin branch
|
33
37
|
And the submodule working directory should be clean
|
@@ -41,11 +45,12 @@ Feature: bard pull
|
|
41
45
|
# And the submodule should be deleted
|
42
46
|
|
43
47
|
Scenario: Pulling latest changes from the remote integration branch after committing locally
|
44
|
-
Given on
|
48
|
+
Given on development_b, a commit
|
49
|
+
And on development_b, I type "bard push"
|
45
50
|
And a commit
|
46
51
|
When I type "bard pull"
|
47
52
|
Then I should see the warning "Someone has pushed some changes"
|
48
|
-
And the "integration" branch should be a fast-forward from the "
|
53
|
+
And the "integration" branch should be a fast-forward from the "development_b:integration" branch
|
49
54
|
|
50
55
|
Scenario: Trying to bard pull when not in the project root
|
51
56
|
Given I am in a subdirectory
|
@@ -53,27 +58,31 @@ Feature: bard pull
|
|
53
58
|
Then I should see the fatal error "root directory"
|
54
59
|
|
55
60
|
Scenario: Trying to bard pull with a dirty working directory
|
56
|
-
Given on
|
61
|
+
Given on development_b, a commit
|
62
|
+
And on development_b, I type "bard push"
|
57
63
|
And a dirty working directory
|
58
64
|
When I type "bard pull"
|
59
65
|
Then I should see the fatal error "You have uncommitted changes!"
|
60
|
-
And the "integration" branch should not match the "
|
66
|
+
And the "integration" branch should not match the "development_b:integration" branch
|
61
67
|
|
62
68
|
Scenario: Trying to bard pull when not on the integration branch
|
63
|
-
Given on
|
69
|
+
Given on development_b, a commit
|
70
|
+
And on development_b, I type "bard push"
|
64
71
|
And I am on a non-integration branch
|
65
72
|
When I type "bard pull"
|
66
73
|
Then I should see the fatal error "not on the integration branch"
|
67
|
-
And the "integration" branch should not match the "
|
74
|
+
And the "integration" branch should not match the "development_b:integration" branch
|
68
75
|
|
69
76
|
Scenario: Pulling in a change that includes a migration on a dev machine
|
70
|
-
Given on
|
77
|
+
Given on development_b, a commit with a new migration
|
78
|
+
And on development_b, I type "bard push"
|
71
79
|
And a development database
|
72
80
|
When I type "bard pull"
|
73
81
|
Then the development database should include that migration
|
74
82
|
|
75
83
|
Scenario: Pulling in a change that includes a migration on a dev and testing machine
|
76
|
-
Given on
|
84
|
+
Given on development_b, a commit with a new migration
|
85
|
+
And on development_b, I type "bard push"
|
77
86
|
And a development database
|
78
87
|
And a test database
|
79
88
|
When I type "bard pull"
|
@@ -82,11 +91,13 @@ Feature: bard pull
|
|
82
91
|
|
83
92
|
Scenario: Pulling in a change that includes a gem dependency change
|
84
93
|
Given the test gem is not installed
|
85
|
-
And on
|
94
|
+
And on development_b, a commit that adds the test gem as a dependency
|
95
|
+
And on development_b, I type "bard push"
|
86
96
|
When I type "bard pull"
|
87
97
|
Then the test gem should be installed
|
88
98
|
|
89
99
|
Scenario: Pulling in a change should restart the rails server
|
90
|
-
Given on
|
100
|
+
Given on development_b, a commit
|
101
|
+
And on development_b, I type "bard push"
|
91
102
|
When I type "bard pull"
|
92
103
|
Then passenger should have been restarted
|
data/features/bard_push.feature
CHANGED
@@ -5,31 +5,34 @@ Feature: bard push
|
|
5
5
|
Scenario: Uploading local changes onto the remote integration branch
|
6
6
|
Given a commit
|
7
7
|
When I type "bard push"
|
8
|
-
|
8
|
+
And on staging, I type "bard stage"
|
9
|
+
Then the "integration" branch should match the "staging:integration" branch
|
9
10
|
|
10
11
|
Scenario: Pushing a change that includes a migration
|
11
12
|
Given on staging, a staging database
|
12
|
-
And on staging, a test database
|
13
13
|
And a commit with a new migration
|
14
14
|
When I type "bard push"
|
15
|
+
And on staging, I type "bard stage"
|
15
16
|
Then on staging, the staging database should include that migration
|
16
|
-
And on staging, the test database should include that migration
|
17
17
|
|
18
18
|
Scenario: Pushing a change that includes a gem dependency change
|
19
19
|
Given the test gem is not installed
|
20
20
|
And a commit that adds the test gem as a dependency
|
21
21
|
When I type "bard push"
|
22
|
+
And on staging, I type "bard stage"
|
22
23
|
Then on staging, the test gem should be installed
|
23
24
|
|
24
25
|
Scenario: Pushing a change should advance the staging HEAD and restart the staging rails server
|
25
26
|
Given a commit
|
26
27
|
When I type "bard push"
|
27
|
-
|
28
|
-
And
|
28
|
+
And on staging, I type "bard stage"
|
29
|
+
And the "integration" branch should match the "staging:integration" branch
|
30
|
+
Then on staging, passenger should have been restarted
|
29
31
|
|
30
32
|
Scenario: Pushing a change that includes a submodule addition
|
31
33
|
Given a commit with a new submodule
|
32
34
|
When I type "bard push"
|
35
|
+
And on staging, I type "bard stage"
|
33
36
|
Then on staging, there should be one new submodule
|
34
37
|
And the submodule branch should match the submodule origin branch
|
35
38
|
And on staging, the submodule working directory should be clean
|
@@ -38,6 +41,7 @@ Feature: bard push
|
|
38
41
|
Given a submodule
|
39
42
|
And a commit with a submodule update
|
40
43
|
When I type "bard push"
|
44
|
+
And on staging, I type "bard stage"
|
41
45
|
Then the submodule branch should match the submodule origin branch
|
42
46
|
Then on staging, the submodule working directory should be clean
|
43
47
|
|
@@ -45,6 +49,7 @@ Feature: bard push
|
|
45
49
|
Given a submodule
|
46
50
|
And a commit with a submodule url change
|
47
51
|
When I type "bard push"
|
52
|
+
And on staging, I type "bard stage"
|
48
53
|
Then on staging, the submodule url should be changed
|
49
54
|
And the submodule branch should match the submodule origin branch
|
50
55
|
Then on staging, the submodule working directory should be clean
|
@@ -54,6 +59,7 @@ Feature: bard push
|
|
54
59
|
# Given a submodule
|
55
60
|
# Given I have committed a set of changes that includes a submodule deletion
|
56
61
|
# When I type "bard push"
|
62
|
+
# And on staging, I type "bard stage"
|
57
63
|
# Then the remote submodule should be deleted
|
58
64
|
|
59
65
|
Scenario: Trying to bard push when not in the project root
|
@@ -77,7 +83,8 @@ Feature: bard push
|
|
77
83
|
|
78
84
|
Scenario: Trying to bard push with a non-fast-foward changeset
|
79
85
|
Given a commit
|
80
|
-
And on
|
86
|
+
And on development_b, a commit
|
87
|
+
And on development_b, I type "bard push"
|
81
88
|
When I type "bard push"
|
82
89
|
Then I should see the fatal error "Someone has pushed some changes"
|
83
90
|
And the "integration" branch should not match the "origin/integration" branch
|
@@ -45,32 +45,3 @@ Given /^the submodule has a detached head$/ do
|
|
45
45
|
type "git checkout `git rev-parse HEAD`"
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
49
|
-
Given /^my "([^\"]*)" environment variable is "([^\"]*)"$/ do |key, value|
|
50
|
-
@env ||= Hash.new
|
51
|
-
@env[key] = value
|
52
|
-
end
|
53
|
-
|
54
|
-
Given /^there is no git hook on the staging server$/ do
|
55
|
-
Dir.chdir "#{ROOT}/tmp/origin" do
|
56
|
-
type "rm .git/hooks/post-receive"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
Given /^the git hook on the staging server is not executable$/ do
|
61
|
-
Dir.chdir "#{ROOT}/tmp/origin" do
|
62
|
-
type "chmod 664 .git/hooks/post-receive"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
Given /^the git hook on the staging server is bad$/ do
|
67
|
-
Dir.chdir "#{ROOT}/tmp/origin" do
|
68
|
-
type "echo 'bad' > .git/hooks/post-receive"
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
Given /^the staging server git config for receive.denyCurrentBranch is not "ignore"$/ do
|
73
|
-
Dir.chdir "#{ROOT}/tmp/origin" do
|
74
|
-
type "git config --unset receive.denyCurrentBranch"
|
75
|
-
end
|
76
|
-
end
|
@@ -51,15 +51,23 @@ end
|
|
51
51
|
|
52
52
|
Then /^the "([^\"]*)" branch (should|should not) match the "([^\"]*)" branch$/ do |local_branch, which, remote_branch|
|
53
53
|
type "git fetch origin"
|
54
|
-
|
55
|
-
|
54
|
+
local_env, local_branch = local_branch.split(':') if local_branch.include? ':'
|
55
|
+
local_env ||= "development_a"
|
56
|
+
remote_env, remote_branch = remote_branch.split(':') if remote_branch.include? ':'
|
57
|
+
remote_env ||= "development_a"
|
58
|
+
local_sha = @repos[local_env].commits(local_branch).first.id
|
59
|
+
remote_sha = @repos[remote_env].commits(remote_branch).first.id
|
56
60
|
which = which.gsub(/ /, '_').to_sym
|
57
61
|
local_sha.send(which) == remote_sha
|
58
62
|
end
|
59
63
|
|
60
64
|
Then /^the "([^\"]*)" branch should be a fast\-forward from the "([^\"]*)" branch$/ do |local_branch, remote_branch|
|
61
|
-
|
62
|
-
|
63
|
-
|
65
|
+
local_env, local_branch = local_branch.split(':') if local_branch.include? ':'
|
66
|
+
local_env ||= "development_a"
|
67
|
+
remote_env, remote_branch = remote_branch.split(':') if remote_branch.include? ':'
|
68
|
+
remote_env ||= "development_a"
|
69
|
+
local_sha = @repos[local_env].commits(local_branch).first.id
|
70
|
+
remote_sha = @repos[remote_env].commits(remote_branch).first.id
|
71
|
+
common_ancestor = @repos[local_env].find_common_ancestor local_sha, remote_sha
|
64
72
|
common_ancestor.should == remote_sha
|
65
73
|
end
|
@@ -7,9 +7,15 @@ Given /^a shared rails project$/ do
|
|
7
7
|
# SETUP
|
8
8
|
Dir.chdir ROOT
|
9
9
|
`cp -r tmp/fixtures/* tmp/`
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
|
11
|
+
Dir.chdir 'tmp'
|
12
|
+
@repos = {}
|
13
|
+
%w(development_a development_b staging production).each do |env|
|
14
|
+
@repos[env] = Grit::Repo.new env
|
15
|
+
end
|
16
|
+
Dir.chdir 'development_a'
|
17
|
+
@repo = @repos['development_a']
|
18
|
+
@env = { 'RAILS_ENV' => 'development', 'TESTING' => true }
|
13
19
|
end
|
14
20
|
|
15
21
|
Given /^I am in a subdirectory$/ do
|
@@ -21,10 +27,16 @@ When /^I type "([^\"]*)"$/ do |command|
|
|
21
27
|
type command.sub /\b(bard)\b/, "#{ROOT}/bin/bard"
|
22
28
|
end
|
23
29
|
|
24
|
-
When /^on
|
25
|
-
|
30
|
+
When /^on (\w+), (.*$)/ do |env, step|
|
31
|
+
old_env = @env['RAILS_ENV']
|
32
|
+
@env['RAILS_ENV'] = env if %w(staging production).include? env
|
33
|
+
Dir.chdir "#{ROOT}/tmp/#{env}" do
|
34
|
+
old_repo = @repo
|
35
|
+
@repo = @repos[env]
|
26
36
|
When step
|
37
|
+
@repo = old_repo
|
27
38
|
end
|
39
|
+
@env['RAILS_ENV'] = old_env
|
28
40
|
end
|
29
41
|
|
30
42
|
Then /^I should see the fatal error "([^\"]*)"$/ do |error_message|
|
@@ -38,3 +50,7 @@ end
|
|
38
50
|
Then /^I should see "([^\"]*)"$/ do |message|
|
39
51
|
@stdout.should include(message)
|
40
52
|
end
|
53
|
+
|
54
|
+
Then /^debug$/ do
|
55
|
+
debugger
|
56
|
+
end
|
@@ -1,12 +1,7 @@
|
|
1
1
|
Given /^a submodule$/ do
|
2
|
-
Given 'on
|
3
|
-
type "
|
4
|
-
type "
|
5
|
-
type "git submodule init"
|
6
|
-
type "git submodule update"
|
7
|
-
Dir.chdir "submodule" do
|
8
|
-
type "git checkout master"
|
9
|
-
end
|
2
|
+
Given 'on development_b, a commit with a new submodule'
|
3
|
+
Given 'on development_b, I type "bard push"'
|
4
|
+
Given 'I type "bard pull"'
|
10
5
|
@submodule_url = File.read(".gitmodules").match(/url = (.*)$/)[1]
|
11
6
|
@submodule_commit = type "git submodule status"
|
12
7
|
end
|
@@ -27,11 +22,11 @@ Given /^a commit to the submodule$/ do
|
|
27
22
|
end
|
28
23
|
|
29
24
|
Given /^a commit with a new submodule$/ do
|
30
|
-
type "git submodule add #{ROOT}/tmp/
|
25
|
+
type "git submodule add #{ROOT}/tmp/submodule_a.git submodule"
|
31
26
|
type "git submodule init"
|
32
27
|
type "git submodule update --merge"
|
33
28
|
Dir.chdir "submodule" do
|
34
|
-
type "
|
29
|
+
type "git checkout -b master origin/master"
|
35
30
|
end
|
36
31
|
type "git add ."
|
37
32
|
type "git commit -m 'added submodule'"
|
@@ -51,7 +46,7 @@ Given /^a commit with a submodule update$/ do
|
|
51
46
|
end
|
52
47
|
|
53
48
|
Given /^a commit with a submodule url change$/ do
|
54
|
-
gsub_file ".gitmodules",
|
49
|
+
gsub_file ".gitmodules", "submodule_a.git", "submodule_b.git"
|
55
50
|
type "git add ."
|
56
51
|
type "git commit -m 'updated submodule url'"
|
57
52
|
end
|
data/features/support/env.rb
CHANGED
@@ -6,33 +6,29 @@ require 'systemu'
|
|
6
6
|
gem 'sqlite3-ruby'
|
7
7
|
|
8
8
|
ENV["PATH"] += ":#{File.dirname(File.expand_path(__FILE__))}/../../bin"
|
9
|
+
ENV["GIT_DIR"] = nil
|
10
|
+
ENV["GIT_WORK_TREE"] = nil
|
11
|
+
ENV["GIT_INDEX_FILE"] = nil
|
9
12
|
|
10
13
|
ROOT = File.expand_path(File.dirname(__FILE__) + '/../..')
|
11
14
|
|
12
15
|
# setup fixtures
|
13
16
|
FileUtils.rm_rf "tmp"
|
14
17
|
FileUtils.mkdir "tmp"
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
Dir.chdir 'tmp' do
|
19
|
+
`git clone --mirror --recursive ../fixtures/repo origin.git`
|
20
|
+
|
21
|
+
`git clone --bare --recursive origin.git submodule_a.git`
|
22
|
+
`git clone --bare --recursive origin.git submodule_b.git`
|
23
|
+
%w(development_a development_b staging production).each do |env|
|
24
|
+
`git clone --recursive origin.git #{env}`
|
25
|
+
Dir.chdir env do
|
26
|
+
FileUtils.cp "config/database.sample.yml", "config/database.yml"
|
27
|
+
`git checkout -b integration origin/integration` unless env == "production"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
FileUtils.mkdir "fixtures"
|
31
|
+
Dir.foreach "." do |file|
|
32
|
+
FileUtils.mv(file, "fixtures/") unless %w(fixtures . ..).include? file
|
24
33
|
end
|
25
|
-
FileUtils.cp "config/database.sample.yml", "config/database.yml"
|
26
|
-
`git checkout -b integration`
|
27
|
-
end
|
28
|
-
FileUtils.cp_r "fixtures/repo", "tmp/submodule"
|
29
|
-
FileUtils.cp_r "fixtures/repo", "tmp/submodule2"
|
30
|
-
`git clone tmp/origin tmp/local`
|
31
|
-
Dir.chdir 'tmp/local' do
|
32
|
-
`grb fetch integration && git checkout integration`
|
33
|
-
FileUtils.cp "config/database.sample.yml", "config/database.yml"
|
34
|
-
end
|
35
|
-
FileUtils.mkdir "tmp/fixtures"
|
36
|
-
Dir.foreach "tmp" do |file|
|
37
|
-
FileUtils.mv("tmp/#{file}", "tmp/fixtures/") unless %w(fixtures . ..).include? file
|
38
34
|
end
|
data/lib/bard.rb
CHANGED
@@ -11,6 +11,7 @@ require 'bard/git'
|
|
11
11
|
require 'bard/io'
|
12
12
|
|
13
13
|
require 'bard/check'
|
14
|
+
require 'bard/ssh_delegation'
|
14
15
|
|
15
16
|
class Bard < Thor
|
16
17
|
include BardGit
|
@@ -48,7 +49,7 @@ class Bard < Thor
|
|
48
49
|
|
49
50
|
run_crucial "git push origin integration", true
|
50
51
|
|
51
|
-
|
52
|
+
run_crucial_via_bard "bard stage"
|
52
53
|
end
|
53
54
|
|
54
55
|
desc "deploy", "pushes, merges integration branch into master and deploys it to production"
|
@@ -67,27 +68,13 @@ class Bard < Thor
|
|
67
68
|
run_crucial "cap ROLES=staging COMMAND='cd #{project_name} && cap deploy' invoke"
|
68
69
|
end
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
check_dependencies
|
74
|
-
|
75
|
-
if ENV['GIT_DIR'] == '.'
|
76
|
-
# this means the script has been called as a hook, not manually.
|
77
|
-
# get the proper GIT_DIR so we can descend into the working copy dir;
|
78
|
-
# if we don't then `git reset --hard` doesn't affect the working tree.
|
79
|
-
Dir.chdir '..'
|
80
|
-
ENV['GIT_DIR'] = '.git'
|
81
|
-
end
|
82
|
-
|
83
|
-
raise StagingDetachedHeadError unless current_branch
|
84
|
-
old_rev, new_rev, branch = gets.split(' ') # get the low down about the commit from the git hook
|
71
|
+
desc "stage", "!!! INTERNAL USE ONLY !!! reset HEAD to integration, update submodules, run migrations, install gems, restart server"
|
72
|
+
def stage
|
73
|
+
check_dependencies
|
85
74
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
end
|
75
|
+
run_crucial "git fetch"
|
76
|
+
run_crucial "git reset --hard origin/integration"
|
77
|
+
prepare_environment
|
91
78
|
end
|
92
79
|
|
93
80
|
private
|
@@ -98,22 +85,20 @@ class Bard < Thor
|
|
98
85
|
raise WorkingTreeDirtyError unless `git status`.include? "working directory clean"
|
99
86
|
end
|
100
87
|
|
101
|
-
def prepare_environment(changed_files)
|
102
|
-
if changed_files.any? { |f| f =~ %r(^
|
88
|
+
def prepare_environment(changed_files = nil)
|
89
|
+
if changed_files.nil? or changed_files.any? { |f| f =~ %r(^config/environment.+) }
|
90
|
+
run_crucial "rake gems:install"
|
91
|
+
end
|
92
|
+
|
93
|
+
if changed_files.nil? or changed_files.any? { |f| f =~ %r(^db/migrate/.+) }
|
103
94
|
run_crucial "rake db:migrate"
|
104
|
-
run_crucial "rake db:migrate RAILS_ENV=test"
|
95
|
+
run_crucial "rake db:migrate RAILS_ENV=test" unless ENV['RAILS_ENV'] == 'staging'
|
105
96
|
end
|
106
97
|
|
107
98
|
run_crucial "git submodule sync"
|
99
|
+
run_crucial "git submodule init"
|
108
100
|
run_crucial "git submodule update --merge"
|
109
|
-
|
110
|
-
run_crucial "git submodule update --init"
|
111
|
-
end
|
112
|
-
run_crucial "git submodule foreach 'git reset --hard'"
|
113
|
-
|
114
|
-
if changed_files.any? { |f| f =~ %r(^config/environment.+) }
|
115
|
-
run_crucial "rake gems:install"
|
116
|
-
end
|
101
|
+
run_crucial "git submodule foreach 'git checkout `git name-rev --name-only HEAD`'"
|
117
102
|
|
118
103
|
system "touch tmp/restart.txt"
|
119
104
|
end
|
data/lib/bard/check.rb
CHANGED
@@ -52,16 +52,6 @@ class Bard < Thor
|
|
52
52
|
errors << "integration branch isnt tracking the remote integration branch, please run `grb track integration`" if `git config branch.integration.merge` !~ %r%\brefs/heads/integration\b%
|
53
53
|
end
|
54
54
|
errors << "you shouldn't be working on the master branch, please work on the integration branch" if current_branch == "master"
|
55
|
-
|
56
|
-
if ENV['RAILS_ENV'] == "staging"
|
57
|
-
if not File.exist? ".git/hooks/post-receive"
|
58
|
-
errors << "missing git hook, please complain to micah"
|
59
|
-
else
|
60
|
-
errors << "unexecutable git hook, please complain to micah" unless File.executable? ".git/hooks/post-receive"
|
61
|
-
errors << "improper git hook, please complain to micah" unless File.read(".git/hooks/post-receive").include? "bard stage $@"
|
62
|
-
end
|
63
|
-
errors << "the git config variable receive.denyCurrentBranch is not set to ignore, please complain to micah" if `git config receive.denyCurrentBranch`.chomp != "ignore"
|
64
|
-
end
|
65
55
|
end
|
66
56
|
|
67
57
|
if not errors.empty?
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class Bard < Thor
|
2
|
+
desc "install-authorized-keys", "!!! INTERNAL USE ONLY !!! run as sudo"
|
3
|
+
def install_authorized_keys(source_user, dest_user)
|
4
|
+
source = "/home/#{source_user}/.ssh/authorized_keys"
|
5
|
+
dest = "/home/#{dest_user}/.ssh/authorized_keys"
|
6
|
+
|
7
|
+
file = File.read(source)
|
8
|
+
file.gsub! /gitosis-serve/, "bard delegate"
|
9
|
+
|
10
|
+
File.open(dest, "w") { |f| f.write(file) }
|
11
|
+
end
|
12
|
+
|
13
|
+
desc "delegate", "!!! INTERNAL USER ONLY !!!"
|
14
|
+
def delegate(key)
|
15
|
+
command = ENV['SSH_ORIGINAL_COMMAND']
|
16
|
+
|
17
|
+
case command
|
18
|
+
when /^scp -f (\w+)\.sql\.gz$/
|
19
|
+
project = $1
|
20
|
+
`#{command_for("staging", "cd #{project} && rake db:dump RAILS_ENV=staging && gzip -9f db/data.sql")}`
|
21
|
+
command = "scp -f ~/#{project}/db/data.sql.gz"
|
22
|
+
end
|
23
|
+
|
24
|
+
exec command_for("staging", command)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def command_for(user, command)
|
29
|
+
%(sudo -H -u #{user} sh -c "cd ~ && #{command}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_crucial_via_bard(command)
|
33
|
+
return if ENV['TESTING']
|
34
|
+
run_crucial %(ssh bard@bard.botandrose.com "cd #{project_name} && #{command}")
|
35
|
+
end
|
36
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2009-12-
|
13
|
+
date: 2009-12-23 00:00:00 -08:00
|
14
14
|
default_executable: bard
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -129,6 +129,7 @@ files:
|
|
129
129
|
- lib/bard/error.rb
|
130
130
|
- lib/bard/git.rb
|
131
131
|
- lib/bard/io.rb
|
132
|
+
- lib/bard/ssh_delegation.rb
|
132
133
|
- spec/bard_spec.rb
|
133
134
|
- spec/spec_helper.rb
|
134
135
|
has_rdoc: true
|