bard 1.5.3 → 1.5.5
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 +16 -0
- data/bard.gemspec +1 -0
- data/lib/bard/ci/github_actions.rb +1 -1
- data/lib/bard/cli/new_rails_template.rb +1 -1
- data/lib/bard/version.rb +1 -1
- data/spec/acceptance/.gitignore +4 -0
- data/spec/acceptance/docker/Dockerfile +35 -0
- data/spec/acceptance/docker/test_key +27 -0
- data/spec/acceptance/docker/test_key.pub +1 -0
- data/spec/acceptance/podman_testcontainers_spec.rb +140 -0
- data/spec/bard/cli/new_spec.rb +1 -1
- metadata +27 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e299224241e3766a31c3dfe6a95b6d4ac74d50a189b4fecd8cd79a2f1856c8ab
|
|
4
|
+
data.tar.gz: 0b87cc9f75177aa95105924a65af0a5e67a9067b177a8824cfd3206bc3d17fe1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 866ce92cbfcc95a4cd2813da2f5cf1db8f40631270ae3160ad8981ae5d71e79deb8cf20f6b41125853b9f0ba05cadd3b878d074532d1ab5cdba5bee3e7ad9921
|
|
7
|
+
data.tar.gz: f33f6555089298fd42b361ed3d5f7c681d6df9ed0265b4027a83a4168d680ee35cb877002e8fb8d58c4e8c9e6e8e05b89d389c0e85e9de75e6861af0f70fdf39
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -18,5 +18,21 @@ jobs:
|
|
|
18
18
|
ruby-version: ${{ matrix.ruby }}
|
|
19
19
|
bundler-cache: true
|
|
20
20
|
|
|
21
|
+
- name: Install Podman
|
|
22
|
+
run: |
|
|
23
|
+
sudo apt-get update -y
|
|
24
|
+
sudo apt-get install -y podman
|
|
25
|
+
# Start podman service as root using TCP for better compatibility in CI
|
|
26
|
+
sudo nohup podman system service --time=0 tcp://127.0.0.1:8080 > /tmp/podman-service.log 2>&1 &
|
|
27
|
+
# Wait for service to be ready
|
|
28
|
+
for i in {1..30}; do
|
|
29
|
+
if curl --silent --fail http://127.0.0.1:8080/v1.40/version >/dev/null 2>&1; then
|
|
30
|
+
echo "Podman REST API ready at tcp://127.0.0.1:8080"
|
|
31
|
+
break
|
|
32
|
+
fi
|
|
33
|
+
sleep 1
|
|
34
|
+
done
|
|
35
|
+
echo "DOCKER_HOST=tcp://127.0.0.1:8080" >> $GITHUB_ENV
|
|
36
|
+
|
|
21
37
|
- name: Run tests
|
|
22
38
|
run: bundle exec rake
|
data/bard.gemspec
CHANGED
|
@@ -103,7 +103,7 @@ module Bard
|
|
|
103
103
|
sha = `git rev-parse #{branch}`.chomp
|
|
104
104
|
|
|
105
105
|
loop do
|
|
106
|
-
runs = client.get("actions/runs", head_sha: sha, created: ">#{start_time.iso8601}")
|
|
106
|
+
runs = client.get("actions/runs", event: "workflow_dispatch", head_sha: sha, created: ">#{start_time.iso8601}")
|
|
107
107
|
if json = runs["workflow_runs"].first
|
|
108
108
|
return Run.new(self, json)
|
|
109
109
|
end
|
data/lib/bard/version.rb
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
FROM ubuntu:22.04
|
|
2
|
+
|
|
3
|
+
# Prevent interactive prompts
|
|
4
|
+
ENV DEBIAN_FRONTEND=noninteractive
|
|
5
|
+
|
|
6
|
+
# Install SSH server and basic tools
|
|
7
|
+
RUN apt-get update && \
|
|
8
|
+
apt-get install -y \
|
|
9
|
+
openssh-server \
|
|
10
|
+
sudo \
|
|
11
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
12
|
+
|
|
13
|
+
# Create deploy user
|
|
14
|
+
RUN useradd -m -s /bin/bash deploy && \
|
|
15
|
+
echo 'deploy:password' | chpasswd
|
|
16
|
+
|
|
17
|
+
# Setup SSH
|
|
18
|
+
RUN mkdir /var/run/sshd && \
|
|
19
|
+
mkdir -p /home/deploy/.ssh && \
|
|
20
|
+
chmod 700 /home/deploy/.ssh
|
|
21
|
+
|
|
22
|
+
# Copy SSH authorized key
|
|
23
|
+
COPY test_key.pub /home/deploy/.ssh/authorized_keys
|
|
24
|
+
RUN chown -R deploy:deploy /home/deploy/.ssh && \
|
|
25
|
+
chmod 600 /home/deploy/.ssh/authorized_keys
|
|
26
|
+
|
|
27
|
+
# Allow SSH login with keys
|
|
28
|
+
RUN sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config && \
|
|
29
|
+
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
|
|
30
|
+
|
|
31
|
+
# Expose SSH port
|
|
32
|
+
EXPOSE 22
|
|
33
|
+
|
|
34
|
+
# Start SSH service
|
|
35
|
+
CMD ["/usr/sbin/sshd", "-D"]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
-----BEGIN OPENSSH PRIVATE KEY-----
|
|
2
|
+
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
|
|
27
|
+
-----END OPENSSH PRIVATE KEY-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6+euShWHoAhIGGpQ62a9N/pMyir8OjqL9rKfVqqz1iZs3nu01WdhcQoFDXkcvluq5jQDgVx/mY7vcvKscZ1Q4OslLq9mjgnzByjITIrE4LZRhXmywJSe2rXd14ThZUd9LKQwSj3PdTtvEVLC3BTwQJhAcotvg4GZBviGn+cO/HgQznniVoFQHIabx+BIo6VgYR1YTQoAVWwp+RFbwCJHZG1DkLWEhP/MKYejTVZO0cym7JmThzGkGVLfHPrCwPrV/pKAyEzRfnvmN9X8zGFsN3cUaTEiTyQzbgO0t8tb2J1hYMPbl19C5crd5BkMne9ygpr7Zbvdd8d18GsAau+Np bard-test-key
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Acceptance test for Bard using Podman + TestContainers
|
|
2
|
+
#
|
|
3
|
+
# This test validates end-to-end functionality of `bard run ls` by:
|
|
4
|
+
# 1. Starting an SSH server container using TestContainers
|
|
5
|
+
# 2. Configuring Bard to connect to it
|
|
6
|
+
# 3. Running bard commands against the container
|
|
7
|
+
# 4. Automatically cleaning up when done
|
|
8
|
+
#
|
|
9
|
+
# Prerequisites:
|
|
10
|
+
# - gem install testcontainers
|
|
11
|
+
# - podman installed
|
|
12
|
+
# - podman socket running (systemctl --user start podman.socket)
|
|
13
|
+
# - Set DOCKER_HOST to podman socket
|
|
14
|
+
|
|
15
|
+
require 'spec_helper'
|
|
16
|
+
require 'testcontainers'
|
|
17
|
+
require 'open3'
|
|
18
|
+
|
|
19
|
+
RSpec.describe "Bard acceptance test with Podman + TestContainers", type: :acceptance do
|
|
20
|
+
# Disable WebMock for acceptance tests - we need real HTTP connections to Podman
|
|
21
|
+
before(:all) do
|
|
22
|
+
WebMock.allow_net_connect!
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
after(:all) do
|
|
26
|
+
WebMock.disable_net_connect!
|
|
27
|
+
end
|
|
28
|
+
# Configure TestContainers to use Podman
|
|
29
|
+
before(:all) do
|
|
30
|
+
# Set up podman socket for TestContainers
|
|
31
|
+
# Use existing DOCKER_HOST if set (e.g., in CI), otherwise use default location
|
|
32
|
+
unless ENV['DOCKER_HOST']
|
|
33
|
+
podman_socket = "/run/user/#{Process.uid}/podman/podman.sock"
|
|
34
|
+
|
|
35
|
+
# Start podman socket if not running
|
|
36
|
+
unless File.exist?(podman_socket)
|
|
37
|
+
system("systemctl --user start podman.socket 2>/dev/null || podman system service --time=0 unix://#{podman_socket} &")
|
|
38
|
+
sleep 2
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Configure TestContainers to use podman
|
|
42
|
+
ENV['DOCKER_HOST'] = "unix://#{podman_socket}"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Ensure SSH key has correct permissions
|
|
46
|
+
system("chmod 600 spec/acceptance/docker/test_key")
|
|
47
|
+
|
|
48
|
+
# Check if we can pull images
|
|
49
|
+
unless system("podman pull ubuntu:22.04 >/dev/null 2>&1")
|
|
50
|
+
skip "Cannot pull images in this environment. Run in a network-enabled environment."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Build the test image
|
|
54
|
+
unless system("podman build -t bard-test-server -f spec/acceptance/docker/Dockerfile spec/acceptance/docker 2>&1")
|
|
55
|
+
skip "Failed to build test image"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# TestContainers will automatically manage this container
|
|
60
|
+
let(:container) do
|
|
61
|
+
Testcontainers::DockerContainer.new("localhost/bard-test-server:latest")
|
|
62
|
+
.with_exposed_port(22)
|
|
63
|
+
.with_name("bard-test-#{SecureRandom.hex(4)}")
|
|
64
|
+
.start
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
let(:ssh_port) { container.mapped_port(22) }
|
|
68
|
+
|
|
69
|
+
before(:each) do
|
|
70
|
+
# Ensure container is started
|
|
71
|
+
container
|
|
72
|
+
|
|
73
|
+
# Wait for SSH to be ready
|
|
74
|
+
30.times do
|
|
75
|
+
break if system("ssh -o StrictHostKeyChecking=no -o ConnectTimeout=1 -p #{ssh_port} deploy@localhost -i spec/acceptance/docker/test_key 'echo ready' 2>/dev/null")
|
|
76
|
+
sleep 0.5
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Create test project directory
|
|
80
|
+
system("ssh -o StrictHostKeyChecking=no -p #{ssh_port} deploy@localhost -i spec/acceptance/docker/test_key 'mkdir -p testproject'")
|
|
81
|
+
|
|
82
|
+
# Create bard config for this container
|
|
83
|
+
@bard_config_path = "tmp/test_bard_#{SecureRandom.hex(4)}.rb"
|
|
84
|
+
FileUtils.mkdir_p("tmp")
|
|
85
|
+
ssh_key_path = File.expand_path("spec/acceptance/docker/test_key")
|
|
86
|
+
File.write(@bard_config_path, <<~RUBY)
|
|
87
|
+
server :production do
|
|
88
|
+
ssh "deploy@localhost:#{ssh_port}"
|
|
89
|
+
path "testproject"
|
|
90
|
+
ssh_key "#{ssh_key_path}"
|
|
91
|
+
ping false
|
|
92
|
+
end
|
|
93
|
+
RUBY
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
after(:each) do
|
|
97
|
+
# Clean up bard config
|
|
98
|
+
FileUtils.rm_f(@bard_config_path) if @bard_config_path
|
|
99
|
+
|
|
100
|
+
# TestContainers will automatically stop and remove the container
|
|
101
|
+
container.stop if container
|
|
102
|
+
container.remove if container
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it "runs ls command via bard run" do
|
|
106
|
+
# Create a test file in the container
|
|
107
|
+
result = system("ssh -o StrictHostKeyChecking=no -p #{ssh_port} deploy@localhost -i spec/acceptance/docker/test_key 'touch testproject/test-file.txt'")
|
|
108
|
+
expect(result).to be true
|
|
109
|
+
|
|
110
|
+
# Run bard command
|
|
111
|
+
Dir.chdir("tmp") do
|
|
112
|
+
# Copy config to bard.rb
|
|
113
|
+
FileUtils.cp("../#{@bard_config_path}", "bard.rb")
|
|
114
|
+
|
|
115
|
+
output, status = Open3.capture2e("bard run ls")
|
|
116
|
+
|
|
117
|
+
# Clean up
|
|
118
|
+
FileUtils.rm_f("bard.rb")
|
|
119
|
+
|
|
120
|
+
# Verify the command succeeded
|
|
121
|
+
expect(status).to be_success, "bard run failed with output: #{output}"
|
|
122
|
+
expect(output).to include("test-file.txt")
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it "runs multiple commands in isolated containers" do
|
|
127
|
+
# Each test gets its own container automatically!
|
|
128
|
+
result = system("ssh -o StrictHostKeyChecking=no -p #{ssh_port} deploy@localhost -i spec/acceptance/docker/test_key 'echo content > testproject/another-file.txt'")
|
|
129
|
+
expect(result).to be true
|
|
130
|
+
|
|
131
|
+
Dir.chdir("tmp") do
|
|
132
|
+
FileUtils.cp("../#{@bard_config_path}", "bard.rb")
|
|
133
|
+
output, status = Open3.capture2e("bard run 'cat another-file.txt'")
|
|
134
|
+
FileUtils.rm_f("bard.rb")
|
|
135
|
+
|
|
136
|
+
expect(status).to be_success, "bard run failed with output: #{output}"
|
|
137
|
+
expect(output).to include("content")
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
data/spec/bard/cli/new_spec.rb
CHANGED
|
@@ -59,7 +59,7 @@ describe Bard::CLI::New do
|
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
describe "#install_and_extract_version" do
|
|
62
|
-
it "correctly installs a gem and extracts its version" do
|
|
62
|
+
it "correctly installs a gem and extracts its version", skip: !!ENV["CI"] do
|
|
63
63
|
cmd = new_cli.send :build_bash_env do
|
|
64
64
|
<<~SH
|
|
65
65
|
#{new_cli.send(:build_gem_install, "bundler", "~> 2.0")}
|
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.5.
|
|
4
|
+
version: 1.5.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Micah Geisel
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date:
|
|
10
|
+
date: 2025-11-30 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: thor
|
|
@@ -121,6 +121,20 @@ dependencies:
|
|
|
121
121
|
- - ">="
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
123
|
version: '0'
|
|
124
|
+
- !ruby/object:Gem::Dependency
|
|
125
|
+
name: testcontainers
|
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
|
127
|
+
requirements:
|
|
128
|
+
- - ">="
|
|
129
|
+
- !ruby/object:Gem::Version
|
|
130
|
+
version: '0'
|
|
131
|
+
type: :development
|
|
132
|
+
prerelease: false
|
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
134
|
+
requirements:
|
|
135
|
+
- - ">="
|
|
136
|
+
- !ruby/object:Gem::Version
|
|
137
|
+
version: '0'
|
|
124
138
|
email:
|
|
125
139
|
- micah@botandrose.com
|
|
126
140
|
executables:
|
|
@@ -210,6 +224,11 @@ files:
|
|
|
210
224
|
- lib/bard/provision/user.rb
|
|
211
225
|
- lib/bard/server.rb
|
|
212
226
|
- lib/bard/version.rb
|
|
227
|
+
- spec/acceptance/.gitignore
|
|
228
|
+
- spec/acceptance/docker/Dockerfile
|
|
229
|
+
- spec/acceptance/docker/test_key
|
|
230
|
+
- spec/acceptance/docker/test_key.pub
|
|
231
|
+
- spec/acceptance/podman_testcontainers_spec.rb
|
|
213
232
|
- spec/bard/ci/github_actions_spec.rb
|
|
214
233
|
- spec/bard/ci_spec.rb
|
|
215
234
|
- spec/bard/cli/ci_spec.rb
|
|
@@ -274,7 +293,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
274
293
|
- !ruby/object:Gem::Version
|
|
275
294
|
version: '0'
|
|
276
295
|
requirements: []
|
|
277
|
-
rubygems_version: 3.6.
|
|
296
|
+
rubygems_version: 3.6.2
|
|
278
297
|
specification_version: 4
|
|
279
298
|
summary: CLI to automate common development tasks.
|
|
280
299
|
test_files:
|
|
@@ -290,6 +309,11 @@ test_files:
|
|
|
290
309
|
- features/support/env.rb
|
|
291
310
|
- features/support/grit_ext.rb
|
|
292
311
|
- features/support/io.rb
|
|
312
|
+
- spec/acceptance/.gitignore
|
|
313
|
+
- spec/acceptance/docker/Dockerfile
|
|
314
|
+
- spec/acceptance/docker/test_key
|
|
315
|
+
- spec/acceptance/docker/test_key.pub
|
|
316
|
+
- spec/acceptance/podman_testcontainers_spec.rb
|
|
293
317
|
- spec/bard/ci/github_actions_spec.rb
|
|
294
318
|
- spec/bard/ci_spec.rb
|
|
295
319
|
- spec/bard/cli/ci_spec.rb
|