bard 2.0.0.beta → 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 +6 -1
- data/CLAUDE.md +76 -0
- data/MIGRATION_GUIDE.md +24 -9
- data/PLUGINS.md +99 -0
- data/README.md +14 -6
- data/Rakefile +3 -1
- data/bard.gemspec +2 -1
- data/cucumber.yml +1 -0
- data/features/ci.feature +63 -0
- data/features/data.feature +13 -0
- data/features/deploy.feature +14 -0
- data/features/deploy_git_workflow.feature +89 -0
- data/features/run.feature +14 -0
- data/features/step_definitions/bard_steps.rb +136 -0
- data/features/support/bard-coverage +16 -0
- data/features/support/env.rb +14 -39
- data/features/support/test_server.rb +216 -0
- data/lib/bard/cli.rb +14 -31
- data/lib/bard/command.rb +10 -69
- data/lib/bard/config.rb +40 -183
- data/lib/bard/copy.rb +28 -103
- data/lib/bard/plugins/data.rb +56 -0
- data/lib/bard/{ci → plugins/deploy/ci}/github_actions.rb +3 -4
- data/lib/bard/plugins/deploy/ci/jenkins.rb +176 -0
- data/lib/bard/{ci → plugins/deploy/ci}/local.rb +7 -7
- data/lib/bard/{ci → plugins/deploy/ci}/runner.rb +38 -4
- data/lib/bard/plugins/deploy/ci.rb +38 -0
- data/lib/bard/plugins/deploy/ssh_strategy.rb +27 -0
- data/lib/bard/{deploy_strategy.rb → plugins/deploy/strategy.rb} +1 -1
- 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} +4 -6
- data/lib/bard/{deploy_strategy/github_pages.rb → plugins/github_pages/strategy.rb} +13 -6
- data/lib/bard/plugins/github_pages.rb +30 -0
- data/lib/bard/plugins/hurt.rb +13 -0
- 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 +9 -0
- 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 +10 -0
- 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} +17 -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 +6 -0
- data/lib/bard/retryable.rb +25 -0
- data/lib/bard/secrets.rb +10 -0
- data/lib/bard/target.rb +27 -185
- data/lib/bard/version.rb +1 -1
- data/lib/bard.rb +1 -3
- data/spec/acceptance/docker/Dockerfile +3 -2
- data/spec/bard/capability_spec.rb +8 -50
- data/spec/bard/ci/github_actions_spec.rb +117 -14
- data/spec/bard/ci/jenkins_spec.rb +139 -0
- data/spec/bard/ci/runner_spec.rb +61 -0
- data/spec/bard/ci_spec.rb +1 -1
- data/spec/bard/cli/ci_spec.rb +34 -27
- data/spec/bard/cli/data_spec.rb +7 -26
- data/spec/bard/cli/deploy_spec.rb +87 -46
- data/spec/bard/cli/hurt_spec.rb +3 -9
- data/spec/bard/cli/install_spec.rb +5 -11
- data/spec/bard/cli/master_key_spec.rb +5 -19
- data/spec/bard/cli/open_spec.rb +14 -30
- data/spec/bard/cli/ping_spec.rb +8 -23
- data/spec/bard/cli/run_spec.rb +27 -21
- 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 +28 -23
- data/spec/bard/cli/vim_spec.rb +3 -9
- data/spec/bard/command_spec.rb +1 -8
- data/spec/bard/config_spec.rb +78 -98
- 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 +2 -2
- data/spec/bard/ping_spec.rb +5 -5
- data/spec/bard/ssh_copy_spec.rb +44 -0
- data/spec/bard/ssh_server_spec.rb +8 -101
- data/spec/bard/target_spec.rb +66 -109
- data/spec/spec_helper.rb +6 -1
- metadata +79 -143
- data/README.rdoc +0 -15
- data/features/bard_check.feature +0 -94
- data/features/bard_deploy.feature +0 -18
- data/features/bard_pull.feature +0 -112
- data/features/bard_push.feature +0 -112
- data/features/podman_testcontainers.feature +0 -16
- data/features/step_definitions/check_steps.rb +0 -47
- data/features/step_definitions/git_steps.rb +0 -73
- data/features/step_definitions/global_steps.rb +0 -56
- data/features/step_definitions/podman_steps.rb +0 -23
- data/features/step_definitions/rails_steps.rb +0 -44
- data/features/step_definitions/submodule_steps.rb +0 -110
- data/features/support/grit_ext.rb +0 -13
- data/features/support/io.rb +0 -32
- data/features/support/podman.rb +0 -153
- data/lib/bard/ci/jenkins.rb +0 -105
- data/lib/bard/ci/retryable.rb +0 -27
- data/lib/bard/ci.rb +0 -50
- data/lib/bard/cli/ci.rb +0 -66
- data/lib/bard/cli/command.rb +0 -26
- data/lib/bard/cli/data.rb +0 -45
- data/lib/bard/cli/deploy.rb +0 -85
- data/lib/bard/cli/hurt.rb +0 -20
- data/lib/bard/cli/install.rb +0 -16
- 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 -22
- data/lib/bard/cli/ping.rb +0 -18
- data/lib/bard/cli/provision.rb +0 -34
- data/lib/bard/cli/run.rb +0 -24
- data/lib/bard/cli/setup.rb +0 -56
- data/lib/bard/cli/ssh.rb +0 -14
- data/lib/bard/cli/stage.rb +0 -27
- data/lib/bard/cli/vim.rb +0 -13
- data/lib/bard/default_config.rb +0 -35
- data/lib/bard/deploy_strategy/ssh.rb +0 -19
- data/lib/bard/github_pages.rb +0 -134
- 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 -72
- data/lib/bard/provision/swapfile.rb +0 -21
- data/lib/bard/provision/user.rb +0 -42
- data/lib/bard/provision.rb +0 -16
- data/lib/bard/server.rb +0 -117
- 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/github_pages_spec.rb +0 -143
- 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 -229
- data/spec/bard/provision/swapfile_spec.rb +0 -32
- 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/ssh_spec.rb
CHANGED
|
@@ -1,27 +1,14 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "bard/cli"
|
|
3
|
-
require "bard/cli/ssh"
|
|
4
|
-
require "thor"
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def initialize
|
|
12
|
-
super
|
|
13
|
-
@config = {}
|
|
14
|
-
@options = {}
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe Bard::CLI::SSH do
|
|
19
|
-
let(:server) { double("server") }
|
|
20
|
-
let(:config) { { production: server } }
|
|
21
|
-
let(:cli) { TestSSHCLI.new }
|
|
4
|
+
describe "bard ssh" do
|
|
5
|
+
let(:target) { double("target") }
|
|
6
|
+
let(:config) { { production: target } }
|
|
7
|
+
let(:cli) { Bard::CLI.new }
|
|
22
8
|
|
|
23
9
|
before do
|
|
24
10
|
allow(cli).to receive(:config).and_return(config)
|
|
11
|
+
allow(cli).to receive(:options).and_return({ home: false })
|
|
25
12
|
end
|
|
26
13
|
|
|
27
14
|
describe "#ssh" do
|
|
@@ -29,27 +16,25 @@ describe Bard::CLI::SSH do
|
|
|
29
16
|
expect(cli).to respond_to(:ssh)
|
|
30
17
|
end
|
|
31
18
|
|
|
32
|
-
it "should execute shell on production
|
|
33
|
-
|
|
34
|
-
expect(server).to receive(:exec!).with("exec $SHELL -l", home: false)
|
|
19
|
+
it "should execute shell on production target by default" do
|
|
20
|
+
expect(target).to receive(:exec!).with("exec $SHELL -l", home: false)
|
|
35
21
|
|
|
36
22
|
cli.ssh
|
|
37
23
|
end
|
|
38
24
|
|
|
39
25
|
it "should execute shell with home option when specified" do
|
|
40
26
|
allow(cli).to receive(:options).and_return({ home: true })
|
|
41
|
-
expect(
|
|
27
|
+
expect(target).to receive(:exec!).with("exec $SHELL -l", home: true)
|
|
42
28
|
|
|
43
29
|
cli.ssh
|
|
44
30
|
end
|
|
45
31
|
|
|
46
|
-
it "should connect to specified
|
|
32
|
+
it "should connect to specified target" do
|
|
47
33
|
staging_server = double("staging")
|
|
48
34
|
allow(config).to receive(:[]).with(:staging).and_return(staging_server)
|
|
49
|
-
allow(cli).to receive(:options).and_return({ home: false })
|
|
50
35
|
expect(staging_server).to receive(:exec!).with("exec $SHELL -l", home: false)
|
|
51
36
|
|
|
52
37
|
cli.ssh(:staging)
|
|
53
38
|
end
|
|
54
39
|
end
|
|
55
|
-
end
|
|
40
|
+
end
|
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,14 +39,29 @@ 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
|
|
56
46
|
end
|
|
57
47
|
|
|
58
|
-
context "when
|
|
59
|
-
let(:
|
|
48
|
+
context "when staging target has a deploy strategy" do
|
|
49
|
+
let(:strategy_instance) { double("strategy") }
|
|
50
|
+
let(:staging_server) { double("staging", deploy_strategy: :fake, deploy_strategy_instance: strategy_instance) }
|
|
51
|
+
|
|
52
|
+
it "uses the deploy strategy" do
|
|
53
|
+
expect(cli).to receive(:run!).with("git push -u origin main", verbose: true)
|
|
54
|
+
expect(strategy_instance).to receive(:deploy)
|
|
55
|
+
expect(cli).to receive(:ping).with(:staging)
|
|
56
|
+
|
|
57
|
+
cli.stage
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
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
|
|
60
65
|
|
|
61
66
|
it "raises an error" do
|
|
62
67
|
expect { cli.stage }.to raise_error(Thor::Error, /bard stage.*is disabled/)
|
|
@@ -74,4 +79,4 @@ describe Bard::CLI::Stage do
|
|
|
74
79
|
end
|
|
75
80
|
end
|
|
76
81
|
end
|
|
77
|
-
end
|
|
82
|
+
end
|
data/spec/bard/cli/vim_spec.rb
CHANGED
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
require "bard/cli"
|
|
3
|
-
require "bard/cli/vim"
|
|
4
|
-
require "thor"
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
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)
|
|
@@ -31,4 +25,4 @@ describe Bard::CLI::Vim do
|
|
|
31
25
|
cli.vim("develop")
|
|
32
26
|
end
|
|
33
27
|
end
|
|
34
|
-
end
|
|
28
|
+
end
|
data/spec/bard/command_spec.rb
CHANGED
|
@@ -2,18 +2,11 @@ require "spec_helper"
|
|
|
2
2
|
require "bard/command"
|
|
3
3
|
|
|
4
4
|
describe Bard::Command do
|
|
5
|
-
let(:remote) { double("remote", to_sym: :remote, ssh: true, env: nil, path: "/path/to", ssh_key: nil, ssh_uri: "user@example.com", gateway: nil) }
|
|
6
|
-
|
|
7
5
|
describe ".run" do
|
|
8
6
|
it "should run a command locally" do
|
|
9
7
|
expect(Open3).to receive(:capture3).with("ls -l").and_return(["output", "", 0])
|
|
10
8
|
Bard::Command.run "ls -l"
|
|
11
9
|
end
|
|
12
|
-
|
|
13
|
-
it "should run a command on a remote server" do
|
|
14
|
-
expect(Open3).to receive(:capture3).with("ssh -tt user@example.com 'cd /path/to && ls -l'").and_return(["output", "", 0])
|
|
15
|
-
Bard::Command.run "ls -l", on: remote
|
|
16
|
-
end
|
|
17
10
|
end
|
|
18
11
|
|
|
19
12
|
describe ".run!" do
|
|
@@ -30,7 +23,7 @@ describe Bard::Command do
|
|
|
30
23
|
|
|
31
24
|
describe ".exec!" do
|
|
32
25
|
it "should exec a command locally" do
|
|
33
|
-
|
|
26
|
+
expect(Kernel).to receive(:exec).with("ls -l")
|
|
34
27
|
Bard::Command.exec! "ls -l"
|
|
35
28
|
end
|
|
36
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,96 +117,34 @@ 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
120
|
end
|
|
85
121
|
|
|
86
|
-
context "with
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
|
122
|
+
context "with remove_target" do
|
|
123
|
+
subject { described_class.new("tracker", source: <<~SOURCE) }
|
|
124
|
+
remove_target :staging
|
|
125
|
+
target :staging do
|
|
126
|
+
ssh "deploy@new-host.com"
|
|
136
127
|
end
|
|
128
|
+
SOURCE
|
|
137
129
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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
|
|
130
|
+
it "replaces the default with a fresh target" do
|
|
131
|
+
staging = subject[:staging]
|
|
132
|
+
expect(staging).to be_a(Bard::Target)
|
|
133
|
+
expect(staging.ssh.to_s).to eq "deploy@new-host.com"
|
|
134
|
+
expect(staging.url).to eq "https://new-host.com"
|
|
148
135
|
end
|
|
149
136
|
end
|
|
150
137
|
|
|
151
138
|
context "with github_pages directive" do
|
|
152
139
|
subject { described_class.new("test", source: "github_pages 'example.com'") }
|
|
153
140
|
|
|
154
|
-
describe "#
|
|
155
|
-
it "
|
|
156
|
-
expect(subject.backup).to be_disabled
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
describe "#server" do
|
|
161
|
-
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
|
|
162
143
|
production = subject[:production]
|
|
163
144
|
expect(production).not_to be_nil
|
|
164
145
|
expect(production.github_pages).to eq "example.com"
|
|
165
|
-
expect(production.ssh).to
|
|
146
|
+
expect(production.ssh).to be_nil
|
|
166
147
|
end
|
|
167
148
|
end
|
|
168
149
|
end
|
|
169
150
|
end
|
|
170
|
-
|
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 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
|