bard 2.2.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +7 -487
- data/Rakefile +1 -4
- data/bard.gemspec +2 -11
- data/lib/bard/config.rb +22 -20
- data/lib/bard/plugins/ping/target_methods.rb +0 -9
- data/lib/bard/plugins/ssh/connection.rb +2 -35
- data/lib/bard/target.rb +0 -15
- data/lib/bard/version.rb +1 -1
- data/lib/bard.rb +2 -1
- data/spec/bard/capability_spec.rb +0 -8
- data/spec/bard/config_spec.rb +30 -67
- data/spec/bard/target_spec.rb +1 -36
- metadata +4 -225
- data/ARCHITECTURE.md +0 -957
- data/CUSTOM_STRATEGIES.md +0 -701
- data/MIGRATION_GUIDE.md +0 -513
- data/PLUGINS.md +0 -99
- data/bin/bard +0 -4
- data/features/ci.feature +0 -63
- data/features/data.feature +0 -13
- data/features/deploy.feature +0 -14
- data/features/deploy_git_workflow.feature +0 -89
- data/features/run.feature +0 -14
- data/features/step_definitions/bard_steps.rb +0 -136
- data/features/support/bard-coverage +0 -16
- data/features/support/env.rb +0 -22
- data/features/support/test_server.rb +0 -216
- data/lib/bard/cli.rb +0 -44
- data/lib/bard/command.rb +0 -31
- data/lib/bard/copy.rb +0 -45
- data/lib/bard/plugins/data.rb +0 -56
- data/lib/bard/plugins/deploy/ci/github_actions.rb +0 -202
- data/lib/bard/plugins/deploy/ci/jenkins.rb +0 -176
- data/lib/bard/plugins/deploy/ci/local.rb +0 -57
- data/lib/bard/plugins/deploy/ci/runner.rb +0 -112
- data/lib/bard/plugins/deploy/ci/state.rb +0 -40
- data/lib/bard/plugins/deploy/ci.rb +0 -38
- data/lib/bard/plugins/deploy/ssh_strategy.rb +0 -26
- data/lib/bard/plugins/deploy/strategy.rb +0 -60
- data/lib/bard/plugins/deploy.rb +0 -260
- data/lib/bard/plugins/git.rb +0 -45
- data/lib/bard/plugins/github.rb +0 -152
- data/lib/bard/plugins/github_pages/strategy.rb +0 -170
- data/lib/bard/plugins/github_pages.rb +0 -35
- data/lib/bard/plugins/hurt.rb +0 -13
- data/lib/bard/plugins/install/.github/dependabot.yml +0 -18
- data/lib/bard/plugins/install/.github/workflows/cache-ci.yml +0 -15
- data/lib/bard/plugins/install/.github/workflows/ci.yml +0 -74
- data/lib/bard/plugins/install/apt_dependencies.rb +0 -33
- data/lib/bard/plugins/install/ci +0 -5
- data/lib/bard/plugins/install/setup +0 -13
- data/lib/bard/plugins/install/specified_bundler.rb +0 -15
- data/lib/bard/plugins/install/specified_ruby.rb +0 -59
- data/lib/bard/plugins/install.rb +0 -9
- data/lib/bard/plugins/open.rb +0 -20
- data/lib/bard/plugins/ping/check.rb +0 -66
- data/lib/bard/plugins/ping.rb +0 -10
- data/lib/bard/plugins/run.rb +0 -19
- data/lib/bard/plugins/setup.rb +0 -75
- data/lib/bard/plugins/ssh/copy.rb +0 -95
- data/lib/bard/plugins/ssh.rb +0 -10
- data/lib/bard/plugins/vim.rb +0 -6
- data/lib/bard/retryable.rb +0 -25
- data/lib/bard/secrets.rb +0 -10
- data/spec/acceptance/.gitignore +0 -4
- data/spec/acceptance/docker/Dockerfile +0 -36
- data/spec/acceptance/docker/test_key +0 -27
- data/spec/acceptance/docker/test_key.pub +0 -1
- data/spec/bard/ci/github_actions_spec.rb +0 -138
- data/spec/bard/ci/jenkins_spec.rb +0 -139
- data/spec/bard/ci/runner_spec.rb +0 -61
- data/spec/bard/ci_spec.rb +0 -10
- data/spec/bard/cli/ci_spec.rb +0 -170
- data/spec/bard/cli/data_spec.rb +0 -58
- data/spec/bard/cli/deploy_spec.rb +0 -243
- data/spec/bard/cli/hurt_spec.rb +0 -17
- data/spec/bard/cli/install_spec.rb +0 -19
- data/spec/bard/cli/master_key_spec.rb +0 -38
- data/spec/bard/cli/open_spec.rb +0 -51
- data/spec/bard/cli/ping_spec.rb +0 -32
- data/spec/bard/cli/run_spec.rb +0 -57
- data/spec/bard/cli/setup_spec.rb +0 -99
- data/spec/bard/cli/ssh_spec.rb +0 -40
- data/spec/bard/cli/stage_spec.rb +0 -127
- data/spec/bard/cli/vim_spec.rb +0 -28
- data/spec/bard/command_spec.rb +0 -30
- data/spec/bard/copy_spec.rb +0 -69
- data/spec/bard/deploy_strategy/github_pages_spec.rb +0 -58
- data/spec/bard/deploy_strategy/ssh_spec.rb +0 -135
- data/spec/bard/deploy_strategy_spec.rb +0 -107
- data/spec/bard/dynamic_dsl_spec.rb +0 -46
- data/spec/bard/git_spec.rb +0 -101
- data/spec/bard/github_spec.rb +0 -45
- data/spec/bard/ping_spec.rb +0 -60
- data/spec/bard/ssh_copy_spec.rb +0 -44
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6e59f0686a010077d3980ceea61597d7c3bac7bd60358110c0e180990df10afc
|
|
4
|
+
data.tar.gz: 7e4ef9ac960e6fb28e7e465357e9edaa806bad6b537f580c3eb86ed1ef271e50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2f1d8d605e8331cc5375170e1206eb3d5a4c665603f9556ce2d2823ee240b867b667695f38084dafa732dce1dd44a58a890d57b48365cdb09197d308321edb16
|
|
7
|
+
data.tar.gz: 56381e180c1d9a65d9f990023bbd23867793a82b77007de941fd3e70d674cd3cd6c5df237c7be61382030ba03711513276411f9c2a77e28a662d159e1781808f
|
data/README.md
CHANGED
|
@@ -1,497 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# bard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The config core of the bard toolchain: the `bard.rb` DSL parser plus the target and SSH primitives everything else is built upon.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## What's here
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
end
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
```bash
|
|
15
|
-
bard deploy
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Features
|
|
19
|
-
|
|
20
|
-
- **Modular Capabilities**: Enable only the features you need
|
|
21
|
-
- **Pluggable Strategies**: SSH, GitHub Pages, or create your own
|
|
22
|
-
- **Default Targets**: Pre-configured for common Bot and Rose workflows
|
|
23
|
-
- **Git Integration**: Built-in branch management and safety checks
|
|
24
|
-
- **CI Integration**: Auto-detects GitHub Actions or Jenkins
|
|
25
|
-
- **Data Syncing**: Copy databases and assets between targets
|
|
26
|
-
|
|
27
|
-
## Installation
|
|
28
|
-
|
|
29
|
-
Add to your Gemfile:
|
|
30
|
-
|
|
31
|
-
```ruby
|
|
32
|
-
gem 'bard'
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Or install globally:
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
gem install bard
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
## Core Concepts
|
|
42
|
-
|
|
43
|
-
### Targets
|
|
44
|
-
|
|
45
|
-
A **target** is a deployment destination. Targets can be servers, serverless environments, static hosting, or anything else you can deploy to.
|
|
46
|
-
|
|
47
|
-
```ruby
|
|
48
|
-
target :production do
|
|
49
|
-
ssh "deploy@example.com:22", path: "app"
|
|
50
|
-
end
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
### Capabilities
|
|
54
|
-
|
|
55
|
-
Capabilities are features enabled on targets. Common capabilities include:
|
|
56
|
-
|
|
57
|
-
- **SSH**: Remote command execution and file transfer
|
|
58
|
-
- **Ping**: Health check URLs
|
|
59
|
-
- **Data**: Database and file syncing
|
|
60
|
-
- **Backup**: Automatic backups during deployment
|
|
61
|
-
|
|
62
|
-
### Deployment Strategies
|
|
63
|
-
|
|
64
|
-
Strategies determine how code gets deployed. Built-in strategies:
|
|
65
|
-
|
|
66
|
-
- **SSH**: Deploy via git pull on remote server
|
|
67
|
-
- **GitHub Pages**: Deploy static site to gh-pages branch
|
|
68
|
-
- **Custom**: Define your own (Jets, Docker, Kubernetes, etc.)
|
|
69
|
-
|
|
70
|
-
## Configuration
|
|
71
|
-
|
|
72
|
-
Create a `bard.rb` file in your project root:
|
|
73
|
-
|
|
74
|
-
```ruby
|
|
75
|
-
# Simple SSH deployment
|
|
76
|
-
target :production do
|
|
77
|
-
ssh "deploy@example.com:22",
|
|
78
|
-
path: "app",
|
|
79
|
-
gateway: "bastion@example.com:22"
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# GitHub Pages static site
|
|
83
|
-
target :production do
|
|
84
|
-
github_pages "https://example.com"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Custom strategy (Jets serverless)
|
|
88
|
-
require_relative 'lib/jets_deploy_strategy'
|
|
89
|
-
|
|
90
|
-
target :production do
|
|
91
|
-
jets "https://api.example.com", run_tests: true
|
|
92
|
-
end
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
## Default Targets
|
|
96
|
-
|
|
97
|
-
Bard ships with default targets for Bot and Rose workflows. Override any in your `bard.rb`:
|
|
98
|
-
|
|
99
|
-
- **:local** - Local development (no SSH)
|
|
100
|
-
- **:ci** - Jenkins CI at staging.botandrose.com
|
|
101
|
-
- **:staging** - Staging server at staging.botandrose.com
|
|
102
|
-
- **:gubs** - Bot and Rose cloud server
|
|
103
|
-
|
|
104
|
-
```ruby
|
|
105
|
-
# Override default staging to use Jets
|
|
106
|
-
target :staging do
|
|
107
|
-
jets "https://staging-api.example.com"
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Keep :ci, :gubs, :local as defaults
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## Commands
|
|
114
|
-
|
|
115
|
-
### Deployment
|
|
116
|
-
|
|
117
|
-
```bash
|
|
118
|
-
# Deploy current branch to production (default)
|
|
119
|
-
bard deploy
|
|
120
|
-
|
|
121
|
-
# Deploy a specific branch to production
|
|
122
|
-
bard deploy feature-branch
|
|
123
|
-
|
|
124
|
-
# Deploy to a different target
|
|
125
|
-
bard deploy --target=staging
|
|
126
|
-
bard deploy feature-branch --target=staging
|
|
127
|
-
|
|
128
|
-
# Deploy feature branch to staging (no merge)
|
|
129
|
-
bard stage feature-branch
|
|
130
|
-
|
|
131
|
-
# Skip CI checks
|
|
132
|
-
bard deploy --skip-ci
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Data Management
|
|
136
|
-
|
|
137
|
-
```bash
|
|
138
|
-
# Copy database and assets from production to local
|
|
139
|
-
bard data --from=production --to=local
|
|
140
|
-
|
|
141
|
-
# Copy staging data to local
|
|
142
|
-
bard data --from=staging --to=local
|
|
143
|
-
|
|
144
|
-
# Configure additional paths to sync
|
|
145
|
-
# bard.rb:
|
|
146
|
-
data "public/uploads", "public/system"
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
### SSH Commands
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
# SSH into a target
|
|
153
|
-
bard ssh production
|
|
154
|
-
|
|
155
|
-
# Run a command on a target
|
|
156
|
-
bard run production "bundle exec rails console"
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### CI
|
|
160
|
-
|
|
161
|
-
```bash
|
|
162
|
-
# Run CI for current branch
|
|
163
|
-
bard ci
|
|
164
|
-
|
|
165
|
-
# Run tests locally
|
|
166
|
-
bard ci --local-ci
|
|
167
|
-
|
|
168
|
-
# Check CI status
|
|
169
|
-
bard ci --status
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
### Utilities
|
|
173
|
-
|
|
174
|
-
```bash
|
|
175
|
-
# Open target URL in browser
|
|
176
|
-
bard open production
|
|
177
|
-
|
|
178
|
-
# Ping target to check health
|
|
179
|
-
bard ping production
|
|
180
|
-
|
|
181
|
-
# Show uncommitted changes
|
|
182
|
-
bard hurt
|
|
183
|
-
|
|
184
|
-
# Open changed files in vim
|
|
185
|
-
bard vim
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
### Provisioning
|
|
189
|
-
|
|
190
|
-
```bash
|
|
191
|
-
# Full server provisioning
|
|
192
|
-
bard provision deploy@new-server.com:22
|
|
193
|
-
|
|
194
|
-
# Configure nginx for current app
|
|
195
|
-
bard setup
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## SSH Capability
|
|
199
|
-
|
|
200
|
-
Enable SSH to run commands and transfer files:
|
|
201
|
-
|
|
202
|
-
```ruby
|
|
203
|
-
target :production do
|
|
204
|
-
ssh "user@host:port",
|
|
205
|
-
path: "deploy/path",
|
|
206
|
-
gateway: "bastion@host:port",
|
|
207
|
-
ssh_key: "/path/to/key",
|
|
208
|
-
env: "RAILS_ENV=production"
|
|
209
|
-
end
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
This provides:
|
|
213
|
-
- `target.run!(command)` - Execute remote command (raises on error)
|
|
214
|
-
- `target.run(command)` - Execute remote command (silent on error)
|
|
215
|
-
- `target.exec!(command)` - Replace process with remote command
|
|
216
|
-
- `target.copy_file(path, to: target)` - Copy file to another target
|
|
217
|
-
- `target.copy_dir(path, to: target)` - Rsync directory to another target
|
|
218
|
-
|
|
219
|
-
## Deployment Strategies
|
|
220
|
-
|
|
221
|
-
### SSH Strategy
|
|
222
|
-
|
|
223
|
-
Deploy by running git pull on remote server:
|
|
224
|
-
|
|
225
|
-
```ruby
|
|
226
|
-
target :production do
|
|
227
|
-
ssh "deploy@example.com:22"
|
|
228
|
-
end
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
Deployment runs: `git pull origin master && bin/setup`
|
|
232
|
-
|
|
233
|
-
### GitHub Pages Strategy
|
|
234
|
-
|
|
235
|
-
Deploy static site to GitHub Pages:
|
|
236
|
-
|
|
237
|
-
```ruby
|
|
238
|
-
target :production do
|
|
239
|
-
github_pages "https://example.com"
|
|
240
|
-
end
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
Deployment:
|
|
244
|
-
1. Starts Rails server locally
|
|
245
|
-
2. Mirrors site with wget
|
|
246
|
-
3. Creates orphan commit with static assets
|
|
247
|
-
4. Force-pushes to `gh-pages` branch
|
|
248
|
-
|
|
249
|
-
### Custom Strategies
|
|
250
|
-
|
|
251
|
-
Create your own deployment strategy:
|
|
252
|
-
|
|
253
|
-
```ruby
|
|
254
|
-
# lib/jets_deploy_strategy.rb
|
|
255
|
-
module Bard
|
|
256
|
-
class DeployStrategy
|
|
257
|
-
class Jets < DeployStrategy
|
|
258
|
-
def deploy
|
|
259
|
-
target_name = target.key.to_s
|
|
260
|
-
options = target.strategy_options(:jets)
|
|
261
|
-
|
|
262
|
-
run! "rake vips:build:#{target_name}" unless options[:skip_build]
|
|
263
|
-
run! "bundle exec rspec" if should_run_tests?(target_name, options)
|
|
264
|
-
run! "jets deploy #{options[:env] || target_name}"
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
private
|
|
268
|
-
|
|
269
|
-
def should_run_tests?(target_name, options)
|
|
270
|
-
return options[:run_tests] if options.key?(:run_tests)
|
|
271
|
-
target_name == "production"
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Use it in your `bard.rb`:
|
|
279
|
-
|
|
280
|
-
```ruby
|
|
281
|
-
require_relative 'lib/jets_deploy_strategy'
|
|
282
|
-
|
|
283
|
-
target :production do
|
|
284
|
-
jets "https://api.example.com", run_tests: true
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
target :staging do
|
|
288
|
-
jets "https://staging-api.example.com", skip_build: true
|
|
289
|
-
end
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
Strategies auto-register via Ruby's `inherited` hook - no manual registration needed!
|
|
293
|
-
|
|
294
|
-
## CI Configuration
|
|
295
|
-
|
|
296
|
-
Bard auto-detects your CI system:
|
|
297
|
-
- Finds `.github/workflows/ci.yml` → GitHub Actions
|
|
298
|
-
- Otherwise → Jenkins (legacy)
|
|
299
|
-
|
|
300
|
-
Override via DSL:
|
|
301
|
-
|
|
302
|
-
```ruby
|
|
303
|
-
# Force specific CI system
|
|
304
|
-
ci :github_actions
|
|
305
|
-
ci :jenkins
|
|
306
|
-
ci :local
|
|
307
|
-
|
|
308
|
-
# Disable CI
|
|
309
|
-
ci false
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
## Ping Configuration
|
|
313
|
-
|
|
314
|
-
Configure health check URLs:
|
|
315
|
-
|
|
316
|
-
```ruby
|
|
317
|
-
target :production do
|
|
318
|
-
ssh "deploy@example.com:22"
|
|
319
|
-
ping "https://example.com", "/health", "/status"
|
|
320
|
-
end
|
|
321
|
-
```
|
|
322
|
-
|
|
323
|
-
Auto-configured by deployment strategies:
|
|
324
|
-
|
|
325
|
-
```ruby
|
|
326
|
-
# Ping URL automatically set from Jets URL
|
|
327
|
-
target :production do
|
|
328
|
-
jets "https://api.example.com"
|
|
329
|
-
end
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
## Data Syncing
|
|
333
|
-
|
|
334
|
-
Database syncing is enabled by default when SSH is configured. Add file paths to sync:
|
|
335
|
-
|
|
336
|
-
```ruby
|
|
337
|
-
# Global configuration
|
|
338
|
-
data "public/uploads", "public/system"
|
|
339
|
-
|
|
340
|
-
target :production do
|
|
341
|
-
ssh "deploy@example.com:22"
|
|
342
|
-
end
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
Then sync:
|
|
346
|
-
|
|
347
|
-
```bash
|
|
348
|
-
bard data --from=production --to=local
|
|
349
|
-
```
|
|
350
|
-
|
|
351
|
-
This:
|
|
352
|
-
1. Runs `bin/rake db:dump` on source
|
|
353
|
-
2. Copies `db/data.sql.gz` via SCP
|
|
354
|
-
3. Runs `bin/rake db:load` on destination
|
|
355
|
-
4. Rsyncs configured data paths
|
|
356
|
-
|
|
357
|
-
## Backup Configuration
|
|
358
|
-
|
|
359
|
-
Control whether backups are created during deployment:
|
|
360
|
-
|
|
361
|
-
```ruby
|
|
362
|
-
# Enable backups (default for SSH deployments)
|
|
363
|
-
backup true
|
|
364
|
-
|
|
365
|
-
# Disable backups (typical for serverless/static)
|
|
366
|
-
backup false
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
## Example Configurations
|
|
370
|
-
|
|
371
|
-
### Traditional Rails App
|
|
372
|
-
|
|
373
|
-
```ruby
|
|
374
|
-
target :staging do
|
|
375
|
-
ssh "deploy@staging.example.com:22"
|
|
376
|
-
end
|
|
377
|
-
|
|
378
|
-
target :production do
|
|
379
|
-
ssh "deploy@production.example.com:22"
|
|
380
|
-
end
|
|
381
|
-
|
|
382
|
-
data "public/uploads"
|
|
383
|
-
backup true
|
|
384
|
-
```
|
|
385
|
-
|
|
386
|
-
### Serverless API (Jets)
|
|
387
|
-
|
|
388
|
-
```ruby
|
|
389
|
-
require_relative 'lib/jets_deploy_strategy'
|
|
390
|
-
|
|
391
|
-
target :staging do
|
|
392
|
-
jets "https://staging-api.example.com"
|
|
393
|
-
end
|
|
394
|
-
|
|
395
|
-
target :production do
|
|
396
|
-
jets "https://api.example.com", run_tests: true
|
|
397
|
-
end
|
|
398
|
-
|
|
399
|
-
backup false
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
### Hybrid (Jets + SSH for debugging)
|
|
403
|
-
|
|
404
|
-
```ruby
|
|
405
|
-
require_relative 'lib/jets_deploy_strategy'
|
|
406
|
-
|
|
407
|
-
target :staging do
|
|
408
|
-
jets "https://staging-api.example.com"
|
|
409
|
-
ssh "deploy@bastion.example.com:22" # Enables SSH commands
|
|
410
|
-
end
|
|
411
|
-
|
|
412
|
-
target :production do
|
|
413
|
-
jets "https://api.example.com"
|
|
414
|
-
# No SSH in production
|
|
415
|
-
end
|
|
416
|
-
|
|
417
|
-
backup false
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
### Static Site
|
|
421
|
-
|
|
422
|
-
```ruby
|
|
423
|
-
target :production do
|
|
424
|
-
github_pages "https://example.com"
|
|
425
|
-
end
|
|
426
|
-
|
|
427
|
-
backup false
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
### Override Default Targets
|
|
431
|
-
|
|
432
|
-
```ruby
|
|
433
|
-
# Override default staging to use Jets
|
|
434
|
-
target :staging do
|
|
435
|
-
jets "https://staging-api.example.com"
|
|
436
|
-
end
|
|
437
|
-
|
|
438
|
-
# Keep :ci, :gubs, :local targets as defaults
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
## Migration from v1.x
|
|
442
|
-
|
|
443
|
-
See [MIGRATION_GUIDE.md](MIGRATION_GUIDE.md) for detailed migration instructions.
|
|
444
|
-
|
|
445
|
-
Key changes in v2.0:
|
|
446
|
-
- `server` renamed to `target`
|
|
447
|
-
- SSH configuration uses hash options
|
|
448
|
-
- Strategy-first configuration
|
|
449
|
-
- Capability-based commands
|
|
450
|
-
|
|
451
|
-
## Architecture
|
|
452
|
-
|
|
453
|
-
Bard follows a modular, capability-based architecture:
|
|
454
|
-
|
|
455
|
-
- **Core**: Minimal git workflow and configuration
|
|
456
|
-
- **Capabilities**: Features enabled via DSL methods
|
|
457
|
-
- **Strategies**: Pluggable deployment strategies with auto-registration
|
|
458
|
-
- **Subsystems**: Independent and composable
|
|
459
|
-
|
|
460
|
-
See [ARCHITECTURE.md](ARCHITECTURE.md) for detailed architecture documentation.
|
|
461
|
-
|
|
462
|
-
## Custom Strategy Guide
|
|
463
|
-
|
|
464
|
-
See [CUSTOM_STRATEGIES.md](CUSTOM_STRATEGIES.md) for a step-by-step guide to creating custom deployment strategies.
|
|
465
|
-
|
|
466
|
-
## Plugin Development
|
|
467
|
-
|
|
468
|
-
See [PLUGINS.md](PLUGINS.md) for a guide to creating plugins.
|
|
7
|
+
- `Bard::Config` — parses `bard.rb`
|
|
8
|
+
- `Bard::Target` / `Bard::SSHServer` — deployment targets and connection details
|
|
9
|
+
- `Bard::Command` — SSH command execution
|
|
10
|
+
- the `ssh` / `ping` / `url` / `data` / `github_pages` / `ci` DSL declarations
|
|
469
11
|
|
|
470
12
|
## Development
|
|
471
13
|
|
|
472
14
|
```bash
|
|
473
|
-
# Clone repository
|
|
474
|
-
git clone https://github.com/botandrose/bard.git
|
|
475
|
-
cd bard
|
|
476
|
-
|
|
477
|
-
# Install dependencies
|
|
478
15
|
bundle install
|
|
479
|
-
|
|
480
|
-
# Run tests
|
|
481
16
|
bundle exec rspec
|
|
482
|
-
|
|
483
|
-
# Run bard from source
|
|
484
|
-
bundle exec bin/bard
|
|
485
17
|
```
|
|
486
|
-
|
|
487
|
-
## License
|
|
488
|
-
|
|
489
|
-
MIT License. Copyright (c) 2018 Micah Geisel. See LICENSE for details.
|
|
490
|
-
|
|
491
|
-
## Contributing
|
|
492
|
-
|
|
493
|
-
1. Fork it
|
|
494
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
495
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
496
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
|
497
|
-
5. Create new Pull Request
|
data/Rakefile
CHANGED
data/bard.gemspec
CHANGED
|
@@ -8,25 +8,16 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.version = Bard::VERSION
|
|
9
9
|
spec.authors = ["Micah Geisel"]
|
|
10
10
|
spec.email = ["micah@botandrose.com"]
|
|
11
|
-
spec.summary = "
|
|
11
|
+
spec.summary = "Config core for bard."
|
|
12
12
|
spec.homepage = "http://github.com/botandrose/bard"
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
|
16
|
-
spec.
|
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
16
|
+
spec.test_files = spec.files.grep(%r{^(test|spec)/})
|
|
18
17
|
spec.required_ruby_version = ">= 3.3"
|
|
19
18
|
spec.require_paths = ["lib"]
|
|
20
19
|
|
|
21
|
-
spec.add_dependency "thor", ">= 0.19.0"
|
|
22
|
-
spec.add_dependency "rvm"
|
|
23
|
-
spec.add_dependency "rbnacl"
|
|
24
|
-
spec.add_dependency "base64"
|
|
25
|
-
|
|
26
20
|
spec.add_development_dependency "rake"
|
|
27
21
|
spec.add_development_dependency "rspec"
|
|
28
22
|
spec.add_development_dependency "debug"
|
|
29
|
-
spec.add_development_dependency "cucumber"
|
|
30
|
-
spec.add_development_dependency "testcontainers"
|
|
31
|
-
spec.add_development_dependency "ostruct"
|
|
32
23
|
end
|
data/lib/bard/config.rb
CHANGED
|
@@ -4,6 +4,11 @@ require "bard/plugins/ping/target_methods"
|
|
|
4
4
|
|
|
5
5
|
module Bard
|
|
6
6
|
class Config
|
|
7
|
+
class << self
|
|
8
|
+
attr_accessor :default_targets
|
|
9
|
+
attr_accessor :strict
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
def self.current
|
|
8
13
|
new(detect_project_name, path: "bard.rb")
|
|
9
14
|
end
|
|
@@ -50,30 +55,27 @@ module Bard
|
|
|
50
55
|
@targets[key.to_sym]
|
|
51
56
|
end
|
|
52
57
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
# A bard.rb may use DSL contributed by plugins. When the owning plugin is loaded it defines
|
|
59
|
+
# a real method that wins over this; otherwise we tolerate the declaration as a plain
|
|
60
|
+
# attribute so the file still parses — notably server-side, where bard-cli is absent.
|
|
61
|
+
def method_missing(name, *args, &block)
|
|
62
|
+
return super if self.class.strict
|
|
63
|
+
if args.empty? && block.nil?
|
|
64
|
+
(@attributes ||= {})[name]
|
|
65
|
+
else
|
|
66
|
+
(@attributes ||= {})[name] = args.length == 1 ? args.first : args
|
|
62
67
|
end
|
|
68
|
+
end
|
|
63
69
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
url false
|
|
68
|
-
end
|
|
70
|
+
def respond_to_missing?(name, include_private = false)
|
|
71
|
+
!self.class.strict || super
|
|
72
|
+
end
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
ssh "www@staging.botandrose.com:22022"
|
|
72
|
-
url "#{config.project_name}.botandrose.com"
|
|
73
|
-
end
|
|
74
|
+
private
|
|
74
75
|
|
|
75
|
-
|
|
76
|
-
target :
|
|
76
|
+
def load_defaults
|
|
77
|
+
target :local
|
|
78
|
+
Bard::Config.default_targets&.call(self)
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
end
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
require "bard/target"
|
|
2
2
|
require "bard/plugins/url/target_methods"
|
|
3
|
-
require "bard/plugins/ping/check"
|
|
4
3
|
|
|
5
4
|
class Bard::Target
|
|
6
5
|
def ping(*urls)
|
|
@@ -12,12 +11,4 @@ class Bard::Target
|
|
|
12
11
|
@ping_urls = urls.flatten.map { |u| normalize_url(u) }
|
|
13
12
|
end
|
|
14
13
|
end
|
|
15
|
-
|
|
16
|
-
def ping!
|
|
17
|
-
require_capability!(:url)
|
|
18
|
-
failed_urls = Bard::Ping.call(self)
|
|
19
|
-
if failed_urls.any?
|
|
20
|
-
raise "Ping failed for: #{failed_urls.join(", ")}"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
14
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require "uri"
|
|
2
|
-
require "shellwords"
|
|
3
2
|
require "bard/plugins/ssh/server"
|
|
4
|
-
require "bard/command"
|
|
5
3
|
|
|
4
|
+
# Data-only SSH mixin: enough for the parser to hold a target's connection details and
|
|
5
|
+
# derive its url. The command-running methods (run!/ssh_command) live in bard-cli.
|
|
6
6
|
module Bard
|
|
7
7
|
module SSH
|
|
8
8
|
def server
|
|
@@ -38,38 +38,5 @@ module Bard
|
|
|
38
38
|
str += "/#{file_path}" if file_path
|
|
39
39
|
str
|
|
40
40
|
end
|
|
41
|
-
|
|
42
|
-
def run!(command, home: false, verbose: false, quiet: false, capture: false)
|
|
43
|
-
result = Command.run!(ssh_command(command, home:), verbose:, quiet:)
|
|
44
|
-
result if capture
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def run(command, home: false, verbose: false, quiet: false)
|
|
48
|
-
Command.run(ssh_command(command, home:), verbose:, quiet:)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def exec!(command, home: false)
|
|
52
|
-
Command.exec!(ssh_command(command, home:))
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
private
|
|
56
|
-
|
|
57
|
-
def ssh_command(command, home: false)
|
|
58
|
-
cmd = command
|
|
59
|
-
cmd = "#{env} #{command}" if env
|
|
60
|
-
|
|
61
|
-
unless home
|
|
62
|
-
cmd = "cd #{path} && #{cmd}" if path
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
ssh_opts = ["-tt", "-o StrictHostKeyChecking=no", "-o UserKnownHostsFile=/dev/null", "-o LogLevel=ERROR"]
|
|
66
|
-
ssh_opts << "-i #{ssh_key}" if ssh_key
|
|
67
|
-
ssh_opts << "-p #{server.port}" if server.port && server.port != "22"
|
|
68
|
-
ssh_opts << "-o ProxyJump=#{gateway}" if gateway
|
|
69
|
-
|
|
70
|
-
ssh_target = "#{server.user}@#{server.host}"
|
|
71
|
-
|
|
72
|
-
"ssh #{ssh_opts.join(" ")} #{ssh_target} #{Shellwords.shellescape(cmd)}"
|
|
73
|
-
end
|
|
74
41
|
end
|
|
75
42
|
end
|
data/lib/bard/target.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require "bard/command"
|
|
2
|
-
|
|
3
1
|
module Bard
|
|
4
2
|
class Target
|
|
5
3
|
attr_reader :key, :config
|
|
@@ -30,19 +28,6 @@ module Bard
|
|
|
30
28
|
@path || config.project_name
|
|
31
29
|
end
|
|
32
30
|
|
|
33
|
-
def run!(command, home: false, verbose: false, quiet: false, capture: false)
|
|
34
|
-
result = Command.run!(command, verbose:, quiet:)
|
|
35
|
-
result if capture
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def run(command, home: false, verbose: false, quiet: false)
|
|
39
|
-
Command.run(command, verbose:, quiet:)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def exec!(command, home: false)
|
|
43
|
-
Command.exec!(command)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
31
|
# Utility methods
|
|
47
32
|
def to_s
|
|
48
33
|
key.to_s
|