bard 2.0.0.beta → 2.0.1

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.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +6 -1
  3. data/CLAUDE.md +76 -0
  4. data/MIGRATION_GUIDE.md +24 -9
  5. data/PLUGINS.md +99 -0
  6. data/README.md +14 -6
  7. data/Rakefile +3 -1
  8. data/bard.gemspec +2 -1
  9. data/cucumber.yml +1 -0
  10. data/features/ci.feature +63 -0
  11. data/features/data.feature +13 -0
  12. data/features/deploy.feature +14 -0
  13. data/features/deploy_git_workflow.feature +89 -0
  14. data/features/run.feature +14 -0
  15. data/features/step_definitions/bard_steps.rb +136 -0
  16. data/features/support/bard-coverage +16 -0
  17. data/features/support/env.rb +14 -39
  18. data/features/support/test_server.rb +216 -0
  19. data/lib/bard/cli.rb +14 -31
  20. data/lib/bard/command.rb +10 -69
  21. data/lib/bard/config.rb +40 -183
  22. data/lib/bard/copy.rb +28 -103
  23. data/lib/bard/plugins/data.rb +56 -0
  24. data/lib/bard/{ci → plugins/deploy/ci}/github_actions.rb +3 -4
  25. data/lib/bard/plugins/deploy/ci/jenkins.rb +176 -0
  26. data/lib/bard/{ci → plugins/deploy/ci}/local.rb +7 -7
  27. data/lib/bard/{ci → plugins/deploy/ci}/runner.rb +38 -4
  28. data/lib/bard/plugins/deploy/ci.rb +38 -0
  29. data/lib/bard/plugins/deploy/ssh_strategy.rb +27 -0
  30. data/lib/bard/{deploy_strategy.rb → plugins/deploy/strategy.rb} +1 -1
  31. data/lib/bard/plugins/deploy.rb +240 -0
  32. data/lib/bard/{git.rb → plugins/git.rb} +6 -3
  33. data/lib/bard/{github.rb → plugins/github.rb} +4 -6
  34. data/lib/bard/{deploy_strategy/github_pages.rb → plugins/github_pages/strategy.rb} +41 -13
  35. data/lib/bard/plugins/github_pages.rb +30 -0
  36. data/lib/bard/plugins/hurt.rb +13 -0
  37. data/{install_files → lib/bard/plugins/install}/.github/dependabot.yml +2 -1
  38. data/{install_files → lib/bard/plugins/install}/.github/workflows/cache-ci.yml +1 -1
  39. data/{install_files → lib/bard/plugins/install}/.github/workflows/ci.yml +2 -2
  40. data/lib/bard/plugins/install.rb +9 -0
  41. data/lib/bard/plugins/open.rb +20 -0
  42. data/lib/bard/{ping.rb → plugins/ping/check.rb} +4 -4
  43. data/lib/bard/plugins/ping/target_methods.rb +23 -0
  44. data/lib/bard/plugins/ping.rb +10 -0
  45. data/lib/bard/plugins/run.rb +19 -0
  46. data/lib/bard/plugins/setup.rb +54 -0
  47. data/lib/bard/plugins/ssh/connection.rb +75 -0
  48. data/lib/bard/plugins/ssh/copy.rb +95 -0
  49. data/lib/bard/{ssh_server.rb → plugins/ssh/server.rb} +17 -42
  50. data/lib/bard/plugins/ssh/target_methods.rb +20 -0
  51. data/lib/bard/plugins/ssh.rb +10 -0
  52. data/lib/bard/plugins/url/target_methods.rb +23 -0
  53. data/lib/bard/plugins/url.rb +1 -0
  54. data/lib/bard/plugins/vim.rb +6 -0
  55. data/lib/bard/retryable.rb +25 -0
  56. data/lib/bard/secrets.rb +10 -0
  57. data/lib/bard/target.rb +27 -185
  58. data/lib/bard/version.rb +1 -1
  59. data/lib/bard.rb +1 -3
  60. data/spec/acceptance/docker/Dockerfile +3 -2
  61. data/spec/bard/capability_spec.rb +8 -50
  62. data/spec/bard/ci/github_actions_spec.rb +117 -14
  63. data/spec/bard/ci/jenkins_spec.rb +139 -0
  64. data/spec/bard/ci/runner_spec.rb +61 -0
  65. data/spec/bard/ci_spec.rb +1 -1
  66. data/spec/bard/cli/ci_spec.rb +34 -27
  67. data/spec/bard/cli/data_spec.rb +7 -26
  68. data/spec/bard/cli/deploy_spec.rb +87 -46
  69. data/spec/bard/cli/hurt_spec.rb +3 -9
  70. data/spec/bard/cli/install_spec.rb +5 -11
  71. data/spec/bard/cli/master_key_spec.rb +5 -19
  72. data/spec/bard/cli/open_spec.rb +14 -30
  73. data/spec/bard/cli/ping_spec.rb +8 -23
  74. data/spec/bard/cli/run_spec.rb +27 -21
  75. data/spec/bard/cli/setup_spec.rb +10 -27
  76. data/spec/bard/cli/ssh_spec.rb +10 -25
  77. data/spec/bard/cli/stage_spec.rb +28 -23
  78. data/spec/bard/cli/vim_spec.rb +3 -9
  79. data/spec/bard/command_spec.rb +1 -8
  80. data/spec/bard/config_spec.rb +78 -98
  81. data/spec/bard/copy_spec.rb +54 -18
  82. data/spec/bard/deploy_strategy/ssh_spec.rb +65 -7
  83. data/spec/bard/deploy_strategy_spec.rb +1 -1
  84. data/spec/bard/dynamic_dsl_spec.rb +18 -98
  85. data/spec/bard/git_spec.rb +9 -5
  86. data/spec/bard/github_spec.rb +2 -2
  87. data/spec/bard/ping_spec.rb +5 -5
  88. data/spec/bard/ssh_copy_spec.rb +44 -0
  89. data/spec/bard/ssh_server_spec.rb +8 -101
  90. data/spec/bard/target_spec.rb +66 -109
  91. data/spec/spec_helper.rb +6 -1
  92. metadata +79 -143
  93. data/README.rdoc +0 -15
  94. data/features/bard_check.feature +0 -94
  95. data/features/bard_deploy.feature +0 -18
  96. data/features/bard_pull.feature +0 -112
  97. data/features/bard_push.feature +0 -112
  98. data/features/podman_testcontainers.feature +0 -16
  99. data/features/step_definitions/check_steps.rb +0 -47
  100. data/features/step_definitions/git_steps.rb +0 -73
  101. data/features/step_definitions/global_steps.rb +0 -56
  102. data/features/step_definitions/podman_steps.rb +0 -23
  103. data/features/step_definitions/rails_steps.rb +0 -44
  104. data/features/step_definitions/submodule_steps.rb +0 -110
  105. data/features/support/grit_ext.rb +0 -13
  106. data/features/support/io.rb +0 -32
  107. data/features/support/podman.rb +0 -153
  108. data/lib/bard/ci/jenkins.rb +0 -105
  109. data/lib/bard/ci/retryable.rb +0 -27
  110. data/lib/bard/ci.rb +0 -50
  111. data/lib/bard/cli/ci.rb +0 -66
  112. data/lib/bard/cli/command.rb +0 -26
  113. data/lib/bard/cli/data.rb +0 -45
  114. data/lib/bard/cli/deploy.rb +0 -85
  115. data/lib/bard/cli/hurt.rb +0 -20
  116. data/lib/bard/cli/install.rb +0 -16
  117. data/lib/bard/cli/master_key.rb +0 -17
  118. data/lib/bard/cli/new.rb +0 -101
  119. data/lib/bard/cli/new_rails_template.rb +0 -197
  120. data/lib/bard/cli/open.rb +0 -22
  121. data/lib/bard/cli/ping.rb +0 -18
  122. data/lib/bard/cli/provision.rb +0 -34
  123. data/lib/bard/cli/run.rb +0 -24
  124. data/lib/bard/cli/setup.rb +0 -56
  125. data/lib/bard/cli/ssh.rb +0 -14
  126. data/lib/bard/cli/stage.rb +0 -27
  127. data/lib/bard/cli/vim.rb +0 -13
  128. data/lib/bard/default_config.rb +0 -35
  129. data/lib/bard/deploy_strategy/ssh.rb +0 -19
  130. data/lib/bard/github_pages.rb +0 -134
  131. data/lib/bard/provision/app.rb +0 -10
  132. data/lib/bard/provision/apt.rb +0 -16
  133. data/lib/bard/provision/authorizedkeys.rb +0 -25
  134. data/lib/bard/provision/data.rb +0 -27
  135. data/lib/bard/provision/deploy.rb +0 -10
  136. data/lib/bard/provision/http.rb +0 -16
  137. data/lib/bard/provision/logrotation.rb +0 -30
  138. data/lib/bard/provision/masterkey.rb +0 -18
  139. data/lib/bard/provision/mysql.rb +0 -22
  140. data/lib/bard/provision/passenger.rb +0 -37
  141. data/lib/bard/provision/repo.rb +0 -72
  142. data/lib/bard/provision/rvm.rb +0 -22
  143. data/lib/bard/provision/ssh.rb +0 -72
  144. data/lib/bard/provision/swapfile.rb +0 -21
  145. data/lib/bard/provision/user.rb +0 -42
  146. data/lib/bard/provision.rb +0 -16
  147. data/lib/bard/server.rb +0 -117
  148. data/spec/bard/cli/command_spec.rb +0 -50
  149. data/spec/bard/cli/new_spec.rb +0 -73
  150. data/spec/bard/cli/provision_spec.rb +0 -42
  151. data/spec/bard/github_pages_spec.rb +0 -143
  152. data/spec/bard/provision/app_spec.rb +0 -33
  153. data/spec/bard/provision/apt_spec.rb +0 -39
  154. data/spec/bard/provision/authorizedkeys_spec.rb +0 -40
  155. data/spec/bard/provision/data_spec.rb +0 -54
  156. data/spec/bard/provision/deploy_spec.rb +0 -33
  157. data/spec/bard/provision/http_spec.rb +0 -57
  158. data/spec/bard/provision/logrotation_spec.rb +0 -34
  159. data/spec/bard/provision/masterkey_spec.rb +0 -63
  160. data/spec/bard/provision/mysql_spec.rb +0 -55
  161. data/spec/bard/provision/passenger_spec.rb +0 -81
  162. data/spec/bard/provision/repo_spec.rb +0 -208
  163. data/spec/bard/provision/rvm_spec.rb +0 -49
  164. data/spec/bard/provision/ssh_spec.rb +0 -229
  165. data/spec/bard/provision/swapfile_spec.rb +0 -32
  166. data/spec/bard/provision/user_spec.rb +0 -103
  167. data/spec/bard/provision_spec.rb +0 -28
  168. data/spec/bard/server_spec.rb +0 -127
  169. /data/lib/bard/{ci → plugins/deploy/ci}/state.rb +0 -0
  170. /data/{install_files → lib/bard/plugins/install}/apt_dependencies.rb +0 -0
  171. /data/{install_files → lib/bard/plugins/install}/ci +0 -0
  172. /data/{install_files → lib/bard/plugins/install}/setup +0 -0
  173. /data/{install_files → lib/bard/plugins/install}/specified_bundler.rb +0 -0
  174. /data/{install_files → lib/bard/plugins/install}/specified_ruby.rb +0 -0
