bard 1.9.6 → 2.0.0.beta

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +0 -5
  3. data/MIGRATION_GUIDE.md +9 -24
  4. data/README.md +6 -14
  5. data/README.rdoc +15 -0
  6. data/Rakefile +1 -3
  7. data/features/bard_check.feature +94 -0
  8. data/features/bard_deploy.feature +18 -0
  9. data/features/bard_pull.feature +112 -0
  10. data/features/bard_push.feature +112 -0
  11. data/features/podman_testcontainers.feature +16 -0
  12. data/features/step_definitions/check_steps.rb +47 -0
  13. data/features/step_definitions/git_steps.rb +73 -0
  14. data/features/step_definitions/global_steps.rb +56 -0
  15. data/features/step_definitions/podman_steps.rb +23 -0
  16. data/features/step_definitions/rails_steps.rb +44 -0
  17. data/features/step_definitions/submodule_steps.rb +110 -0
  18. data/features/support/env.rb +39 -14
  19. data/features/support/grit_ext.rb +13 -0
  20. data/features/support/io.rb +32 -0
  21. data/features/support/podman.rb +153 -0
  22. data/lib/bard/ci/github_actions.rb +2 -1
  23. data/lib/bard/ci/jenkins.rb +11 -82
  24. data/lib/bard/ci/local.rb +6 -6
  25. data/lib/bard/ci/runner.rb +1 -35
  26. data/lib/bard/ci.rb +23 -11
  27. data/lib/bard/cli/ci.rb +38 -45
  28. data/lib/bard/cli/deploy.rb +9 -40
  29. data/lib/bard/cli/hurt.rb +15 -10
  30. data/lib/bard/cli/install.rb +12 -7
  31. data/lib/bard/cli/open.rb +16 -12
  32. data/lib/bard/cli/ping.rb +14 -8
  33. data/lib/bard/cli/provision.rb +1 -1
  34. data/lib/bard/cli/run.rb +3 -5
  35. data/lib/bard/cli/stage.rb +1 -9
  36. data/lib/bard/cli/vim.rb +10 -5
  37. data/lib/bard/cli.rb +11 -13
  38. data/lib/bard/command.rb +13 -33
  39. data/lib/bard/config.rb +14 -10
  40. data/lib/bard/copy.rb +33 -12
  41. data/lib/bard/deploy_strategy/github_pages.rb +2 -10
  42. data/lib/bard/deploy_strategy.rb +0 -3
  43. data/lib/bard/github.rb +4 -2
  44. data/lib/bard/provision/apt.rb +1 -1
  45. data/lib/bard/provision/logrotation.rb +1 -1
  46. data/lib/bard/provision/mysql.rb +2 -2
  47. data/lib/bard/provision/passenger.rb +2 -2
  48. data/lib/bard/provision/repo.rb +2 -2
  49. data/lib/bard/provision/ssh.rb +2 -9
  50. data/lib/bard/provision/swapfile.rb +1 -3
  51. data/lib/bard/server.rb +3 -46
  52. data/lib/bard/ssh_server.rb +2 -9
  53. data/lib/bard/target.rb +16 -67
  54. data/lib/bard/version.rb +1 -1
  55. data/spec/acceptance/docker/Dockerfile +1 -2
  56. data/spec/bard/ci/github_actions_spec.rb +13 -116
  57. data/spec/bard/cli/ci_spec.rb +8 -34
  58. data/spec/bard/cli/deploy_spec.rb +8 -46
  59. data/spec/bard/cli/hurt_spec.rb +2 -2
  60. data/spec/bard/cli/install_spec.rb +4 -4
  61. data/spec/bard/cli/open_spec.rb +8 -10
  62. data/spec/bard/cli/ping_spec.rb +5 -5
  63. data/spec/bard/cli/run_spec.rb +1 -20
  64. data/spec/bard/cli/stage_spec.rb +0 -20
  65. data/spec/bard/cli/vim_spec.rb +5 -5
  66. data/spec/bard/command_spec.rb +1 -3
  67. data/spec/bard/config_spec.rb +0 -28
  68. data/spec/bard/copy_spec.rb +3 -3
  69. data/spec/bard/github_spec.rb +1 -1
  70. data/spec/bard/provision/apt_spec.rb +1 -1
  71. data/spec/bard/provision/logrotation_spec.rb +1 -1
  72. data/spec/bard/provision/passenger_spec.rb +1 -1
  73. data/spec/bard/provision/repo_spec.rb +1 -1
  74. data/spec/bard/provision/ssh_spec.rb +4 -17
  75. data/spec/bard/provision/swapfile_spec.rb +1 -2
  76. data/spec/bard/ssh_server_spec.rb +8 -12
  77. data/spec/bard/target_spec.rb +5 -9
  78. data/spec/spec_helper.rb +1 -6
  79. metadata +31 -41
  80. data/CLAUDE.md +0 -76
  81. data/PLUGINS.md +0 -114
  82. data/cucumber.yml +0 -1
  83. data/features/ci.feature +0 -62
  84. data/features/data.feature +0 -12
  85. data/features/deploy.feature +0 -13
  86. data/features/deploy_git_workflow.feature +0 -88
  87. data/features/run.feature +0 -13
  88. data/features/step_definitions/bard_steps.rb +0 -135
  89. data/features/support/bard-coverage +0 -16
  90. data/features/support/test_server.rb +0 -216
  91. data/lib/bard/deprecation.rb +0 -19
  92. data/lib/bard/plugin.rb +0 -100
  93. data/lib/bard/plugins/backup.rb +0 -19
  94. data/lib/bard/plugins/github_pages.rb +0 -34
  95. data/lib/bard/plugins/hurt.rb +0 -5
  96. data/lib/bard/plugins/install.rb +0 -5
  97. data/lib/bard/plugins/jenkins.rb +0 -6
  98. data/lib/bard/plugins/new.rb +0 -5
  99. data/lib/bard/plugins/ping.rb +0 -6
  100. data/lib/bard/plugins/provision.rb +0 -5
  101. data/lib/bard/plugins/vim.rb +0 -5
  102. data/lib/bard/secrets.rb +0 -10
  103. data/spec/bard/ci/jenkins_spec.rb +0 -139
  104. data/spec/bard/ci/runner_spec.rb +0 -61
  105. data/spec/bard/deprecation_spec.rb +0 -281
  106. data/spec/bard/plugin_spec.rb +0 -79
