bard 1.9.6 → 2.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/.github/workflows/ci.yml +2 -2
- data/CLAUDE.md +1 -1
- data/PLUGINS.md +31 -46
- data/bard.gemspec +2 -1
- data/features/ci.feature +1 -0
- data/features/data.feature +1 -0
- data/features/deploy.feature +1 -0
- data/features/deploy_git_workflow.feature +1 -0
- data/features/run.feature +1 -0
- data/features/step_definitions/bard_steps.rb +1 -0
- data/features/support/test_server.rb +3 -3
- data/lib/bard/cli.rb +9 -28
- data/lib/bard/command.rb +9 -88
- data/lib/bard/config.rb +38 -177
- data/lib/bard/copy.rb +28 -82
- data/lib/bard/plugins/data.rb +56 -0
- data/lib/bard/{ci → plugins/deploy/ci}/github_actions.rb +2 -2
- data/lib/bard/{ci → plugins/deploy/ci}/jenkins.rb +1 -1
- data/lib/bard/{ci → plugins/deploy/ci}/local.rb +1 -1
- data/lib/bard/{ci → plugins/deploy/ci}/runner.rb +3 -3
- data/lib/bard/{ci.rb → plugins/deploy/ci.rb} +1 -1
- data/lib/bard/plugins/deploy/ssh_strategy.rb +27 -0
- data/lib/bard/{deploy_strategy.rb → plugins/deploy/strategy.rb} +1 -4
- data/lib/bard/plugins/deploy.rb +240 -0
- data/lib/bard/{git.rb → plugins/git.rb} +6 -3
- data/lib/bard/{github.rb → plugins/github.rb} +2 -2
- data/lib/bard/{deploy_strategy/github_pages.rb → plugins/github_pages/strategy.rb} +3 -4
- data/lib/bard/plugins/github_pages.rb +11 -15
- data/lib/bard/plugins/hurt.rb +12 -4
- data/{install_files → lib/bard/plugins/install}/.github/dependabot.yml +2 -1
- data/{install_files → lib/bard/plugins/install}/.github/workflows/cache-ci.yml +1 -1
- data/{install_files → lib/bard/plugins/install}/.github/workflows/ci.yml +2 -2
- data/lib/bard/plugins/install.rb +7 -3
- data/lib/bard/plugins/open.rb +20 -0
- data/lib/bard/{ping.rb → plugins/ping/check.rb} +4 -4
- data/lib/bard/plugins/ping/target_methods.rb +23 -0
- data/lib/bard/plugins/ping.rb +8 -4
- data/lib/bard/plugins/run.rb +19 -0
- data/lib/bard/plugins/setup.rb +54 -0
- data/lib/bard/plugins/ssh/connection.rb +75 -0
- data/lib/bard/plugins/ssh/copy.rb +95 -0
- data/lib/bard/{ssh_server.rb → plugins/ssh/server.rb} +10 -42
- data/lib/bard/plugins/ssh/target_methods.rb +20 -0
- data/lib/bard/plugins/ssh.rb +10 -0
- data/lib/bard/plugins/url/target_methods.rb +23 -0
- data/lib/bard/plugins/url.rb +1 -0
- data/lib/bard/plugins/vim.rb +5 -4
- data/lib/bard/retryable.rb +25 -0
- data/lib/bard/target.rb +21 -230
- data/lib/bard/version.rb +1 -1
- data/lib/bard.rb +1 -3
- data/spec/acceptance/docker/Dockerfile +1 -1
- data/spec/bard/capability_spec.rb +8 -50
- data/spec/bard/ci/github_actions_spec.rb +1 -1
- data/spec/bard/ci/jenkins_spec.rb +1 -1
- data/spec/bard/ci/runner_spec.rb +3 -3
- data/spec/bard/ci_spec.rb +1 -1
- data/spec/bard/cli/ci_spec.rb +4 -23
- data/spec/bard/cli/data_spec.rb +7 -26
- data/spec/bard/cli/deploy_spec.rb +43 -40
- data/spec/bard/cli/hurt_spec.rb +2 -8
- data/spec/bard/cli/install_spec.rb +4 -10
- data/spec/bard/cli/master_key_spec.rb +5 -19
- data/spec/bard/cli/open_spec.rb +17 -35
- data/spec/bard/cli/ping_spec.rb +10 -25
- data/spec/bard/cli/run_spec.rb +10 -23
- data/spec/bard/cli/setup_spec.rb +10 -27
- data/spec/bard/cli/ssh_spec.rb +10 -25
- data/spec/bard/cli/stage_spec.rb +17 -32
- data/spec/bard/cli/vim_spec.rb +5 -11
- data/spec/bard/command_spec.rb +1 -10
- data/spec/bard/config_spec.rb +68 -116
- data/spec/bard/copy_spec.rb +54 -18
- data/spec/bard/deploy_strategy/ssh_spec.rb +65 -7
- data/spec/bard/deploy_strategy_spec.rb +1 -1
- data/spec/bard/dynamic_dsl_spec.rb +18 -98
- data/spec/bard/git_spec.rb +9 -5
- data/spec/bard/github_spec.rb +1 -1
- data/spec/bard/ping_spec.rb +5 -5
- data/spec/bard/ssh_copy_spec.rb +44 -0
- data/spec/bard/ssh_server_spec.rb +1 -98
- data/spec/bard/target_spec.rb +61 -108
- metadata +50 -124
- data/lib/bard/ci/retryable.rb +0 -27
- data/lib/bard/cli/ci.rb +0 -73
- data/lib/bard/cli/command.rb +0 -26
- data/lib/bard/cli/data.rb +0 -45
- data/lib/bard/cli/deploy.rb +0 -116
- data/lib/bard/cli/hurt.rb +0 -15
- data/lib/bard/cli/install.rb +0 -11
- data/lib/bard/cli/master_key.rb +0 -17
- data/lib/bard/cli/new.rb +0 -101
- data/lib/bard/cli/new_rails_template.rb +0 -197
- data/lib/bard/cli/open.rb +0 -18
- data/lib/bard/cli/ping.rb +0 -12
- data/lib/bard/cli/provision.rb +0 -34
- data/lib/bard/cli/run.rb +0 -26
- data/lib/bard/cli/setup.rb +0 -56
- data/lib/bard/cli/ssh.rb +0 -14
- data/lib/bard/cli/stage.rb +0 -35
- data/lib/bard/cli/vim.rb +0 -8
- data/lib/bard/default_config.rb +0 -35
- data/lib/bard/deploy_strategy/ssh.rb +0 -19
- data/lib/bard/deprecation.rb +0 -19
- data/lib/bard/github_pages.rb +0 -134
- data/lib/bard/plugin.rb +0 -100
- data/lib/bard/plugins/backup.rb +0 -19
- data/lib/bard/plugins/jenkins.rb +0 -6
- data/lib/bard/plugins/new.rb +0 -5
- data/lib/bard/plugins/provision.rb +0 -5
- data/lib/bard/provision/app.rb +0 -10
- data/lib/bard/provision/apt.rb +0 -16
- data/lib/bard/provision/authorizedkeys.rb +0 -25
- data/lib/bard/provision/data.rb +0 -27
- data/lib/bard/provision/deploy.rb +0 -10
- data/lib/bard/provision/http.rb +0 -16
- data/lib/bard/provision/logrotation.rb +0 -30
- data/lib/bard/provision/masterkey.rb +0 -18
- data/lib/bard/provision/mysql.rb +0 -22
- data/lib/bard/provision/passenger.rb +0 -37
- data/lib/bard/provision/repo.rb +0 -72
- data/lib/bard/provision/rvm.rb +0 -22
- data/lib/bard/provision/ssh.rb +0 -79
- data/lib/bard/provision/swapfile.rb +0 -23
- data/lib/bard/provision/user.rb +0 -42
- data/lib/bard/provision.rb +0 -16
- data/lib/bard/server.rb +0 -160
- data/spec/bard/cli/command_spec.rb +0 -50
- data/spec/bard/cli/new_spec.rb +0 -73
- data/spec/bard/cli/provision_spec.rb +0 -42
- data/spec/bard/deprecation_spec.rb +0 -281
- data/spec/bard/github_pages_spec.rb +0 -143
- data/spec/bard/plugin_spec.rb +0 -79
- data/spec/bard/provision/app_spec.rb +0 -33
- data/spec/bard/provision/apt_spec.rb +0 -39
- data/spec/bard/provision/authorizedkeys_spec.rb +0 -40
- data/spec/bard/provision/data_spec.rb +0 -54
- data/spec/bard/provision/deploy_spec.rb +0 -33
- data/spec/bard/provision/http_spec.rb +0 -57
- data/spec/bard/provision/logrotation_spec.rb +0 -34
- data/spec/bard/provision/masterkey_spec.rb +0 -63
- data/spec/bard/provision/mysql_spec.rb +0 -55
- data/spec/bard/provision/passenger_spec.rb +0 -81
- data/spec/bard/provision/repo_spec.rb +0 -208
- data/spec/bard/provision/rvm_spec.rb +0 -49
- data/spec/bard/provision/ssh_spec.rb +0 -242
- data/spec/bard/provision/swapfile_spec.rb +0 -33
- data/spec/bard/provision/user_spec.rb +0 -103
- data/spec/bard/provision_spec.rb +0 -28
- data/spec/bard/server_spec.rb +0 -127
- /data/lib/bard/{ci → plugins/deploy/ci}/state.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/apt_dependencies.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/ci +0 -0
- /data/{install_files → lib/bard/plugins/install}/setup +0 -0
- /data/{install_files → lib/bard/plugins/install}/specified_bundler.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/specified_ruby.rb +0 -0
data/spec/bard/cli/stage_spec.rb
CHANGED
|
@@ -1,24 +1,13 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "bard/cli"
|
|
3
|
-
require "bard/cli/stage"
|
|
4
|
-
require "thor"
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@config = nil
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
describe Bard::CLI::Stage do
|
|
18
|
-
let(:staging_server) { double("staging") }
|
|
19
|
-
let(:servers) { { production: double("production"), staging: staging_server } }
|
|
20
|
-
let(:config) { double("config", servers: servers) }
|
|
21
|
-
let(:cli) { TestStageCLI.new }
|
|
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 }
|
|
22
11
|
|
|
23
12
|
before do
|
|
24
13
|
allow(cli).to receive(:config).and_return(config)
|
|
@@ -31,6 +20,7 @@ describe Bard::CLI::Stage do
|
|
|
31
20
|
allow(cli).to receive(:yellow).and_return("")
|
|
32
21
|
allow(Bard::Git).to receive(:current_branch).and_return("main")
|
|
33
22
|
allow(config).to receive(:[]).with(:staging).and_return(staging_server)
|
|
23
|
+
allow(config).to receive(:[]).with(:production).and_return(production_server)
|
|
34
24
|
end
|
|
35
25
|
|
|
36
26
|
describe "#stage" do
|
|
@@ -41,7 +31,7 @@ describe Bard::CLI::Stage do
|
|
|
41
31
|
context "when production server is defined" do
|
|
42
32
|
it "pushes branch and stages it" do
|
|
43
33
|
expect(cli).to receive(:run!).with("git push -u origin main", verbose: true)
|
|
44
|
-
expect(
|
|
34
|
+
expect(staging_strategy).to receive(:deploy)
|
|
45
35
|
expect(cli).to receive(:ping).with(:staging)
|
|
46
36
|
|
|
47
37
|
cli.stage
|
|
@@ -49,7 +39,7 @@ describe Bard::CLI::Stage do
|
|
|
49
39
|
|
|
50
40
|
it "accepts custom branch" do
|
|
51
41
|
expect(cli).to receive(:run!).with("git push -u origin develop", verbose: true)
|
|
52
|
-
expect(
|
|
42
|
+
expect(staging_strategy).to receive(:deploy)
|
|
53
43
|
|
|
54
44
|
cli.stage("develop")
|
|
55
45
|
end
|
|
@@ -57,26 +47,21 @@ describe Bard::CLI::Stage do
|
|
|
57
47
|
|
|
58
48
|
context "when staging target has a deploy strategy" do
|
|
59
49
|
let(:strategy_instance) { double("strategy") }
|
|
60
|
-
let(:staging_server) { double("staging", deploy_strategy: :fake) }
|
|
50
|
+
let(:staging_server) { double("staging", deploy_strategy: :fake, deploy_strategy_instance: strategy_instance) }
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
allow(staging_server).to receive(:respond_to?).with(:deploy_strategy).and_return(true)
|
|
64
|
-
allow(staging_server).to receive(:deploy_strategy_instance).and_return(strategy_instance)
|
|
65
|
-
allow(cli).to receive(:require).with("bard/deploy_strategy/fake").and_return(true)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "uses the deploy strategy instead of SSH" do
|
|
52
|
+
it "uses the deploy strategy" do
|
|
69
53
|
expect(cli).to receive(:run!).with("git push -u origin main", verbose: true)
|
|
70
54
|
expect(strategy_instance).to receive(:deploy)
|
|
71
|
-
expect(staging_server).not_to receive(:run!)
|
|
72
55
|
expect(cli).to receive(:ping).with(:staging)
|
|
73
56
|
|
|
74
57
|
cli.stage
|
|
75
58
|
end
|
|
76
59
|
end
|
|
77
60
|
|
|
78
|
-
context "when production
|
|
79
|
-
|
|
61
|
+
context "when production target is equivalent to staging" do
|
|
62
|
+
before do
|
|
63
|
+
allow(config).to receive(:[]).with(:production).and_return(staging_server)
|
|
64
|
+
end
|
|
80
65
|
|
|
81
66
|
it "raises an error" do
|
|
82
67
|
expect { cli.stage }.to raise_error(Thor::Error, /bard stage.*is disabled/)
|
|
@@ -94,4 +79,4 @@ describe Bard::CLI::Stage do
|
|
|
94
79
|
end
|
|
95
80
|
end
|
|
96
81
|
end
|
|
97
|
-
end
|
|
82
|
+
end
|
data/spec/bard/cli/vim_spec.rb
CHANGED
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "bard/cli"
|
|
3
|
-
require "bard/cli/vim"
|
|
4
|
-
require "thor"
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
Bard::CLI
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
describe Bard::CLI::Vim do
|
|
11
|
-
let(:cli) { TestVimCLI.new }
|
|
4
|
+
describe "bard vim" do
|
|
5
|
+
let(:cli) { Bard::CLI.new }
|
|
12
6
|
|
|
13
7
|
before do
|
|
14
|
-
|
|
8
|
+
allow(cli).to receive(:exec)
|
|
15
9
|
end
|
|
16
10
|
|
|
17
11
|
describe "#vim" do
|
|
@@ -20,13 +14,13 @@ describe Bard::CLI::Vim do
|
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
it "should exec vim with git diff files by default" do
|
|
23
|
-
|
|
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`")
|
|
24
18
|
|
|
25
19
|
cli.vim
|
|
26
20
|
end
|
|
27
21
|
|
|
28
22
|
it "should exec vim with specified branch" do
|
|
29
|
-
|
|
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`")
|
|
30
24
|
|
|
31
25
|
cli.vim("develop")
|
|
32
26
|
end
|
data/spec/bard/command_spec.rb
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "bard/command"
|
|
3
|
-
require "shellwords"
|
|
4
3
|
|
|
5
4
|
describe Bard::Command do
|
|
6
|
-
let(:remote) { double("remote", to_sym: :remote, ssh: true, env: nil, path: "/path/to", ssh_key: nil, ssh_uri: "user@example.com", gateway: nil) }
|
|
7
|
-
|
|
8
5
|
describe ".run" do
|
|
9
6
|
it "should run a command locally" do
|
|
10
7
|
expect(Open3).to receive(:capture3).with("ls -l").and_return(["output", "", 0])
|
|
11
8
|
Bard::Command.run "ls -l"
|
|
12
9
|
end
|
|
13
|
-
|
|
14
|
-
it "should run a command on a remote server" do
|
|
15
|
-
expected_cmd = "ssh -tt -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR user@example.com #{Shellwords.shellescape("cd /path/to && ls -l")}"
|
|
16
|
-
expect(Open3).to receive(:capture3).with(expected_cmd).and_return(["output", "", 0])
|
|
17
|
-
Bard::Command.run "ls -l", on: remote
|
|
18
|
-
end
|
|
19
10
|
end
|
|
20
11
|
|
|
21
12
|
describe ".run!" do
|
|
@@ -32,7 +23,7 @@ describe Bard::Command do
|
|
|
32
23
|
|
|
33
24
|
describe ".exec!" do
|
|
34
25
|
it "should exec a command locally" do
|
|
35
|
-
|
|
26
|
+
expect(Kernel).to receive(:exec).with("ls -l")
|
|
36
27
|
Bard::Command.exec! "ls -l"
|
|
37
28
|
end
|
|
38
29
|
end
|
data/spec/bard/config_spec.rb
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
require "bard/config"
|
|
2
|
+
require "bard/plugins/ssh/target_methods"
|
|
3
|
+
require "bard/plugins/data"
|
|
4
|
+
require "bard/plugins/github_pages"
|
|
2
5
|
|
|
3
6
|
describe Bard::Config do
|
|
7
|
+
describe ".detect_project_name" do
|
|
8
|
+
let(:tmpdir) { Dir.mktmpdir("bard-detect-test") }
|
|
9
|
+
after { FileUtils.rm_rf(tmpdir) }
|
|
10
|
+
|
|
11
|
+
def init_repo(path)
|
|
12
|
+
FileUtils.mkdir_p(path)
|
|
13
|
+
Dir.chdir(path) do
|
|
14
|
+
system("git init -q")
|
|
15
|
+
system("git commit --allow-empty -q -m init")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "returns the repo dir basename when run from the main checkout" do
|
|
20
|
+
repo = File.join(tmpdir, "myproject")
|
|
21
|
+
init_repo(repo)
|
|
22
|
+
|
|
23
|
+
Dir.chdir(repo) do
|
|
24
|
+
expect(described_class.detect_project_name).to eq("myproject")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it "returns the main repo basename when run from a sibling worktree" do
|
|
29
|
+
repo = File.join(tmpdir, "myproject")
|
|
30
|
+
init_repo(repo)
|
|
31
|
+
Dir.chdir(repo) { system("git worktree add -q ../wt-feature -b feature") }
|
|
32
|
+
|
|
33
|
+
Dir.chdir(File.join(tmpdir, "wt-feature")) do
|
|
34
|
+
expect(described_class.detect_project_name).to eq("myproject")
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "returns the main repo basename when run from a nested worktree" do
|
|
39
|
+
repo = File.join(tmpdir, "myproject")
|
|
40
|
+
init_repo(repo)
|
|
41
|
+
Dir.chdir(repo) { system("git worktree add -q tmp/worktrees/wt-feature -b feature") }
|
|
42
|
+
|
|
43
|
+
Dir.chdir(File.join(repo, "tmp/worktrees/wt-feature")) do
|
|
44
|
+
expect(described_class.detect_project_name).to eq("myproject")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
4
49
|
context "empty" do
|
|
5
50
|
subject { described_class.new("tracker") }
|
|
6
51
|
|
|
@@ -10,15 +55,22 @@ describe Bard::Config do
|
|
|
10
55
|
end
|
|
11
56
|
end
|
|
12
57
|
|
|
13
|
-
describe "#
|
|
14
|
-
it "is prefilled with
|
|
15
|
-
expect(subject.
|
|
58
|
+
describe "#targets" do
|
|
59
|
+
it "is prefilled with default targets" do
|
|
60
|
+
expect(subject.targets.keys).to eq %i[local gubs ci staging production]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "creates Target instances for defaults" do
|
|
64
|
+
subject.targets.each_value do |target|
|
|
65
|
+
expect(target).to be_a(Bard::Target)
|
|
66
|
+
end
|
|
16
67
|
end
|
|
17
68
|
end
|
|
18
69
|
|
|
19
70
|
describe "#[]" do
|
|
20
|
-
it "
|
|
71
|
+
it "defines a default production target equivalent to staging" do
|
|
21
72
|
expect(subject[:production]).to eq subject[:staging]
|
|
73
|
+
expect(subject[:production]).not_to equal subject[:staging]
|
|
22
74
|
end
|
|
23
75
|
end
|
|
24
76
|
|
|
@@ -27,26 +79,16 @@ describe Bard::Config do
|
|
|
27
79
|
expect(subject.data).to eq []
|
|
28
80
|
end
|
|
29
81
|
end
|
|
30
|
-
|
|
31
|
-
describe "#backup" do
|
|
32
|
-
it "returns a BackupConfig with bard enabled by default" do
|
|
33
|
-
backup = subject.backup
|
|
34
|
-
expect(backup).to be_a(Bard::BackupConfig)
|
|
35
|
-
expect(backup.bard?).to eq true
|
|
36
|
-
expect(backup.destinations).to be_empty
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
82
|
end
|
|
40
83
|
|
|
41
84
|
context "with production definition" do
|
|
42
85
|
subject { described_class.new("tracker", source: <<~SOURCE) }
|
|
43
|
-
|
|
86
|
+
target :production do
|
|
44
87
|
ssh "www@ssh.botandrose.com:22022"
|
|
45
|
-
|
|
88
|
+
url "tracker.botandrose.com"
|
|
46
89
|
end
|
|
47
90
|
|
|
48
91
|
data "public/system", "public/ckeditor"
|
|
49
|
-
backup false
|
|
50
92
|
SOURCE
|
|
51
93
|
|
|
52
94
|
describe "#project_name" do
|
|
@@ -55,18 +97,18 @@ describe Bard::Config do
|
|
|
55
97
|
end
|
|
56
98
|
end
|
|
57
99
|
|
|
58
|
-
describe "#
|
|
59
|
-
it "contains the defined
|
|
60
|
-
expect(subject.
|
|
100
|
+
describe "#targets" do
|
|
101
|
+
it "contains the defined target" do
|
|
102
|
+
expect(subject.targets.keys).to eq %i[local gubs ci staging production]
|
|
61
103
|
end
|
|
62
104
|
end
|
|
63
105
|
|
|
64
|
-
describe "#
|
|
106
|
+
describe "#target" do
|
|
65
107
|
it "can overwrite existing definition" do
|
|
66
|
-
subject.
|
|
108
|
+
subject.target :staging do
|
|
67
109
|
ssh "www@tracker-staging.botandrose.com:22022"
|
|
68
110
|
end
|
|
69
|
-
expect(subject[:staging].
|
|
111
|
+
expect(subject[:staging].server.to_s).to eq "www@tracker-staging.botandrose.com:22022"
|
|
70
112
|
end
|
|
71
113
|
end
|
|
72
114
|
|
|
@@ -75,89 +117,6 @@ describe Bard::Config do
|
|
|
75
117
|
expect(subject.data).to eq ["public/system", "public/ckeditor"]
|
|
76
118
|
end
|
|
77
119
|
end
|
|
78
|
-
|
|
79
|
-
describe "#backup" do
|
|
80
|
-
it "returns the backup setting" do
|
|
81
|
-
expect(subject.backup).to be_disabled
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
context "with new backup block syntax" do
|
|
87
|
-
describe "#backup with bard directive" do
|
|
88
|
-
subject { described_class.new("test", source: "backup { bard }") }
|
|
89
|
-
|
|
90
|
-
it "returns a BackupConfig with bard enabled" do
|
|
91
|
-
backup = subject.backup
|
|
92
|
-
expect(backup).to be_a(Bard::BackupConfig)
|
|
93
|
-
expect(backup.bard?).to eq true
|
|
94
|
-
expect(backup.destinations).to be_empty
|
|
95
|
-
expect(backup.self_managed?).to eq false
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
describe "#backup with s3 directive" do
|
|
100
|
-
subject { described_class.new("test", source: "backup { s3 :primary, path: 'bucket/path' }") }
|
|
101
|
-
|
|
102
|
-
it "returns a BackupConfig with s3 destination" do
|
|
103
|
-
backup = subject.backup
|
|
104
|
-
expect(backup).to be_a(Bard::BackupConfig)
|
|
105
|
-
expect(backup.bard?).to eq false
|
|
106
|
-
expect(backup.destinations.length).to eq 1
|
|
107
|
-
expect(backup.self_managed?).to eq true
|
|
108
|
-
|
|
109
|
-
dest = backup.destinations.first
|
|
110
|
-
expect(dest[:name]).to eq :primary
|
|
111
|
-
expect(dest[:type]).to eq :s3
|
|
112
|
-
expect(dest[:path]).to eq 'bucket/path'
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
describe "#backup with both bard and s3 directives" do
|
|
117
|
-
subject { described_class.new("test", source: "backup { bard; s3 :custom, path: 'bucket/path' }") }
|
|
118
|
-
|
|
119
|
-
it "returns a BackupConfig with bard and s3 destination" do
|
|
120
|
-
backup = subject.backup
|
|
121
|
-
expect(backup).to be_a(Bard::BackupConfig)
|
|
122
|
-
expect(backup.bard?).to eq true
|
|
123
|
-
expect(backup.destinations.length).to eq 1
|
|
124
|
-
expect(backup.self_managed?).to eq true
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
describe "#backup with multiple s3 destinations" do
|
|
129
|
-
subject do
|
|
130
|
-
described_class.new("test", source: <<~SOURCE)
|
|
131
|
-
backup do
|
|
132
|
-
s3 :primary, path: 'bucket1/path'
|
|
133
|
-
s3 :secondary, path: 'bucket2/path'
|
|
134
|
-
end
|
|
135
|
-
SOURCE
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
it "returns a BackupConfig with multiple destinations" do
|
|
139
|
-
backup = subject.backup
|
|
140
|
-
expect(backup).to be_a(Bard::BackupConfig)
|
|
141
|
-
expect(backup.bard?).to eq false
|
|
142
|
-
expect(backup.destinations.length).to eq 2
|
|
143
|
-
expect(backup.self_managed?).to eq true
|
|
144
|
-
|
|
145
|
-
expect(backup.destinations[0][:name]).to eq :primary
|
|
146
|
-
expect(backup.destinations[1][:name]).to eq :secondary
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
context "with target overriding default server" do
|
|
152
|
-
subject { described_class.new("tracker", source: <<~SOURCE) }
|
|
153
|
-
target :staging do
|
|
154
|
-
ssh false
|
|
155
|
-
end
|
|
156
|
-
SOURCE
|
|
157
|
-
|
|
158
|
-
it "replaces the default Server with a Target" do
|
|
159
|
-
expect(subject[:staging]).to be_a(Bard::Target)
|
|
160
|
-
end
|
|
161
120
|
end
|
|
162
121
|
|
|
163
122
|
context "with remove_target" do
|
|
@@ -172,27 +131,20 @@ describe Bard::Config do
|
|
|
172
131
|
staging = subject[:staging]
|
|
173
132
|
expect(staging).to be_a(Bard::Target)
|
|
174
133
|
expect(staging.ssh.to_s).to eq "deploy@new-host.com"
|
|
175
|
-
expect(staging.
|
|
134
|
+
expect(staging.url).to eq "https://new-host.com"
|
|
176
135
|
end
|
|
177
136
|
end
|
|
178
137
|
|
|
179
138
|
context "with github_pages directive" do
|
|
180
139
|
subject { described_class.new("test", source: "github_pages 'example.com'") }
|
|
181
140
|
|
|
182
|
-
describe "#
|
|
183
|
-
it "
|
|
184
|
-
expect(subject.backup).to be_disabled
|
|
185
|
-
end
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
describe "#server" do
|
|
189
|
-
it "creates a production server with github_pages enabled" do
|
|
141
|
+
describe "#target" do
|
|
142
|
+
it "creates a production target with github_pages enabled" do
|
|
190
143
|
production = subject[:production]
|
|
191
144
|
expect(production).not_to be_nil
|
|
192
145
|
expect(production.github_pages).to eq "example.com"
|
|
193
|
-
expect(production.ssh).to
|
|
146
|
+
expect(production.ssh).to be_nil
|
|
194
147
|
end
|
|
195
148
|
end
|
|
196
149
|
end
|
|
197
150
|
end
|
|
198
|
-
|
data/spec/bard/copy_spec.rb
CHANGED
|
@@ -2,32 +2,68 @@ require "spec_helper"
|
|
|
2
2
|
require "bard/copy"
|
|
3
3
|
|
|
4
4
|
describe Bard::Copy do
|
|
5
|
-
let(:
|
|
6
|
-
let(:
|
|
5
|
+
let(:local) { double("local", key: :local, has_capability?: false) }
|
|
6
|
+
let(:production) { double("production", key: :production, has_capability?: true) }
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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")
|
|
12
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
|
|
13
32
|
|
|
14
|
-
|
|
15
|
-
expect(Bard::Command).to receive(:run!).with("scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR path/to/file user@example.com:/path/to/file", verbose: false)
|
|
16
|
-
Bard::Copy.file "path/to/file", from: local, to: production
|
|
33
|
+
expect(Bard::Copy.file("db/data.sql.gz", from: local, to: production)).to eq("file_copied")
|
|
17
34
|
end
|
|
18
35
|
end
|
|
19
36
|
|
|
20
|
-
|
|
21
|
-
it "
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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")
|
|
25
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
|
|
26
61
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
expect(
|
|
30
|
-
|
|
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)
|
|
31
67
|
end
|
|
32
68
|
end
|
|
33
69
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
|
-
require "bard/
|
|
3
|
-
require "bard/
|
|
2
|
+
require "bard/plugins/deploy/strategy"
|
|
3
|
+
require "bard/plugins/deploy/ssh_strategy"
|
|
4
4
|
|
|
5
5
|
describe Bard::DeployStrategy::SSH do
|
|
6
6
|
let(:config) { double("config", project_name: "testapp") }
|
|
@@ -17,12 +17,12 @@ describe Bard::DeployStrategy::SSH do
|
|
|
17
17
|
strategy_without_ssh = described_class.new(target_without_ssh)
|
|
18
18
|
|
|
19
19
|
expect { strategy_without_ssh.deploy }
|
|
20
|
-
.to raise_error(/
|
|
20
|
+
.to raise_error(/ssh capability not configured/)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "runs git pull on remote server" do
|
|
24
24
|
expect(target).to receive(:run!)
|
|
25
|
-
.with(
|
|
25
|
+
.with("git pull --ff-only origin master")
|
|
26
26
|
|
|
27
27
|
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
28
28
|
|
|
@@ -42,12 +42,69 @@ describe Bard::DeployStrategy::SSH do
|
|
|
42
42
|
target.instance_variable_set(:@branch, "main")
|
|
43
43
|
|
|
44
44
|
expect(target).to receive(:run!)
|
|
45
|
-
.with(
|
|
45
|
+
.with("git pull --ff-only origin main")
|
|
46
46
|
|
|
47
47
|
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
48
48
|
|
|
49
49
|
strategy.deploy
|
|
50
50
|
end
|
|
51
|
+
|
|
52
|
+
context "with force: true" do
|
|
53
|
+
it "force-checks-out the given branch on the remote server" do
|
|
54
|
+
expect(target).to receive(:run!).with("git fetch origin feature-x").ordered
|
|
55
|
+
expect(target).to receive(:run!).with("git checkout -f origin/feature-x").ordered
|
|
56
|
+
|
|
57
|
+
allow(target).to receive(:run!).with(/bin\/setup/)
|
|
58
|
+
|
|
59
|
+
strategy.deploy(branch: "feature-x", force: true)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context "with clone" do
|
|
64
|
+
let(:local_target) { double("local") }
|
|
65
|
+
|
|
66
|
+
before do
|
|
67
|
+
allow(config).to receive(:[]).with(:local).and_return(local_target)
|
|
68
|
+
allow(Bard::Copy).to receive(:file)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "clones the repository" do
|
|
72
|
+
expect(target).to receive(:run!)
|
|
73
|
+
.with("git clone git@github.com:botandrosedesign/testapp /app", home: true)
|
|
74
|
+
allow(target).to receive(:run!).with("bin/setup")
|
|
75
|
+
allow(target).to receive(:run!).with("bard setup")
|
|
76
|
+
|
|
77
|
+
strategy.deploy(clone: "testapp")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "copies master key from local" do
|
|
81
|
+
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
82
|
+
expect(Bard::Copy).to receive(:file)
|
|
83
|
+
.with("config/master.key", from: local_target, to: target)
|
|
84
|
+
allow(target).to receive(:run!).with("bin/setup")
|
|
85
|
+
allow(target).to receive(:run!).with("bard setup")
|
|
86
|
+
|
|
87
|
+
strategy.deploy(clone: "testapp")
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "runs bin/setup and bard setup" do
|
|
91
|
+
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
92
|
+
expect(target).to receive(:run!).with("bin/setup")
|
|
93
|
+
expect(target).to receive(:run!).with("bard setup")
|
|
94
|
+
|
|
95
|
+
strategy.deploy(clone: "testapp")
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "does not run git pull" do
|
|
99
|
+
allow(target).to receive(:run!).with(/git clone/, home: true)
|
|
100
|
+
allow(target).to receive(:run!).with("bin/setup")
|
|
101
|
+
allow(target).to receive(:run!).with("bard setup")
|
|
102
|
+
|
|
103
|
+
expect(target).not_to receive(:run!).with(/git pull/)
|
|
104
|
+
|
|
105
|
+
strategy.deploy(clone: "testapp")
|
|
106
|
+
end
|
|
107
|
+
end
|
|
51
108
|
end
|
|
52
109
|
|
|
53
110
|
describe "auto-registration" do
|
|
@@ -57,11 +114,12 @@ describe Bard::DeployStrategy::SSH do
|
|
|
57
114
|
end
|
|
58
115
|
|
|
59
116
|
describe "integration with target" do
|
|
60
|
-
it "is
|
|
117
|
+
it "is the default strategy when SSH is configured" do
|
|
118
|
+
require "bard/plugins/deploy"
|
|
61
119
|
new_target = Bard::Target.new(:staging, config)
|
|
62
120
|
new_target.ssh("deploy@staging.example.com:22")
|
|
63
121
|
|
|
64
|
-
expect(new_target.
|
|
122
|
+
expect(new_target.deploy_strategy_instance).to be_a(described_class)
|
|
65
123
|
end
|
|
66
124
|
end
|
|
67
125
|
end
|