@@ -1,34 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/logrotation"
4
-
5
- describe Bard::Provision::LogRotation do
6
- let(:server) { double("server", project_name: "test_app") }
7
- let(:config) { { production: server } }
8
- let(:ssh_url) { "user@example.com" }
9
- let(:provision_server) { double("provision_server") }
10
- let(:logrotation) { Bard::Provision::LogRotation.new(config, ssh_url) }
11
-
12
- before do
13
- allow(logrotation).to receive(:server).and_return(server)
14
- allow(logrotation).to receive(:provision_server).and_return(provision_server)
15
- allow(logrotation).to receive(:print)
16
- allow(logrotation).to receive(:puts)
17
- end
18
-
19
- describe "#call" do
20
- it "sets up log rotation config on the server" do
21
- expect(provision_server).to receive(:run!).with(/file=\/etc\/logrotate\.d\/test_app/, quiet: true)
22
-
23
- logrotation.call
24
- end
25
-
26
- it "prints status messages" do
27
- allow(provision_server).to receive(:run!)
28
- expect(logrotation).to receive(:print).with("Log Rotation:")
29
- expect(logrotation).to receive(:puts).with(" ✓")
30
-
31
- logrotation.call
32
- end
33
- end
34
- end
@@ -1,63 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/masterkey"
4
-
5
- describe Bard::Provision::MasterKey do
6
- let(:config) { { production: double("production") } }
7
- let(:ssh_url) { "user@example.com" }
8
- let(:provision_server) { double("provision_server") }
9
- let(:master_key) { Bard::Provision::MasterKey.new(config, ssh_url) }
10
-
11
- before do
12
- allow(master_key).to receive(:provision_server).and_return(provision_server)
13
- allow(master_key).to receive(:print)
14
- allow(master_key).to receive(:puts)
15
- end
16
-
17
- describe "#call" do
18
- context "when master.key exists locally" do
19
- before do
20
- allow(File).to receive(:exist?).with("config/master.key").and_return(true)
21
- end
22
-
23
- it "uploads master.key if not present on server" do
24
- allow(provision_server).to receive(:run).with("[ -f config/master.key ]", quiet: true).and_return(false)
25
-
26
- copy_double = double("copy")
27
- expect(Bard::Copy).to receive(:new).with("config/master.key").and_return(copy_double)
28
- expect(copy_double).to receive(:scp_using_local).with(:to, provision_server)
29
-
30
- master_key.call
31
- end
32
-
33
- it "skips upload if master.key already exists on server" do
34
- allow(provision_server).to receive(:run).with("[ -f config/master.key ]", quiet: true).and_return(true)
35
-
36
- expect(Bard::Copy).not_to receive(:new)
37
-
38
- master_key.call
39
- end
40
- end
41
-
42
- context "when master.key doesn't exist locally" do
43
- before do
44
- allow(File).to receive(:exist?).with("config/master.key").and_return(false)
45
- end
46
-
47
- it "skips the upload" do
48
- expect(Bard::Copy).not_to receive(:new)
49
-
50
- master_key.call
51
- end
52
- end
53
-
54
- it "prints status messages" do
55
- allow(File).to receive(:exist?).and_return(false)
56
-
57
- expect(master_key).to receive(:print).with("Master Key:")
58
- expect(master_key).to receive(:puts).with(" ✓")
59
-
60
- master_key.call
61
- end
62
- end
63
- end
@@ -1,55 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/mysql"
4
-
5
- describe Bard::Provision::MySQL do
6
- let(:config) { { production: double("production") } }
7
- let(:ssh_url) { "user@example.com" }
8
- let(:provision_server) { double("provision_server") }
9
- let(:mysql) { Bard::Provision::MySQL.new(config, ssh_url) }
10
-
11
- before do
12
- allow(mysql).to receive(:provision_server).and_return(provision_server)
13
- allow(mysql).to receive(:print)
14
- allow(mysql).to receive(:puts)
15
- end
16
-
17
- describe "#call" do
18
- context "when MySQL is not responding" do
19
- it "installs MySQL" do
20
- allow(mysql).to receive(:mysql_responding?).and_return(false)
21
-
22
- expect(provision_server).to receive(:run!).with(/sudo apt-get install -y mysql-server/, home: true)
23
-
24
- mysql.call
25
- end
26
- end
27
-
28
- context "when MySQL is already responding" do
29
- it "skips installation" do
30
- allow(mysql).to receive(:mysql_responding?).and_return(true)
31
-
32
- expect(provision_server).not_to receive(:run!)
33
-
34
- mysql.call
35
- end
36
- end
37
-
38
- it "prints status messages" do
39
- allow(mysql).to receive(:mysql_responding?).and_return(true)
40
-
41
- expect(mysql).to receive(:print).with("MySQL:")
42
- expect(mysql).to receive(:puts).with(" ✓")
43
-
44
- mysql.call
45
- end
46
- end
47
-
48
- describe "#mysql_responding?" do
49
- it "checks if MySQL service is active" do
50
- expect(provision_server).to receive(:run).with("sudo systemctl is-active --quiet mysql", home: true, quiet: true)
51
-
52
- mysql.mysql_responding?
53
- end
54
- end
55
- end
@@ -1,81 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/passenger"
4
-
5
- describe Bard::Provision::Passenger do
6
- let(:server) { double("server", project_name: "test_app") }
7
- let(:config) { { production: server } }
8
- let(:ssh_url) { "user@example.com" }
9
- let(:provision_server) { double("provision_server") }
10
- let(:passenger) { Bard::Provision::Passenger.new(config, ssh_url) }
11
-
12
- before do
13
- allow(passenger).to receive(:server).and_return(server)
14
- allow(passenger).to receive(:provision_server).and_return(provision_server)
15
- allow(provision_server).to receive_message_chain(:ssh_uri, :host).and_return("192.168.1.100")
16
- allow(passenger).to receive(:print)
17
- allow(passenger).to receive(:puts)
18
- allow(passenger).to receive(:system)
19
- end
20
-
21
- describe "#call" do
22
- context "when HTTP is not responding" do
23
- it "installs nginx and passenger" do
24
- allow(passenger).to receive(:http_responding?).and_return(false)
25
- allow(passenger).to receive(:app_configured?).and_return(true)
26
-
27
- expect(provision_server).to receive(:run!).with(/grep -qxF.*RAILS_ENV/, home: true)
28
-
29
- passenger.call
30
- end
31
- end
32
-
33
- context "when app is not configured" do
34
- it "creates nginx config" do
35
- allow(passenger).to receive(:http_responding?).and_return(true)
36
- allow(passenger).to receive(:app_configured?).and_return(false)
37
-
38
- expect(provision_server).to receive(:run!).with("bard setup")
39
-
40
- passenger.call
41
- end
42
- end
43
-
44
- context "when everything is already set up" do
45
- it "skips installation and configuration" do
46
- allow(passenger).to receive(:http_responding?).and_return(true)
47
- allow(passenger).to receive(:app_configured?).and_return(true)
48
-
49
- expect(provision_server).not_to receive(:run!)
50
-
51
- passenger.call
52
- end
53
- end
54
-
55
- it "prints status messages" do
56
- allow(passenger).to receive(:http_responding?).and_return(true)
57
- allow(passenger).to receive(:app_configured?).and_return(true)
58
-
59
- expect(passenger).to receive(:print).with("Passenger:")
60
- expect(passenger).to receive(:puts).with(" ✓")
61
-
62
- passenger.call
63
- end
64
- end
65
-
66
- describe "#http_responding?" do
67
- it "checks if port 80 is responding" do
68
- expect(passenger).to receive(:system).with("nc -zv 192.168.1.100 80 2>/dev/null")
69
-
70
- passenger.http_responding?
71
- end
72
- end
73
-
74
- describe "#app_configured?" do
75
- it "checks if nginx config exists for the app" do
76
- expect(provision_server).to receive(:run).with("[ -f /etc/nginx/sites-enabled/test_app ]", quiet: true)
77
-
78
- passenger.app_configured?
79
- end
80
- end
81
- end
@@ -1,208 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/repo"
4
-
5
- describe Bard::Provision::Repo do
6
- let(:ssh_uri) { double("ssh_uri", user: "deploy", host: "example.com") }
7
- let(:server) { double("server", ssh_uri: ssh_uri, project_name: "test_project") }
8
- let(:config) { { production: server } }
9
- let(:ssh_url) { "deploy@example.com" }
10
- let(:provision_server) { double("provision_server") }
11
- let(:github_api) { double("github_api") }
12
- let(:repo_provisioner) { Bard::Provision::Repo.new(config, ssh_url) }
13
-
14
- before do
15
- allow(repo_provisioner).to receive(:server).and_return(server)
16
- allow(repo_provisioner).to receive(:provision_server).and_return(provision_server)
17
- allow(repo_provisioner).to receive(:print)
18
- allow(repo_provisioner).to receive(:puts)
19
- allow(Bard::Github).to receive(:new).and_return(github_api)
20
- end
21
-
22
- describe "#call" do
23
- context "when repository is already cloned" do
24
- context "when not on latest master" do
25
- it "updates to latest master" do
26
- allow(repo_provisioner).to receive(:already_cloned?).and_return(true)
27
- allow(repo_provisioner).to receive(:on_latest_master?).and_return(false)
28
-
29
- expect(repo_provisioner).to receive(:update_to_latest_master!)
30
- expect(github_api).not_to receive(:add_deploy_key)
31
-
32
- repo_provisioner.call
33
- end
34
-
35
- it "prints status message when updating to latest master" do
36
- allow(repo_provisioner).to receive(:already_cloned?).and_return(true)
37
- allow(repo_provisioner).to receive(:on_latest_master?).and_return(false)
38
- allow(repo_provisioner).to receive(:update_to_latest_master!)
39
-
40
- expect(repo_provisioner).to receive(:print).with("Repo:")
41
- expect(repo_provisioner).to receive(:print).with(" Updating to latest master,")
42
- expect(repo_provisioner).to receive(:puts).with(" ✓")
43
-
44
- repo_provisioner.call
45
- end
46
- end
47
-
48
- context "when already on latest master" do
49
- it "skips update" do
50
- allow(repo_provisioner).to receive(:already_cloned?).and_return(true)
51
- allow(repo_provisioner).to receive(:on_latest_master?).and_return(true)
52
-
53
- expect(repo_provisioner).not_to receive(:update_to_latest_master!)
54
- expect(github_api).not_to receive(:add_deploy_key)
55
-
56
- repo_provisioner.call
57
- end
58
-
59
- it "only prints repo header and checkbox" do
60
- allow(repo_provisioner).to receive(:already_cloned?).and_return(true)
61
- allow(repo_provisioner).to receive(:on_latest_master?).and_return(true)
62
-
63
- expect(repo_provisioner).to receive(:print).with("Repo:")
64
- expect(repo_provisioner).not_to receive(:print).with(" Updating to latest master,")
65
- expect(repo_provisioner).to receive(:puts).with(" ✓")
66
-
67
- repo_provisioner.call
68
- end
69
- end
70
- end
71
-
72
- context "when repository is not cloned but can be cloned" do
73
- it "clones the repository directly" do
74
- allow(repo_provisioner).to receive(:already_cloned?).and_return(false)
75
- allow(repo_provisioner).to receive(:can_clone_project?).and_return(true)
76
-
77
- expect(provision_server).to receive(:run!).with("git clone git@github.com:botandrosedesign/test_project", home: true)
78
- expect(github_api).not_to receive(:add_deploy_key)
79
-
80
- repo_provisioner.call
81
- end
82
- end
83
-
84
- context "when repository cannot be cloned and SSH keypair exists" do
85
- it "adds deploy key and clones repository" do
86
- allow(repo_provisioner).to receive(:already_cloned?).and_return(false)
87
- allow(repo_provisioner).to receive(:can_clone_project?).and_return(false)
88
- allow(repo_provisioner).to receive(:ssh_keypair?).and_return(true)
89
- allow(provision_server).to receive(:run).with("cat ~/.ssh/id_rsa.pub", home: true).and_return("ssh-rsa AAAAB3...")
90
-
91
- expect(github_api).to receive(:add_deploy_key).with(title: "deploy@example.com", key: "ssh-rsa AAAAB3...")
92
- expect(provision_server).to receive(:run!).with("git clone git@github.com:botandrosedesign/test_project", home: true)
93
-
94
- repo_provisioner.call
95
- end
96
- end
97
-
98
- context "when repository cannot be cloned and no SSH keypair exists" do
99
- it "generates keypair, adds deploy key, and clones repository" do
100
- allow(repo_provisioner).to receive(:already_cloned?).and_return(false)
101
- allow(repo_provisioner).to receive(:can_clone_project?).and_return(false)
102
- allow(repo_provisioner).to receive(:ssh_keypair?).and_return(false)
103
- allow(provision_server).to receive(:run).with("cat ~/.ssh/id_rsa.pub", home: true).and_return("ssh-rsa AAAAB3...")
104
-
105
- expect(provision_server).to receive(:run!).with('ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -q -N ""', home: true)
106
- expect(github_api).to receive(:add_deploy_key).with(title: "deploy@example.com", key: "ssh-rsa AAAAB3...")
107
- expect(provision_server).to receive(:run!).with("git clone git@github.com:botandrosedesign/test_project", home: true)
108
-
109
- repo_provisioner.call
110
- end
111
-
112
- it "prints status messages during setup" do
113
- allow(repo_provisioner).to receive(:already_cloned?).and_return(false)
114
- allow(repo_provisioner).to receive(:can_clone_project?).and_return(false)
115
- allow(repo_provisioner).to receive(:ssh_keypair?).and_return(false)
116
- allow(provision_server).to receive(:run).and_return("ssh-rsa AAAAB3...")
117
- allow(provision_server).to receive(:run!)
118
- allow(github_api).to receive(:add_deploy_key)
119
-
120
- expect(repo_provisioner).to receive(:print).with("Repo:")
121
- expect(repo_provisioner).to receive(:print).with(" Generating keypair in ~/.ssh,")
122
- expect(repo_provisioner).to receive(:print).with(" Add public key to GitHub repo deploy keys,")
123
- expect(repo_provisioner).to receive(:print).with(" Cloning repo,")
124
- expect(repo_provisioner).to receive(:puts).with(" ✓")
125
-
126
- repo_provisioner.call
127
- end
128
- end
129
-
130
- it "always prints success message" do
131
- allow(repo_provisioner).to receive(:already_cloned?).and_return(true)
132
- allow(repo_provisioner).to receive(:on_latest_master?).and_return(true)
133
-
134
- expect(repo_provisioner).to receive(:print).with("Repo:")
135
- expect(repo_provisioner).to receive(:puts).with(" ✓")
136
-
137
- repo_provisioner.call
138
- end
139
- end
140
-
141
- describe "private methods" do
142
- describe "#ssh_keypair?" do
143
- it "checks if SSH public key exists" do
144
- expect(provision_server).to receive(:run).with("[ -f ~/.ssh/id_rsa.pub ]", home: true, quiet: true)
145
-
146
- repo_provisioner.send(:ssh_keypair?)
147
- end
148
- end
149
-
150
- describe "#already_cloned?" do
151
- it "checks if git directory exists" do
152
- expect(provision_server).to receive(:run).with("[ -d ~/test_project/.git ]", home: true, quiet: true)
153
-
154
- repo_provisioner.send(:already_cloned?)
155
- end
156
- end
157
-
158
- describe "#can_clone_project?" do
159
- it "tests if repository can be cloned" do
160
- expected_commands = [
161
- "needle=$(ssh-keyscan -t ed25519 github.com 2>/dev/null | cut -d \" \" -f 2-3)",
162
- "grep -q \"$needle\" ~/.ssh/known_hosts || ssh-keyscan -H github.com >> ~/.ssh/known_hosts 2>/dev/null",
163
- "git ls-remote git@github.com:botandrosedesign/test_project"
164
- ].join("; ")
165
-
166
- expect(provision_server).to receive(:run).with(expected_commands, home: true, quiet: true)
167
-
168
- repo_provisioner.send(:can_clone_project?)
169
- end
170
- end
171
-
172
- describe "#project_name" do
173
- it "returns the server's project name" do
174
- expect(repo_provisioner.send(:project_name)).to eq("test_project")
175
- end
176
- end
177
-
178
- describe "#on_latest_master?" do
179
- it "checks if current HEAD matches origin/master after fetching" do
180
- expected_command = "cd ~/test_project && git fetch origin && [ $(git rev-parse HEAD) = $(git rev-parse origin/master) ]"
181
- expect(provision_server).to receive(:run).with(expected_command, home: true, quiet: true)
182
-
183
- repo_provisioner.send(:on_latest_master?)
184
- end
185
-
186
- it "returns true when on latest master" do
187
- allow(provision_server).to receive(:run).and_return(true)
188
-
189
- expect(repo_provisioner.send(:on_latest_master?)).to be true
190
- end
191
-
192
- it "returns false when not on latest master" do
193
- allow(provision_server).to receive(:run).and_return(false)
194
-
195
- expect(repo_provisioner.send(:on_latest_master?)).to be false
196
- end
197
- end
198
-
199
- describe "#update_to_latest_master!" do
200
- it "checks out master and resets to origin/master" do
201
- expected_command = "cd ~/test_project && git checkout master && git reset --hard origin/master"
202
- expect(provision_server).to receive(:run!).with(expected_command, home: true)
203
-
204
- repo_provisioner.send(:update_to_latest_master!)
205
- end
206
- end
207
- end
208
- end
@@ -1,49 +0,0 @@
1
- require "spec_helper"
2
- require "bard/provision"
3
- require "bard/provision/rvm"
4
-
5
- describe Bard::Provision::RVM do
6
- let(:config) { { production: double("production") } }
7
- let(:ssh_url) { "user@example.com" }
8
- let(:provision_server) { double("provision_server") }
9
- let(:rvm) { Bard::Provision::RVM.new(config, ssh_url) }
10
-
11
- before do
12
- allow(rvm).to receive(:provision_server).and_return(provision_server)
13
- allow(rvm).to receive(:print)
14
- allow(rvm).to receive(:puts)
15
- allow(File).to receive(:read).with(".ruby-version").and_return("3.2.0\n")
16
- end
17
-
18
- describe "#call" do
19
- context "when RVM is not installed" do
20
- it "installs RVM and Ruby" do
21
- allow(provision_server).to receive(:run).with("[ -d ~/.rvm ]", quiet: true).and_return(false)
22
-
23
- expect(provision_server).to receive(:run!).with(/sed -i.*bashrc/)
24
- expect(provision_server).to receive(:run!).with("rvm install 3.2.0")
25
-
26
- rvm.call
27
- end
28
- end
29
-
30
- context "when RVM is already installed" do
31
- it "skips installation" do
32
- allow(provision_server).to receive(:run).with("[ -d ~/.rvm ]", quiet: true).and_return(true)
33
-
34
- expect(provision_server).not_to receive(:run!)
35
-
36
- rvm.call
37
- end
38
- end
39
-
40
- it "prints status messages" do
41
- allow(provision_server).to receive(:run).and_return(true)
42
-
43
- expect(rvm).to receive(:print).with("RVM:")
44
- expect(rvm).to receive(:puts).with(" ✓")
45
-
46
- rvm.call
47
- end
48
- end
49
- end