@@ -5,7 +5,7 @@ describe Bard::Github do
5
5
  let(:github) { Bard::Github.new("test-project") }
6
6
 
7
7
  before do
8
- allow(Bard::Secrets).to receive(:fetch).with("github-apikey").and_return("12345")
8
+ allow(github).to receive(:`).with("git ls-remote -t git@github.com:botandrosedesign/secrets").and_return("github-apikey|12345")
9
9
  end
10
10
 
11
11
  describe "#get" do
@@ -20,7 +20,7 @@ describe Bard::Provision::Apt do
20
20
  %(echo "\\$nrconf{restart} = \\"a\\";" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf),
21
21
  "sudo apt-get update -y",
22
22
  "sudo apt-get upgrade -y",
23
- "sudo apt-get install -y curl build-essential"
23
+ "sudo apt-get install -y curl"
24
24
  ].join("; ")
25
25
 
26
26
  expect(provision_server).to receive(:run!).with(expected_commands, home: true)
@@ -4,7 +4,7 @@ require "bard/provision/logrotation"
4
4
 
5
5
  describe Bard::Provision::LogRotation do
6
6
  let(:server) { double("server", project_name: "test_app") }
7
- let(:config) { double("config", project_name: "test_app", :[] => server) }
7
+ let(:config) { { production: server } }
8
8
  let(:ssh_url) { "user@example.com" }
9
9
  let(:provision_server) { double("provision_server") }
10
10
  let(:logrotation) { Bard::Provision::LogRotation.new(config, ssh_url) }
@@ -4,7 +4,7 @@ require "bard/provision/passenger"
4
4
 
5
5
  describe Bard::Provision::Passenger do
6
6
  let(:server) { double("server", project_name: "test_app") }
7
- let(:config) { double("config", project_name: "test_app", :[] => server) }
7
+ let(:config) { { production: server } }
8
8
  let(:ssh_url) { "user@example.com" }
9
9
  let(:provision_server) { double("provision_server") }
10
10
  let(:passenger) { Bard::Provision::Passenger.new(config, ssh_url) }
@@ -5,7 +5,7 @@ require "bard/provision/repo"
5
5
  describe Bard::Provision::Repo do
6
6
  let(:ssh_uri) { double("ssh_uri", user: "deploy", host: "example.com") }
7
7
  let(:server) { double("server", ssh_uri: ssh_uri, project_name: "test_project") }
8
- let(:config) { double("config", project_name: "test_project", :[] => server) }
8
+ let(:config) { { production: server } }
9
9
  let(:ssh_url) { "deploy@example.com" }
10
10
  let(:provision_server) { double("provision_server") }
11
11
  let(:github_api) { double("github_api") }
@@ -45,39 +45,26 @@ describe Bard::Provision::SSH do
45
45
  context "when SSH is not available on target port but available on default port" do
46
46
  it "reconfigures SSH port and adds to known hosts" do
47
47
  allow(ssh_provisioner).to receive(:password_auth_enabled?).and_return(false)
48
- allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri, port: 2222).and_return(false, true)
48
+ allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri, port: 2222).and_return(false)
49
49
  allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri).and_return(true)
50
50
  allow(ssh_provisioner).to receive(:ssh_known_host?).with(provision_ssh_uri).and_return(false)
51
- allow(ssh_provisioner).to receive(:sleep)
52
51
 
53
52
  expect(ssh_provisioner).to receive(:add_ssh_known_host!).with(provision_ssh_uri).twice
54
53
  expect(provision_server).to receive(:run!).with(
55
- 'echo "Port 2222" | sudo tee /etc/ssh/sshd_config.d/port_2222.conf && sudo service ssh restart',
54
+ 'echo "Port 2222" | sudo tee /etc/ssh/sshd_config.d/port_2222.conf; sudo service ssh restart',
56
55
  home: true
57
56
  )
58
57
 
59
58
  ssh_provisioner.call
60
59
  end
61
60
 
62
- it "raises if new port is not responding after reconfiguration" do
63
- allow(ssh_provisioner).to receive(:password_auth_enabled?).and_return(false)
64
- allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri, port: 2222).and_return(false)
65
- allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri).and_return(true)
66
- allow(ssh_provisioner).to receive(:ssh_known_host?).with(provision_ssh_uri).and_return(true)
67
- allow(provision_server).to receive(:run!)
68
- allow(ssh_provisioner).to receive(:sleep)
69
-
70
- expect { ssh_provisioner.call }.to raise_error(/reconfigured SSH to port 2222 but it's not responding/)
71
- end
72
-
73
61
  it "prints status messages during reconfiguration" do
74
62
  allow(ssh_provisioner).to receive(:password_auth_enabled?).and_return(false)
75
- allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri, port: 2222).and_return(false, true)
63
+ allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri, port: 2222).and_return(false)
76
64
  allow(ssh_provisioner).to receive(:ssh_available?).with(provision_ssh_uri).and_return(true)
77
65
  allow(ssh_provisioner).to receive(:ssh_known_host?).and_return(false)
78
66
  allow(ssh_provisioner).to receive(:add_ssh_known_host!)
79
67
  allow(provision_server).to receive(:run!)
80
- allow(ssh_provisioner).to receive(:sleep)
81
68
 
82
69
  expect(ssh_provisioner).to receive(:print).with("SSH:")
83
70
  expect(ssh_provisioner).to receive(:print).with(" Adding known host,")
@@ -231,7 +218,7 @@ describe Bard::Provision::SSH do
231
218
  describe "#disable_password_auth!" do
232
219
  it "creates sshd config file to disable password authentication and restarts ssh" do
233
220
  expect(provision_server).to receive(:run!).with(
234
- %q{echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/disable_password_auth.conf && sudo service ssh restart},
221
+ %q{echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/disable_password_auth.conf; sudo service ssh restart},
235
222
  home: true
236
223
  )
237
224
 
@@ -16,8 +16,7 @@ describe Bard::Provision::Swapfile do
16
16
 
17
17
  describe "#call" do
18
18
  it "sets up swapfile on the server" do
19
- expect(provision_server).to receive(:run!).with(/if \[ ! -f \/swapfile \]/, home: true).ordered
20
- expect(provision_server).to receive(:run!).with("sudo swapon --show | grep -q /swapfile", home: true).ordered
19
+ expect(provision_server).to receive(:run!).with(/if \[ ! -f \/swapfile \]/)
21
20
 
22
21
  swapfile.call
23
22
  end
@@ -40,18 +40,14 @@ describe Bard::SSHServer do
40
40
  end
41
41
 
42
42
  describe "#ssh_uri" do
43
- it "returns a URI object" do
43
+ it "returns the SSH connection string" do
44
44
  server = described_class.new("deploy@example.com:22")
45
- expect(server.ssh_uri).to be_a(URI::Generic)
46
- expect(server.ssh_uri.scheme).to eq("ssh")
47
- expect(server.ssh_uri.user).to eq("deploy")
48
- expect(server.ssh_uri.host).to eq("example.com")
49
- expect(server.ssh_uri.port).to eq(22)
45
+ expect(server.ssh_uri).to eq("deploy@example.com:22")
50
46
  end
51
47
 
52
48
  it "includes port if non-standard" do
53
49
  server = described_class.new("deploy@example.com:2222")
54
- expect(server.ssh_uri.port).to eq(2222)
50
+ expect(server.ssh_uri).to eq("deploy@example.com:2222")
55
51
  end
56
52
  end
57
53
 
@@ -81,7 +77,7 @@ describe Bard::SSHServer do
81
77
 
82
78
  it "executes command via SSH" do
83
79
  expect(Open3).to receive(:capture3)
84
- .with(/ssh.*deploy@example.com.*cd.+\/app.+ls/)
80
+ .with(/ssh.*deploy@example.com.*cd \/app && ls/)
85
81
  .and_return(["output", "", 0])
86
82
 
87
83
  server.run("ls")
@@ -94,7 +90,7 @@ describe Bard::SSHServer do
94
90
  )
95
91
 
96
92
  expect(Open3).to receive(:capture3)
97
- .with(/RAILS_ENV.*production/)
93
+ .with(/RAILS_ENV=production/)
98
94
  .and_return(["output", "", 0])
99
95
 
100
96
  server_with_env.run("ls")
@@ -108,7 +104,7 @@ describe Bard::SSHServer do
108
104
 
109
105
  it "executes command via SSH" do
110
106
  expect(Open3).to receive(:capture3)
111
- .with(/ssh.*deploy@example.com.*cd.+\/app.+ls/)
107
+ .with(/ssh.*deploy@example.com.*cd \/app && ls/)
112
108
  .and_return(["output", "", 0])
113
109
 
114
110
  server.run!("ls")
@@ -129,7 +125,7 @@ describe Bard::SSHServer do
129
125
 
130
126
  it "replaces current process with SSH command" do
131
127
  expect(server).to receive(:exec)
132
- .with(/ssh.*deploy@example.com.*cd.+\/app.+ls/)
128
+ .with(/ssh.*deploy@example.com.*cd \/app && ls/)
133
129
 
134
130
  server.exec!("ls")
135
131
  end
@@ -140,7 +136,7 @@ describe Bard::SSHServer do
140
136
  server = described_class.new("deploy@example.com:22", path: "/var/www/app")
141
137
 
142
138
  expect(Open3).to receive(:capture3)
143
- .with(/cd.+\/var\/www\/app.+ls/)
139
+ .with(/cd \/var\/www\/app && ls/)
144
140
  .and_return(["output", "", 0])
145
141
 
146
142
  server.run("ls")
@@ -37,11 +37,7 @@ describe Bard::Target do
37
37
  end
38
38
 
39
39
  it "parses SSH URI" do
40
- expect(target.ssh_uri).to be_a(URI::Generic)
41
- expect(target.ssh_uri.scheme).to eq("ssh")
42
- expect(target.ssh_uri.user).to eq("deploy")
43
- expect(target.ssh_uri.host).to eq("example.com")
44
- expect(target.ssh_uri.port).to eq(22)
40
+ expect(target.ssh_uri).to eq("deploy@example.com:22")
45
41
  end
46
42
  end
47
43
 
@@ -76,7 +72,7 @@ describe Bard::Target do
76
72
  end
77
73
 
78
74
  it "auto-configures ping URL from hostname" do
79
- expect(target.ping_urls).to include("https://example.com")
75
+ expect(target.ping_urls).to include("example.com")
80
76
  end
81
77
  end
82
78
 
@@ -141,7 +137,7 @@ describe Bard::Target do
141
137
 
142
138
  it "executes command on remote server" do
143
139
  expect(Bard::Command).to receive(:run!)
144
- .with("ls", on: target, home: false, verbose: false, quiet: false)
140
+ .with("ls", on: target.server, home: false, verbose: false, quiet: false)
145
141
  target.run!("ls")
146
142
  end
147
143
  end
@@ -155,7 +151,7 @@ describe Bard::Target do
155
151
 
156
152
  it "executes command on remote server without raising" do
157
153
  expect(Bard::Command).to receive(:run)
158
- .with("ls", on: target, home: false, verbose: false, quiet: false)
154
+ .with("ls", on: target.server, home: false, verbose: false, quiet: false)
159
155
  target.run("ls")
160
156
  end
161
157
  end
@@ -169,7 +165,7 @@ describe Bard::Target do
169
165
 
170
166
  it "replaces process with remote command" do
171
167
  expect(Bard::Command).to receive(:exec!)
172
- .with("ls", on: target, home: false)
168
+ .with("ls", on: target.server, home: false)
173
169
  target.exec!("ls")
174
170
  end
175
171
  end
data/spec/spec_helper.rb CHANGED
@@ -1,10 +1,5 @@
1
1
  require "simplecov"
2
- SimpleCov.start do
3
- command_name "RSpec"
4
- track_files "lib/**/*.rb"
5
- add_filter "spec/"
6
- add_filter "features/"
7
- end
2
+ SimpleCov.start
8
3
 
9
4
  require "webmock/rspec"
10
5
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bard
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.6
4
+ version: 2.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Micah Geisel
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-03-07 00:00:00.000000000 Z
10
+ date: 2025-12-18 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: thor
@@ -161,27 +161,31 @@ files:
161
161
  - ".gitmodules"
162
162
  - ".rspec"
163
163
  - ARCHITECTURE.md
164
- - CLAUDE.md
165
164
  - CUSTOM_STRATEGIES.md
166
165
  - Gemfile
167
166
  - LICENSE
168
167
  - MIGRATION_GUIDE.md
169
- - PLUGINS.md
170
168
  - README.md
169
+ - README.rdoc
171
170
  - Rakefile
172
171
  - bard.gemspec
173
172
  - bin/bard
174
173
  - bin/setup
175
- - cucumber.yml
176
- - features/ci.feature
177
- - features/data.feature
178
- - features/deploy.feature
179
- - features/deploy_git_workflow.feature
180
- - features/run.feature
181
- - features/step_definitions/bard_steps.rb
182
- - features/support/bard-coverage
174
+ - features/bard_check.feature
175
+ - features/bard_deploy.feature
176
+ - features/bard_pull.feature
177
+ - features/bard_push.feature
178
+ - features/podman_testcontainers.feature
179
+ - features/step_definitions/check_steps.rb
180
+ - features/step_definitions/git_steps.rb
181
+ - features/step_definitions/global_steps.rb
182
+ - features/step_definitions/podman_steps.rb
183
+ - features/step_definitions/rails_steps.rb
184
+ - features/step_definitions/submodule_steps.rb
183
185
  - features/support/env.rb
184
- - features/support/test_server.rb
186
+ - features/support/grit_ext.rb
187
+ - features/support/io.rb
188
+ - features/support/podman.rb
185
189
  - install_files/.github/dependabot.yml
186
190
  - install_files/.github/workflows/cache-ci.yml
187
191
  - install_files/.github/workflows/ci.yml
@@ -223,21 +227,10 @@ files:
223
227
  - lib/bard/deploy_strategy.rb
224
228
  - lib/bard/deploy_strategy/github_pages.rb
225
229
  - lib/bard/deploy_strategy/ssh.rb
226
- - lib/bard/deprecation.rb
227
230
  - lib/bard/git.rb
228
231
  - lib/bard/github.rb
229
232
  - lib/bard/github_pages.rb
230
233
  - lib/bard/ping.rb
231
- - lib/bard/plugin.rb
232
- - lib/bard/plugins/backup.rb
233
- - lib/bard/plugins/github_pages.rb
234
- - lib/bard/plugins/hurt.rb
235
- - lib/bard/plugins/install.rb
236
- - lib/bard/plugins/jenkins.rb
237
- - lib/bard/plugins/new.rb
238
- - lib/bard/plugins/ping.rb
239
- - lib/bard/plugins/provision.rb
240
- - lib/bard/plugins/vim.rb
241
234
  - lib/bard/provision.rb
242
235
  - lib/bard/provision/app.rb
243
236
  - lib/bard/provision/apt.rb
@@ -254,7 +247,6 @@ files:
254
247
  - lib/bard/provision/ssh.rb
255
248
  - lib/bard/provision/swapfile.rb
256
249
  - lib/bard/provision/user.rb
257
- - lib/bard/secrets.rb
258
250
  - lib/bard/server.rb
259
251
  - lib/bard/ssh_server.rb
260
252
  - lib/bard/target.rb
@@ -265,8 +257,6 @@ files:
265
257
  - spec/acceptance/docker/test_key.pub
266
258
  - spec/bard/capability_spec.rb
267
259
  - spec/bard/ci/github_actions_spec.rb
268
- - spec/bard/ci/jenkins_spec.rb
269
- - spec/bard/ci/runner_spec.rb
270
260
  - spec/bard/ci_spec.rb
271
261
  - spec/bard/cli/ci_spec.rb
272
262
  - spec/bard/cli/command_spec.rb
@@ -289,13 +279,11 @@ files:
289
279
  - spec/bard/copy_spec.rb
290
280
  - spec/bard/deploy_strategy/ssh_spec.rb
291
281
  - spec/bard/deploy_strategy_spec.rb
292
- - spec/bard/deprecation_spec.rb
293
282
  - spec/bard/dynamic_dsl_spec.rb
294
283
  - spec/bard/git_spec.rb
295
284
  - spec/bard/github_pages_spec.rb
296
285
  - spec/bard/github_spec.rb
297
286
  - spec/bard/ping_spec.rb
298
- - spec/bard/plugin_spec.rb
299
287
  - spec/bard/provision/app_spec.rb
300
288
  - spec/bard/provision/apt_spec.rb
301
289
  - spec/bard/provision/authorizedkeys_spec.rb
@@ -341,23 +329,27 @@ rubygems_version: 3.6.2
341
329
  specification_version: 4
342
330
  summary: CLI to automate common development tasks.
343
331
  test_files:
344
- - features/ci.feature
345
- - features/data.feature
346
- - features/deploy.feature
347
- - features/deploy_git_workflow.feature
348
- - features/run.feature
349
- - features/step_definitions/bard_steps.rb
350
- - features/support/bard-coverage
332
+ - features/bard_check.feature
333
+ - features/bard_deploy.feature
334
+ - features/bard_pull.feature
335
+ - features/bard_push.feature
336
+ - features/podman_testcontainers.feature
337
+ - features/step_definitions/check_steps.rb
338
+ - features/step_definitions/git_steps.rb
339
+ - features/step_definitions/global_steps.rb
340
+ - features/step_definitions/podman_steps.rb
341
+ - features/step_definitions/rails_steps.rb
342
+ - features/step_definitions/submodule_steps.rb
351
343
  - features/support/env.rb
352
- - features/support/test_server.rb
344
+ - features/support/grit_ext.rb
345
+ - features/support/io.rb
346
+ - features/support/podman.rb
353
347
  - spec/acceptance/.gitignore
354
348
  - spec/acceptance/docker/Dockerfile
355
349
  - spec/acceptance/docker/test_key
356
350
  - spec/acceptance/docker/test_key.pub
357
351
  - spec/bard/capability_spec.rb
358
352
  - spec/bard/ci/github_actions_spec.rb
359
- - spec/bard/ci/jenkins_spec.rb
360
- - spec/bard/ci/runner_spec.rb
361
353
  - spec/bard/ci_spec.rb
362
354
  - spec/bard/cli/ci_spec.rb
363
355
  - spec/bard/cli/command_spec.rb
@@ -380,13 +372,11 @@ test_files:
380
372
  - spec/bard/copy_spec.rb
381
373
  - spec/bard/deploy_strategy/ssh_spec.rb
382
374
  - spec/bard/deploy_strategy_spec.rb
383
- - spec/bard/deprecation_spec.rb
384
375
  - spec/bard/dynamic_dsl_spec.rb
385
376
  - spec/bard/git_spec.rb
386
377
  - spec/bard/github_pages_spec.rb
387
378
  - spec/bard/github_spec.rb
388
379
  - spec/bard/ping_spec.rb
389
- - spec/bard/plugin_spec.rb
390
380
  - spec/bard/provision/app_spec.rb
391
381
  - spec/bard/provision/apt_spec.rb
392
382
  - spec/bard/provision/authorizedkeys_spec.rb
data/CLAUDE.md DELETED
@@ -1,76 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## What is Bard?
6
-
7
- Bard is a modular deployment CLI tool for Ruby applications. It provides:
8
- - SSH-based deployment via git pull
9
- - GitHub Pages static site deployment
10
- - Custom pluggable deployment strategies
11
- - Data syncing (database dumps and file rsync)
12
- - CI integration (GitHub Actions/Jenkins)
13
- - Server provisioning
14
-
15
- ## Development Commands
16
-
17
- ```bash
18
- # Install dependencies
19
- bundle install
20
-
21
- # Run all tests (RSpec + Cucumber)
22
- bundle exec rake
23
-
24
- # Run only RSpec tests
25
- bundle exec rspec
26
-
27
- # Run a single spec file
28
- bundle exec rspec spec/bard/target_spec.rb
29
-
30
- # Run a specific test by line number
31
- bundle exec rspec spec/bard/target_spec.rb:42
32
-
33
- # Run Cucumber features (slow - avoid full suite)
34
- bundle exec cucumber features/deploy.feature
35
-
36
- # Run bard from source
37
- bundle exec bin/bard
38
- ```
39
-
40
- ## Architecture
41
-
42
- ### Core Classes
43
-
44
- - **`Bard::CLI`** (`lib/bard/cli.rb`) - Thor-based command dispatcher. Commands are modules in `lib/bard/cli/` included into CLI.
45
- - **`Bard::Config`** (`lib/bard/config.rb`) - DSL parser for `bard.rb` files. Manages targets and settings.
46
- - **`Bard::Target`** (`lib/bard/target.rb`) - Deployment destination with capabilities (ssh, ping, data). Supports dynamic strategy DSL via `method_missing`.
47
- - **`Bard::Server`** (`lib/bard/server.rb`) - Legacy v1.x server representation (deprecated, use Target).
48
- - **`Bard::DeployStrategy`** (`lib/bard/deploy_strategy.rb`) - Base class for deployment strategies. Subclasses auto-register via Ruby's `inherited` hook.
49
-
50
- ### Capability System
51
-
52
- Targets track enabled capabilities (`:ssh`, `:ping`, `:github_pages`, etc.). Commands call `require_capability!` to ensure the target supports the operation.
53
-
54
- ### Strategy Auto-Registration
55
-
56
- Custom strategies subclass `DeployStrategy` and are automatically registered by class name:
57
- ```ruby
58
- class Bard::DeployStrategy::Jets < DeployStrategy # registers as :jets
59
- def deploy; ...; end
60
- end
61
- ```
62
-
63
- ### File Organization
64
-
65
- - `lib/bard/cli/*.rb` - CLI command modules (deploy, data, ssh, etc.)
66
- - `lib/bard/ci/*.rb` - CI system integrations (github_actions, jenkins, local)
67
- - `lib/bard/deploy_strategy/*.rb` - Built-in strategies (ssh, github_pages)
68
- - `lib/bard/provision/*.rb` - Server provisioning modules
69
- - `spec/` - RSpec unit tests
70
- - `features/` - Cucumber integration tests
71
-
72
- ## Testing Notes
73
-
74
- - Use `focus: true` in RSpec to run specific tests
75
- - Cucumber tests use testcontainers and are slow - run specific feature files only
76
- - SimpleCov tracks coverage across both RSpec and Cucumber runs
data/PLUGINS.md DELETED
@@ -1,114 +0,0 @@
1
- # Plugin Development
2
-
3
- Bard uses a plugin system to extend functionality. Plugins can add CLI commands, target methods, and config DSL methods.
4
-
5
- ## Plugin Structure
6
-
7
- Plugins live in `lib/bard/plugins/` and register themselves:
8
-
9
- ```ruby
10
- # lib/bard/plugins/my_plugin.rb
11
- require "bard/plugin"
12
-
13
- Bard::Plugin.register :my_plugin do
14
- # Add CLI commands (class must implement .setup)
15
- cli "Bard::CLI::MyPlugin", require: "bard/cli/my_plugin"
16
-
17
- # Add methods to Target
18
- target_method :my_feature do |url = nil|
19
- if url.nil?
20
- @my_feature_url
21
- else
22
- @my_feature_url = url
23
- enable_capability(:my_feature)
24
- end
25
- end
26
-
27
- # Add methods to Config
28
- config_method :my_global_setting do |value = nil|
29
- if value.nil?
30
- @my_global_setting
31
- else
32
- @my_global_setting = value
33
- end
34
- end
35
- end
36
- ```
37
-
38
- ## CLI Commands
39
-
40
- CLI commands inherit from `Bard::CLI::Command` and implement a `setup` class method:
41
-
42
- ```ruby
43
- # lib/bard/cli/my_plugin.rb
44
- require "bard/cli/command"
45
-
46
- class Bard::CLI::MyPlugin < Bard::CLI::Command
47
- desc "mycommand", "Description of my command"
48
- def mycommand
49
- puts "Hello from my plugin!"
50
- end
51
- end
52
- ```
53
-
54
- The `Command` base class provides:
55
- - Automatic `setup` that registers the command with the CLI
56
- - Delegation to the CLI instance (access to `config`, `project_name`, etc.)
57
- - `desc` and `option` class methods for Thor integration
58
-
59
- For Thor subcommand groups (nested under `bard mygroup`):
60
-
61
- ```ruby
62
- # lib/bard/cli/my_subcommand.rb
63
- class Bard::CLI::MySubcommand < Thor
64
- def self.setup(cli)
65
- cli.register(self, "mygroup", "mygroup COMMAND", "My subcommand group")
66
- end
67
-
68
- desc "action", "Do something"
69
- def action
70
- puts "Hello from subcommand!"
71
- end
72
- end
73
- ```
74
-
75
- ## Adding Strategies
76
-
77
- Plugins can add deployment strategies or CI runners:
78
-
79
- ```ruby
80
- # Custom deploy strategy
81
- module Bard
82
- class DeployStrategy
83
- class MyCloud < DeployStrategy
84
- def deploy
85
- # Deployment logic here
86
- run! "my-cloud deploy #{target.key}"
87
- end
88
- end
89
- end
90
- end
91
-
92
- # Custom CI runner
93
- module Bard
94
- class CI
95
- class Runner
96
- class MyCI < Runner
97
- def run
98
- # Start CI run
99
- end
100
-
101
- def status
102
- # Return current status
103
- end
104
- end
105
- end
106
- end
107
- end
108
- ```
109
-
110
- Strategies auto-register via Ruby's `inherited` hook. The class name determines the strategy key (e.g., `MyCloud` → `:my_cloud`).
111
-
112
- ## Plugin Loading
113
-
114
- Plugins are loaded automatically from `lib/bard/plugins/`. The load order is alphabetical by filename. For CI runners, the last registered runner becomes the default.
data/cucumber.yml DELETED
@@ -1 +0,0 @@
1
- default: --publish-quiet
data/features/ci.feature DELETED
@@ -1,62 +0,0 @@
1
- Feature: bard ci
2
- Run continuous integration tests.
3
-
4
- Background:
5
- Given a test server is running
6
-
7
- Scenario: no CI configured error
8
- When I run expecting failure: bard ci
9
- Then the output should contain "No CI found"
10
- And the output should contain "Re-run with --skip-ci to bypass CI"
11
-
12
- Scenario: local CI runs successfully
13
- Given a local CI script that passes
14
- When I run: bard ci --local-ci
15
- Then the output should contain "Continuous integration: starting build"
16
- And the output should contain "Continuous integration: success!"
17
-
18
- Scenario: local CI reports failure
19
- Given a local CI script that fails with "Test failed: expected 1 but got 2"
20
- When I run expecting failure: bard ci --local-ci
21
- Then the output should contain "Test failed: expected 1 but got 2"
22
- And the output should contain "Automated tests failed!"
23
-
24
- Scenario: --ci option runs specified CI runner
25
- Given a local CI script that passes
26
- When I run: bard ci --ci=local
27
- Then the output should contain "Continuous integration: starting build"
28
- And the output should contain "Continuous integration: success!"
29
-
30
- Scenario: --ci option reports failure from specified runner
31
- Given a local CI script that fails with "Custom runner failed"
32
- When I run expecting failure: bard ci --ci=local
33
- Then the output should contain "Custom runner failed"
34
- And the output should contain "Automated tests failed!"
35
-
36
- Scenario: deploy passes --ci option to CI
37
- Given a local CI script that passes
38
- And I create a file "ci-option-test.txt" with content "ci option test"
39
- And I commit the changes with message "Add CI option test file"
40
- When I run: bard deploy --ci=local
41
- Then the output should contain "Continuous integration: starting build"
42
- And the output should contain "Continuous integration: success!"
43
- And the output should contain "Deploy Succeeded"
44
-
45
- Scenario: deploy runs CI before deploying
46
- Given a local CI script that passes
47
- And I create a file "ci-test.txt" with content "ci test"
48
- And I commit the changes with message "Add CI test file"
49
- When I run: bard deploy --local-ci
50
- Then the output should contain "Continuous integration: starting build"
51
- And the output should contain "Continuous integration: success!"
52
- And the output should contain "Deploy Succeeded"
53
-
54
- Scenario: deploy aborts if CI fails
55
- Given a local CI script that fails with "Build failed"
56
- And I create a file "ci-fail.txt" with content "ci fail test"
57
- And I commit the changes with message "Add CI fail test file"
58
- When I run expecting failure: bard deploy --local-ci
59
- Then the output should contain "Continuous integration: starting build"
60
- And the output should contain "Build failed"
61
- And the output should contain "Automated tests failed!"
62
- And the output should not contain "Deploy Succeeded"
@@ -1,12 +0,0 @@
1
- Feature: bard data
2
- Copy database from a remote server to local.
3
-
4
- Background:
5
- Given a test server is running
6
-
7
- Scenario: copies database from production to local
8
- When I run: bard data
9
- Then the output should contain "Dumping production database to file"
10
- And the output should contain "Transfering file from production to local"
11
- And the output should contain "Loading file into local database"
12
- And a file "db/data.sql.gz" should exist locally