bard 2.2.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -487
- data/Rakefile +1 -4
- data/bard.gemspec +2 -11
- data/lib/bard/config.rb +22 -20
- data/lib/bard/plugins/ping/target_methods.rb +0 -9
- data/lib/bard/plugins/ssh/connection.rb +2 -35
- data/lib/bard/target.rb +0 -15
- data/lib/bard/version.rb +1 -1
- data/lib/bard.rb +2 -1
- data/spec/bard/capability_spec.rb +0 -8
- data/spec/bard/config_spec.rb +30 -67
- data/spec/bard/target_spec.rb +1 -36
- metadata +4 -225
- data/ARCHITECTURE.md +0 -957
- data/CUSTOM_STRATEGIES.md +0 -701
- data/MIGRATION_GUIDE.md +0 -513
- data/PLUGINS.md +0 -99
- data/bin/bard +0 -4
- data/features/ci.feature +0 -63
- data/features/data.feature +0 -13
- data/features/deploy.feature +0 -14
- data/features/deploy_git_workflow.feature +0 -89
- data/features/run.feature +0 -14
- data/features/step_definitions/bard_steps.rb +0 -136
- data/features/support/bard-coverage +0 -16
- data/features/support/env.rb +0 -22
- data/features/support/test_server.rb +0 -216
- data/lib/bard/cli.rb +0 -44
- data/lib/bard/command.rb +0 -31
- data/lib/bard/copy.rb +0 -45
- data/lib/bard/plugins/data.rb +0 -56
- data/lib/bard/plugins/deploy/ci/github_actions.rb +0 -202
- data/lib/bard/plugins/deploy/ci/jenkins.rb +0 -176
- data/lib/bard/plugins/deploy/ci/local.rb +0 -57
- data/lib/bard/plugins/deploy/ci/runner.rb +0 -112
- data/lib/bard/plugins/deploy/ci/state.rb +0 -40
- data/lib/bard/plugins/deploy/ci.rb +0 -38
- data/lib/bard/plugins/deploy/ssh_strategy.rb +0 -26
- data/lib/bard/plugins/deploy/strategy.rb +0 -60
- data/lib/bard/plugins/deploy.rb +0 -260
- data/lib/bard/plugins/git.rb +0 -45
- data/lib/bard/plugins/github.rb +0 -152
- data/lib/bard/plugins/github_pages/strategy.rb +0 -170
- data/lib/bard/plugins/github_pages.rb +0 -35
- data/lib/bard/plugins/hurt.rb +0 -13
- data/lib/bard/plugins/install/.github/dependabot.yml +0 -18
- data/lib/bard/plugins/install/.github/workflows/cache-ci.yml +0 -15
- data/lib/bard/plugins/install/.github/workflows/ci.yml +0 -74
- data/lib/bard/plugins/install/apt_dependencies.rb +0 -33
- data/lib/bard/plugins/install/ci +0 -5
- data/lib/bard/plugins/install/setup +0 -13
- data/lib/bard/plugins/install/specified_bundler.rb +0 -15
- data/lib/bard/plugins/install/specified_ruby.rb +0 -59
- data/lib/bard/plugins/install.rb +0 -9
- data/lib/bard/plugins/open.rb +0 -20
- data/lib/bard/plugins/ping/check.rb +0 -66
- data/lib/bard/plugins/ping.rb +0 -10
- data/lib/bard/plugins/run.rb +0 -19
- data/lib/bard/plugins/setup.rb +0 -75
- data/lib/bard/plugins/ssh/copy.rb +0 -95
- data/lib/bard/plugins/ssh.rb +0 -10
- data/lib/bard/plugins/vim.rb +0 -6
- data/lib/bard/retryable.rb +0 -25
- data/lib/bard/secrets.rb +0 -10
- data/spec/acceptance/.gitignore +0 -4
- data/spec/acceptance/docker/Dockerfile +0 -36
- data/spec/acceptance/docker/test_key +0 -27
- data/spec/acceptance/docker/test_key.pub +0 -1
- data/spec/bard/ci/github_actions_spec.rb +0 -138
- data/spec/bard/ci/jenkins_spec.rb +0 -139
- data/spec/bard/ci/runner_spec.rb +0 -61
- data/spec/bard/ci_spec.rb +0 -10
- data/spec/bard/cli/ci_spec.rb +0 -170
- data/spec/bard/cli/data_spec.rb +0 -58
- data/spec/bard/cli/deploy_spec.rb +0 -243
- data/spec/bard/cli/hurt_spec.rb +0 -17
- data/spec/bard/cli/install_spec.rb +0 -19
- data/spec/bard/cli/master_key_spec.rb +0 -38
- data/spec/bard/cli/open_spec.rb +0 -51
- data/spec/bard/cli/ping_spec.rb +0 -32
- data/spec/bard/cli/run_spec.rb +0 -57
- data/spec/bard/cli/setup_spec.rb +0 -99
- data/spec/bard/cli/ssh_spec.rb +0 -40
- data/spec/bard/cli/stage_spec.rb +0 -127
- data/spec/bard/cli/vim_spec.rb +0 -28
- data/spec/bard/command_spec.rb +0 -30
- data/spec/bard/copy_spec.rb +0 -69
- data/spec/bard/deploy_strategy/github_pages_spec.rb +0 -58
- data/spec/bard/deploy_strategy/ssh_spec.rb +0 -135
- data/spec/bard/deploy_strategy_spec.rb +0 -107
- data/spec/bard/dynamic_dsl_spec.rb +0 -46
- data/spec/bard/git_spec.rb +0 -101
- data/spec/bard/github_spec.rb +0 -45
- data/spec/bard/ping_spec.rb +0 -60
- data/spec/bard/ssh_copy_spec.rb +0 -44
data/spec/bard/cli/stage_spec.rb
DELETED
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/cli"
|
|
3
|
-
|
|
4
|
-
describe "bard stage" do
|
|
5
|
-
let(:staging_strategy) { double("staging_strategy", deploy: true) }
|
|
6
|
-
let(:staging_server) { double("staging", deploy_strategy: :ssh, deploy_strategy_instance: staging_strategy) }
|
|
7
|
-
let(:production_server) { double("production") }
|
|
8
|
-
let(:targets) { { production: production_server, staging: staging_server } }
|
|
9
|
-
let(:config) { double("config", targets: targets) }
|
|
10
|
-
let(:cli) { Bard::CLI.new }
|
|
11
|
-
|
|
12
|
-
before do
|
|
13
|
-
allow(cli).to receive(:config).and_return(config)
|
|
14
|
-
allow(cli).to receive(:puts)
|
|
15
|
-
allow(cli).to receive(:exit)
|
|
16
|
-
allow(cli).to receive(:run!)
|
|
17
|
-
allow(cli).to receive(:ping)
|
|
18
|
-
allow(cli).to receive(:green).and_return("")
|
|
19
|
-
allow(cli).to receive(:red).and_return("")
|
|
20
|
-
allow(cli).to receive(:yellow) { |s| s }
|
|
21
|
-
allow(Bard::Git).to receive(:current_branch).and_return("main")
|
|
22
|
-
allow(config).to receive(:[]).with(:staging).and_return(staging_server)
|
|
23
|
-
allow(config).to receive(:[]).with(:production).and_return(production_server)
|
|
24
|
-
allow(cli).to receive(:project_name).and_return("acme")
|
|
25
|
-
allow(cli).to receive(:staging_provisioned?).and_return(true)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
describe "#stage" do
|
|
29
|
-
it "should have a stage command" do
|
|
30
|
-
expect(cli).to respond_to(:stage)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
context "when the staging site has been reaped" do
|
|
34
|
-
before do
|
|
35
|
-
allow(cli).to receive(:staging_provisioned?).and_return(false)
|
|
36
|
-
allow(cli).to receive(:invoke)
|
|
37
|
-
allow($stdin).to receive(:tty?).and_return(false)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it "provisions from scratch by cloning and checking out the branch" do
|
|
41
|
-
expect(staging_strategy).to receive(:deploy).with(clone: "acme", branch: "main")
|
|
42
|
-
cli.stage
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "restores data from production by default (Enter/no decline)" do
|
|
46
|
-
allow(staging_strategy).to receive(:deploy)
|
|
47
|
-
allow($stdin).to receive(:tty?).and_return(true)
|
|
48
|
-
allow(cli).to receive(:no?).and_return(false)
|
|
49
|
-
expect(cli).to receive(:invoke).with(:data, [], from: "production", to: "staging")
|
|
50
|
-
cli.stage
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "skips the restore when the user declines" do
|
|
54
|
-
allow(staging_strategy).to receive(:deploy)
|
|
55
|
-
allow($stdin).to receive(:tty?).and_return(true)
|
|
56
|
-
allow(cli).to receive(:no?).and_return(true)
|
|
57
|
-
expect(cli).not_to receive(:invoke)
|
|
58
|
-
cli.stage
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "prints restore instructions when non-interactive" do
|
|
62
|
-
allow(staging_strategy).to receive(:deploy)
|
|
63
|
-
expect(cli).to receive(:puts).with(/bard data --from production --to staging/)
|
|
64
|
-
cli.stage
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
context "when the staging site already exists" do
|
|
69
|
-
it "does not prompt to restore data" do
|
|
70
|
-
allow($stdin).to receive(:tty?).and_return(true)
|
|
71
|
-
expect(cli).not_to receive(:invoke)
|
|
72
|
-
cli.stage
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
context "when production server is defined" do
|
|
77
|
-
it "pushes branch and stages it" do
|
|
78
|
-
expect(cli).to receive(:run!).with("git push -u origin main", verbose: true)
|
|
79
|
-
expect(staging_strategy).to receive(:deploy)
|
|
80
|
-
expect(cli).to receive(:ping).with(:staging)
|
|
81
|
-
|
|
82
|
-
cli.stage
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
it "accepts custom branch" do
|
|
86
|
-
expect(cli).to receive(:run!).with("git push -u origin develop", verbose: true)
|
|
87
|
-
expect(staging_strategy).to receive(:deploy)
|
|
88
|
-
|
|
89
|
-
cli.stage("develop")
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
context "when staging target has a deploy strategy" do
|
|
94
|
-
let(:strategy_instance) { double("strategy") }
|
|
95
|
-
let(:staging_server) { double("staging", deploy_strategy: :fake, deploy_strategy_instance: strategy_instance) }
|
|
96
|
-
|
|
97
|
-
it "uses the deploy strategy" do
|
|
98
|
-
expect(cli).to receive(:run!).with("git push -u origin main", verbose: true)
|
|
99
|
-
expect(strategy_instance).to receive(:deploy)
|
|
100
|
-
expect(cli).to receive(:ping).with(:staging)
|
|
101
|
-
|
|
102
|
-
cli.stage
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
context "when production target is equivalent to staging" do
|
|
107
|
-
before do
|
|
108
|
-
allow(config).to receive(:[]).with(:production).and_return(staging_server)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "raises an error" do
|
|
112
|
-
expect { cli.stage }.to raise_error(Thor::Error, /bard stage.*is disabled/)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
context "when command fails" do
|
|
117
|
-
it "handles errors gracefully" do
|
|
118
|
-
allow(cli).to receive(:run!).and_raise(Bard::Command::Error.new("Git push failed"))
|
|
119
|
-
|
|
120
|
-
expect(cli).to receive(:puts).with(/Running command failed/)
|
|
121
|
-
expect(cli).to receive(:exit).with(1)
|
|
122
|
-
|
|
123
|
-
cli.stage
|
|
124
|
-
end
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
end
|
data/spec/bard/cli/vim_spec.rb
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/cli"
|
|
3
|
-
|
|
4
|
-
describe "bard vim" do
|
|
5
|
-
let(:cli) { Bard::CLI.new }
|
|
6
|
-
|
|
7
|
-
before do
|
|
8
|
-
allow(cli).to receive(:exec)
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
describe "#vim" do
|
|
12
|
-
it "should have a vim command" do
|
|
13
|
-
expect(cli).to respond_to(:vim)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
it "should exec vim with git diff files by default" do
|
|
17
|
-
expect(cli).to receive(:exec).with("vim -p `(git diff master --name-only; git ls-files --others --exclude-standard) | grep -v '^app/assets/images/' | grep -v '^app/assets/stylesheets/' | while read f; do [ -f \"$f\" ] && ! file -b \"$f\" | grep -q \"binary\" && echo \"$f\"; done | tac`")
|
|
18
|
-
|
|
19
|
-
cli.vim
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it "should exec vim with specified branch" do
|
|
23
|
-
expect(cli).to receive(:exec).with("vim -p `(git diff develop --name-only; git ls-files --others --exclude-standard) | grep -v '^app/assets/images/' | grep -v '^app/assets/stylesheets/' | while read f; do [ -f \"$f\" ] && ! file -b \"$f\" | grep -q \"binary\" && echo \"$f\"; done | tac`")
|
|
24
|
-
|
|
25
|
-
cli.vim("develop")
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
data/spec/bard/command_spec.rb
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/command"
|
|
3
|
-
|
|
4
|
-
describe Bard::Command do
|
|
5
|
-
describe ".run" do
|
|
6
|
-
it "should run a command locally" do
|
|
7
|
-
expect(Open3).to receive(:capture3).with("ls -l").and_return(["output", "", 0])
|
|
8
|
-
Bard::Command.run "ls -l"
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
describe ".run!" do
|
|
13
|
-
it "should run a command locally" do
|
|
14
|
-
expect(Open3).to receive(:capture3).with("ls -l").and_return(["output", "", 0])
|
|
15
|
-
Bard::Command.run! "ls -l"
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "should raise an error if the command fails" do
|
|
19
|
-
expect(Open3).to receive(:capture3).with("ls -l").and_return(["output", "error", 1])
|
|
20
|
-
expect { Bard::Command.run! "ls -l" }.to raise_error(Bard::Command::Error)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
describe ".exec!" do
|
|
25
|
-
it "should exec a command locally" do
|
|
26
|
-
expect(Kernel).to receive(:exec).with("ls -l")
|
|
27
|
-
Bard::Command.exec! "ls -l"
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
data/spec/bard/copy_spec.rb
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/copy"
|
|
3
|
-
|
|
4
|
-
describe Bard::Copy do
|
|
5
|
-
let(:local) { double("local", key: :local, has_capability?: false) }
|
|
6
|
-
let(:production) { double("production", key: :production, has_capability?: true) }
|
|
7
|
-
|
|
8
|
-
around do |example|
|
|
9
|
-
original_handlers = Bard::Copy.instance_variable_get(:@handlers).dup
|
|
10
|
-
example.run
|
|
11
|
-
Bard::Copy.instance_variable_set(:@handlers, original_handlers)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
describe "auto-registration" do
|
|
15
|
-
it "registers handlers via inherited hook" do
|
|
16
|
-
handler = Class.new(Bard::Copy) do
|
|
17
|
-
def self.can_handle?(from, to) = true
|
|
18
|
-
def file = "copied"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
copy = handler.new("path", local, production, false)
|
|
22
|
-
expect(copy.file).to eq("copied")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
describe ".file" do
|
|
27
|
-
it "dispatches to the handler that can handle the pair" do
|
|
28
|
-
Class.new(Bard::Copy) do
|
|
29
|
-
def self.can_handle?(from, to) = true
|
|
30
|
-
def file = "file_copied"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
expect(Bard::Copy.file("db/data.sql.gz", from: local, to: production)).to eq("file_copied")
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
describe ".dir" do
|
|
38
|
-
it "dispatches to the handler that can handle the pair" do
|
|
39
|
-
Class.new(Bard::Copy) do
|
|
40
|
-
def self.can_handle?(from, to) = true
|
|
41
|
-
def dir = "dir_copied"
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
expect(Bard::Copy.dir("storage/", from: local, to: production)).to eq("dir_copied")
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
describe ".handler_for!" do
|
|
49
|
-
it "raises when no handler matches" do
|
|
50
|
-
expect {
|
|
51
|
-
Bard::Copy.file("file", from: local, to: local)
|
|
52
|
-
}.to raise_error(/No copy handler for local -> local/)
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
describe "#initialize" do
|
|
57
|
-
it "stores path, from, to, verbose" do
|
|
58
|
-
handler = Class.new(Bard::Copy) do
|
|
59
|
-
def self.can_handle?(from, to) = true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
copy = handler.new("db/data.sql.gz", local, production, true)
|
|
63
|
-
expect(copy.path).to eq("db/data.sql.gz")
|
|
64
|
-
expect(copy.from).to eq(local)
|
|
65
|
-
expect(copy.to).to eq(production)
|
|
66
|
-
expect(copy.verbose).to eq(true)
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/plugins/github_pages/strategy"
|
|
3
|
-
require "bard/plugins/github_pages"
|
|
4
|
-
|
|
5
|
-
describe Bard::DeployStrategy::GithubPages do
|
|
6
|
-
let(:config) { double("config", project_name: "testapp") }
|
|
7
|
-
|
|
8
|
-
def build_shell_for(target)
|
|
9
|
-
strategy = described_class.new(target)
|
|
10
|
-
strategy.instance_variable_set(:@sha, "abc123")
|
|
11
|
-
strategy.instance_variable_set(:@build_dir, "tmp/github-build-abc123")
|
|
12
|
-
strategy.instance_variable_set(:@port, 4321)
|
|
13
|
-
strategy.instance_variable_set(:@domain, strategy.send(:extract_domain))
|
|
14
|
-
|
|
15
|
-
captured = []
|
|
16
|
-
allow(strategy).to receive(:run!) { |cmd| captured << cmd }
|
|
17
|
-
allow(strategy).to receive(:system)
|
|
18
|
-
strategy.send(:build_site)
|
|
19
|
-
captured.join("\n")
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context "with no custom domain (project page under /<repo>/)" do
|
|
23
|
-
let(:target) do
|
|
24
|
-
Bard::Target.new(:production, config).tap { |t| t.github_pages(nil) }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "mirrors with --convert-links so the tree is relocatable under the subpath" do
|
|
28
|
-
expect(build_shell_for(target)).to match(/wget .*\s-k\s/)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "strips the localhost prefix wget bakes into un-crawled links" do
|
|
32
|
-
expect(build_shell_for(target))
|
|
33
|
-
.to include(%(sed -i "s#http://localhost:$PORT/#/#g"))
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "does not write a CNAME" do
|
|
37
|
-
expect(build_shell_for(target)).not_to match(/> CNAME/)
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
context "with a custom domain (served at the domain root)" do
|
|
42
|
-
let(:target) do
|
|
43
|
-
Bard::Target.new(:production, config).tap { |t| t.github_pages("example.com") }
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "does not add --convert-links" do
|
|
47
|
-
expect(build_shell_for(target)).not_to match(/wget .*\s-k\s/)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "does not run the localhost strip" do
|
|
51
|
-
expect(build_shell_for(target)).not_to include("localhost:$PORT/#")
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "writes the CNAME" do
|
|
55
|
-
expect(build_shell_for(target)).to match(/echo example\.com > CNAME/)
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
end
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/plugins/deploy/strategy"
|
|
3
|
-
require "bard/plugins/deploy/ssh_strategy"
|
|
4
|
-
|
|
5
|
-
describe Bard::DeployStrategy::SSH do
|
|
6
|
-
let(:config) { double("config", project_name: "testapp") }
|
|
7
|
-
let(:target) do
|
|
8
|
-
t = Bard::Target.new(:production, config)
|
|
9
|
-
t.ssh("deploy@example.com:22", path: "/app")
|
|
10
|
-
t
|
|
11
|
-
end
|
|
12
|
-
let(:strategy) { described_class.new(target) }
|
|
13
|
-
|
|
14
|
-
describe "#deploy" do
|
|
15
|
-
it "requires SSH capability" do
|
|
16
|
-
target_without_ssh = Bard::Target.new(:local, config)
|
|
17
|
-
strategy_without_ssh = described_class.new(target_without_ssh)
|
|
18
|
-
|
|
19
|
-
expect { strategy_without_ssh.deploy }
|
|
20
|
-
.to raise_error(/ssh capability not configured/)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "runs git pull on remote server" do
|
|
24
|
-
expect(target).to receive(:run!)
|
|
25
|
-
.with("git pull --ff-only origin master")
|
|
26
|
-
|
|
27
|
-
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
28
|
-
|
|
29
|
-
strategy.deploy
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "runs bin/setup on remote server" do
|
|
33
|
-
allow(target).to receive(:run!).with(/git pull/)
|
|
34
|
-
|
|
35
|
-
expect(target).to receive(:run!)
|
|
36
|
-
.with(/bin\/setup/)
|
|
37
|
-
|
|
38
|
-
strategy.deploy
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
it "pulls the given branch when one is specified" do
|
|
42
|
-
expect(target).to receive(:run!)
|
|
43
|
-
.with("git pull --ff-only origin main")
|
|
44
|
-
|
|
45
|
-
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
46
|
-
|
|
47
|
-
strategy.deploy(branch: "main")
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
context "with force: true" do
|
|
51
|
-
it "force-checks-out the given branch on the remote server" do
|
|
52
|
-
expect(target).to receive(:run!).with("git fetch origin feature-x").ordered
|
|
53
|
-
expect(target).to receive(:run!).with("git checkout -f origin/feature-x").ordered
|
|
54
|
-
|
|
55
|
-
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
56
|
-
|
|
57
|
-
strategy.deploy(branch: "feature-x", force: true)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
context "with clone" do
|
|
62
|
-
let(:local_target) { double("local") }
|
|
63
|
-
|
|
64
|
-
before do
|
|
65
|
-
allow(config).to receive(:[]).with(:local).and_return(local_target)
|
|
66
|
-
allow(Bard::Copy).to receive(:file)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "clones the repository, defaulting to master" do
|
|
70
|
-
expect(target).to receive(:run!)
|
|
71
|
-
.with("git clone --branch master git@github.com:botandrosedesign/testapp /app", home: true)
|
|
72
|
-
allow(target).to receive(:run!).with("bin/setup")
|
|
73
|
-
allow(target).to receive(:run!).with("bard setup")
|
|
74
|
-
|
|
75
|
-
strategy.deploy(clone: "testapp")
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it "copies master key from local" do
|
|
79
|
-
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
80
|
-
expect(Bard::Copy).to receive(:file)
|
|
81
|
-
.with("config/master.key", from: local_target, to: target)
|
|
82
|
-
allow(target).to receive(:run!).with("bin/setup")
|
|
83
|
-
allow(target).to receive(:run!).with("bard setup")
|
|
84
|
-
|
|
85
|
-
strategy.deploy(clone: "testapp")
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
it "runs bin/setup and bard setup" do
|
|
89
|
-
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
90
|
-
expect(target).to receive(:run!).with("bin/setup")
|
|
91
|
-
expect(target).to receive(:run!).with("bard setup")
|
|
92
|
-
|
|
93
|
-
strategy.deploy(clone: "testapp")
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "does not run git pull" do
|
|
97
|
-
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
98
|
-
allow(target).to receive(:run!).with("bin/setup")
|
|
99
|
-
allow(target).to receive(:run!).with("bard setup")
|
|
100
|
-
|
|
101
|
-
expect(target).not_to receive(:run!).with(/git pull/)
|
|
102
|
-
|
|
103
|
-
strategy.deploy(clone: "testapp")
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
it "clones the requested branch directly when provisioning from scratch" do
|
|
107
|
-
allow(target).to receive(:run!).with("bin/setup")
|
|
108
|
-
allow(target).to receive(:run!).with("bard setup")
|
|
109
|
-
|
|
110
|
-
expect(target).to receive(:run!)
|
|
111
|
-
.with("git clone --branch feature-x git@github.com:botandrosedesign/testapp /app", home: true)
|
|
112
|
-
expect(target).not_to receive(:run!).with(/git fetch/)
|
|
113
|
-
expect(target).not_to receive(:run!).with(/git checkout/)
|
|
114
|
-
|
|
115
|
-
strategy.deploy(clone: "testapp", branch: "feature-x")
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
describe "auto-registration" do
|
|
121
|
-
it "registers as :ssh strategy" do
|
|
122
|
-
expect(Bard::DeployStrategy[:ssh]).to eq(described_class)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
describe "integration with target" do
|
|
127
|
-
it "is the default strategy when SSH is configured" do
|
|
128
|
-
require "bard/plugins/deploy"
|
|
129
|
-
new_target = Bard::Target.new(:staging, config)
|
|
130
|
-
new_target.ssh("deploy@staging.example.com:22")
|
|
131
|
-
|
|
132
|
-
expect(new_target.deploy_strategy_instance).to be_a(described_class)
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/plugins/deploy/strategy"
|
|
3
|
-
|
|
4
|
-
describe Bard::DeployStrategy do
|
|
5
|
-
describe "auto-registration" do
|
|
6
|
-
it "registers strategies via inherited hook" do
|
|
7
|
-
# Define a test strategy
|
|
8
|
-
class Bard::DeployStrategy::TestStrategy < Bard::DeployStrategy
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
expect(Bard::DeployStrategy[:test_strategy]).to eq(Bard::DeployStrategy::TestStrategy)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "extracts strategy name from class name" do
|
|
15
|
-
class Bard::DeployStrategy::MyCustomStrategy < Bard::DeployStrategy
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
expect(Bard::DeployStrategy[:my_custom_strategy]).to eq(Bard::DeployStrategy::MyCustomStrategy)
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
it "allows retrieval of registered strategies" do
|
|
23
|
-
class Bard::DeployStrategy::RetrievalTest < Bard::DeployStrategy
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
strategy_class = Bard::DeployStrategy[:retrieval_test]
|
|
27
|
-
expect(strategy_class).to eq(Bard::DeployStrategy::RetrievalTest)
|
|
28
|
-
expect(strategy_class.superclass).to eq(Bard::DeployStrategy)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe ".strategies" do
|
|
33
|
-
it "returns a hash of all registered strategies" do
|
|
34
|
-
class Bard::DeployStrategy::Strategy1 < Bard::DeployStrategy
|
|
35
|
-
end
|
|
36
|
-
class Bard::DeployStrategy::Strategy2 < Bard::DeployStrategy
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
strategies = Bard::DeployStrategy.strategies
|
|
40
|
-
expect(strategies).to be_a(Hash)
|
|
41
|
-
expect(strategies[:strategy1]).to eq(Bard::DeployStrategy::Strategy1)
|
|
42
|
-
expect(strategies[:strategy2]).to eq(Bard::DeployStrategy::Strategy2)
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe ".[]" do
|
|
47
|
-
it "retrieves a strategy by symbol" do
|
|
48
|
-
class Bard::DeployStrategy::LookupTest < Bard::DeployStrategy
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
expect(Bard::DeployStrategy[:lookup_test]).to eq(Bard::DeployStrategy::LookupTest)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "returns nil for unknown strategies" do
|
|
55
|
-
expect(Bard::DeployStrategy[:unknown_strategy]).to be_nil
|
|
56
|
-
end
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
describe "#initialize" do
|
|
60
|
-
let(:target) { double("target") }
|
|
61
|
-
|
|
62
|
-
it "stores the target" do
|
|
63
|
-
strategy = described_class.new(target)
|
|
64
|
-
expect(strategy.target).to eq(target)
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
describe "#deploy" do
|
|
69
|
-
let(:target) { double("target") }
|
|
70
|
-
let(:strategy) { described_class.new(target) }
|
|
71
|
-
|
|
72
|
-
it "raises NotImplementedError" do
|
|
73
|
-
expect { strategy.deploy }.to raise_error(NotImplementedError)
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
describe "helper methods" do
|
|
78
|
-
let(:target) { double("target") }
|
|
79
|
-
let(:strategy) { described_class.new(target) }
|
|
80
|
-
|
|
81
|
-
describe "#run!" do
|
|
82
|
-
it "delegates to Bard::Command.run!" do
|
|
83
|
-
expect(Bard::Command).to receive(:run!).with("ls -l")
|
|
84
|
-
strategy.run!("ls -l")
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
describe "#run" do
|
|
89
|
-
it "delegates to Bard::Command.run" do
|
|
90
|
-
expect(Bard::Command).to receive(:run).with("ls -l")
|
|
91
|
-
strategy.run("ls -l")
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
describe "#system!" do
|
|
96
|
-
it "delegates to Kernel.system with error checking" do
|
|
97
|
-
expect(Kernel).to receive(:system).with("ls -l").and_return(true)
|
|
98
|
-
strategy.system!("ls -l")
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it "raises error if command fails" do
|
|
102
|
-
expect(Kernel).to receive(:system).with("false").and_return(false)
|
|
103
|
-
expect { strategy.system!("false") }.to raise_error(/Command failed/)
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "bard/target"
|
|
3
|
-
require "bard/plugins/deploy"
|
|
4
|
-
|
|
5
|
-
describe "Deploy strategy target methods" do
|
|
6
|
-
let(:config) { double("config", project_name: "testapp") }
|
|
7
|
-
let(:target) { Bard::Target.new(:production, config) }
|
|
8
|
-
|
|
9
|
-
describe "#deploy_strategy" do
|
|
10
|
-
it "returns nil if no strategy configured" do
|
|
11
|
-
expect(target.deploy_strategy).to be_nil
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "returns :ssh after ssh is configured via deploy_strategy_instance" do
|
|
15
|
-
target.ssh("deploy@example.com:22")
|
|
16
|
-
expect(target.deploy_strategy_instance).to be_a(Bard::DeployStrategy::SSH)
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
describe "#deploy_strategy_instance" do
|
|
21
|
-
it "defaults to SSH strategy when SSH capability is present" do
|
|
22
|
-
target.ssh("deploy@example.com:22")
|
|
23
|
-
instance = target.deploy_strategy_instance
|
|
24
|
-
expect(instance).to be_a(Bard::DeployStrategy::SSH)
|
|
25
|
-
expect(instance.target).to eq(target)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
it "raises error if no strategy configured and no SSH capability" do
|
|
29
|
-
expect { target.deploy_strategy_instance }
|
|
30
|
-
.to raise_error(/No deployment strategy configured/)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
it "raises error if strategy class not found" do
|
|
34
|
-
target.instance_variable_set(:@deploy_strategy, :unknown)
|
|
35
|
-
expect { target.deploy_strategy_instance }
|
|
36
|
-
.to raise_error(/Unknown deployment strategy: unknown/)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe "#strategy_options" do
|
|
41
|
-
it "returns empty hash if strategy not configured" do
|
|
42
|
-
options = target.strategy_options(:unknown)
|
|
43
|
-
expect(options).to eq({})
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|