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
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require "bard/plugins/github_pages/strategy"
|
|
2
|
-
require "bard/plugins/git"
|
|
3
|
-
require "bard/config"
|
|
4
|
-
require "bard/target"
|
|
5
|
-
|
|
6
|
-
class Bard::Config
|
|
7
|
-
def github_pages(url = nil)
|
|
8
|
-
hostname = if url
|
|
9
|
-
uri = url.start_with?("http") ? URI.parse(url) : URI.parse("https://#{url}")
|
|
10
|
-
uri.hostname.sub(/^www\./, "")
|
|
11
|
-
else
|
|
12
|
-
Bard::Git.github_pages_url
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
remove_target :production
|
|
16
|
-
target :production do
|
|
17
|
-
github_pages url
|
|
18
|
-
url hostname
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
backup(false) if respond_to?(:backup)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
class Bard::Target
|
|
26
|
-
def github_pages(*args)
|
|
27
|
-
if args.empty?
|
|
28
|
-
@github_pages_url
|
|
29
|
-
else
|
|
30
|
-
@deploy_strategy = :github_pages
|
|
31
|
-
@github_pages_url = args.first
|
|
32
|
-
enable_capability(:github_pages)
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
data/lib/bard/plugins/hurt.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
class Bard::CLI
|
|
2
|
-
desc "hurt <command>", "reruns a command until it fails"
|
|
3
|
-
def hurt(*args)
|
|
4
|
-
(1..).each do |count|
|
|
5
|
-
puts "Running attempt #{count}"
|
|
6
|
-
system *args
|
|
7
|
-
unless $?.success?
|
|
8
|
-
puts "Ran #{count-1} times before failing"
|
|
9
|
-
break
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
version: 2
|
|
2
|
-
updates:
|
|
3
|
-
- package-ecosystem: "bundler"
|
|
4
|
-
directory: "/"
|
|
5
|
-
schedule:
|
|
6
|
-
interval: "weekly"
|
|
7
|
-
cooldown:
|
|
8
|
-
default-days: 7
|
|
9
|
-
allow:
|
|
10
|
-
- dependency-type: "all"
|
|
11
|
-
rebase-strategy: "disabled"
|
|
12
|
-
versioning-strategy: "lockfile-only"
|
|
13
|
-
groups:
|
|
14
|
-
semver_updates:
|
|
15
|
-
applies-to: "version-updates"
|
|
16
|
-
update-types:
|
|
17
|
-
- "minor"
|
|
18
|
-
- "patch"
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
name: cache-ci
|
|
2
|
-
on:
|
|
3
|
-
push:
|
|
4
|
-
branches: [ master ]
|
|
5
|
-
schedule:
|
|
6
|
-
- cron: '0 0 */3 * *'
|
|
7
|
-
jobs:
|
|
8
|
-
build_ruby_cache:
|
|
9
|
-
runs-on: ubuntu-24.04
|
|
10
|
-
timeout-minutes: 30
|
|
11
|
-
steps:
|
|
12
|
-
- uses: actions/checkout@v3
|
|
13
|
-
- uses: ruby/setup-ruby@v1
|
|
14
|
-
with:
|
|
15
|
-
bundler-cache: true
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
name: ci
|
|
2
|
-
on:
|
|
3
|
-
pull_request_target:
|
|
4
|
-
workflow_dispatch:
|
|
5
|
-
inputs:
|
|
6
|
-
git-ref:
|
|
7
|
-
required: true
|
|
8
|
-
|
|
9
|
-
permissions:
|
|
10
|
-
contents: write
|
|
11
|
-
pull-requests: write
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
test:
|
|
15
|
-
runs-on: ubuntu-24.04${{ github.actor != 'dependabot[bot]' && '-8core' || '' }}
|
|
16
|
-
timeout-minutes: 30
|
|
17
|
-
env:
|
|
18
|
-
RAILS_ENV: test
|
|
19
|
-
RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
|
|
20
|
-
steps:
|
|
21
|
-
- name: Set up MySQL
|
|
22
|
-
run: |
|
|
23
|
-
sudo /etc/init.d/mysql start
|
|
24
|
-
sudo mysql -uroot -proot -e"ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY '';"
|
|
25
|
-
- name: Checkout code
|
|
26
|
-
uses: actions/checkout@v3
|
|
27
|
-
with:
|
|
28
|
-
ref: ${{ github.event.inputs.git-ref || github.event.pull_request.head.sha }}
|
|
29
|
-
- name: Install Ruby and gems
|
|
30
|
-
uses: ruby/setup-ruby@v1
|
|
31
|
-
with:
|
|
32
|
-
bundler-cache: true
|
|
33
|
-
- name: Set up apt packages
|
|
34
|
-
if: ${{ hashFiles('Aptfile') != '' }}
|
|
35
|
-
run: |
|
|
36
|
-
sudo rm -f /var/lib/man-db/auto-update
|
|
37
|
-
echo "APT_PACKAGES=$(paste -sd " " Aptfile)" >> $GITHUB_ENV
|
|
38
|
-
- name: Apt packages
|
|
39
|
-
if: ${{ hashFiles('Aptfile') != '' }}
|
|
40
|
-
uses: awalsh128/cache-apt-pkgs-action@latest
|
|
41
|
-
with:
|
|
42
|
-
packages: ${{ env.APT_PACKAGES }}
|
|
43
|
-
- name: Setup
|
|
44
|
-
run: bin/setup
|
|
45
|
-
- name: Run tests
|
|
46
|
-
run: bin/ci
|
|
47
|
-
|
|
48
|
-
autodeploy-dependabot-prs:
|
|
49
|
-
needs: test
|
|
50
|
-
runs-on: ubuntu-24.04
|
|
51
|
-
timeout-minutes: 30
|
|
52
|
-
if: github.actor == 'dependabot[bot]'
|
|
53
|
-
steps:
|
|
54
|
-
- name: Merge Dependabot PR
|
|
55
|
-
run: gh pr merge --auto --rebase "$PR_URL"
|
|
56
|
-
env:
|
|
57
|
-
PR_URL: ${{github.event.pull_request.html_url}}
|
|
58
|
-
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
|
59
|
-
- uses: actions/checkout@v3
|
|
60
|
-
- uses: ruby/setup-ruby@v1
|
|
61
|
-
with:
|
|
62
|
-
bundler-cache: true
|
|
63
|
-
- name: Install SSH key
|
|
64
|
-
uses: shimataro/ssh-key-action@v2
|
|
65
|
-
with:
|
|
66
|
-
key: ${{ secrets.DEPLOY_SSH_PRIVATE_KEY }}
|
|
67
|
-
known_hosts: unnecessary
|
|
68
|
-
config: |
|
|
69
|
-
Host *
|
|
70
|
-
StrictHostKeyChecking no
|
|
71
|
-
UserKnownHostsFile=/dev/null
|
|
72
|
-
- name: deploy
|
|
73
|
-
run: bundle exec bard deploy --skip-ci
|
|
74
|
-
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
module AptDependencies
|
|
2
|
-
extend self
|
|
3
|
-
|
|
4
|
-
def self.ensure!
|
|
5
|
-
return "true" if deps_to_install.none?
|
|
6
|
-
return "true" if ENV["APT_PACKAGES"] # already installed via github actions
|
|
7
|
-
if sudo_password_required? && ENV["RAILS_ENV"] != "development"
|
|
8
|
-
$stderr.puts "sudo requires password! cannot install #{deps_to_install.join(' ')}"
|
|
9
|
-
exit 1
|
|
10
|
-
else
|
|
11
|
-
system "sudo DEBIAN_FRONTEND=noninteractive apt-get update -y && sudo DEBIAN_FRONTEND=noninteractive apt-get install -y #{deps_to_install.join(' ')}"
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
private
|
|
16
|
-
|
|
17
|
-
def deps_to_install
|
|
18
|
-
deps.reject do |dep|
|
|
19
|
-
system("dpkg-query -W -f='${Status}' #{dep} 2>/dev/null > /dev/null")
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def deps
|
|
24
|
-
@deps ||= File.readlines("Aptfile", chomp: true).select { |line| line.length > 0 }
|
|
25
|
-
rescue Errno::ENOENT
|
|
26
|
-
@deps = []
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def sudo_password_required?
|
|
30
|
-
!system("sudo -n true 2>/dev/null")
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
|
data/lib/bard/plugins/install/ci
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env ruby
|
|
2
|
-
require_relative './apt_dependencies'
|
|
3
|
-
require_relative './specified_ruby'
|
|
4
|
-
require_relative './specified_bundler'
|
|
5
|
-
|
|
6
|
-
Dir.chdir File.expand_path("..", __dir__) do
|
|
7
|
-
exec [
|
|
8
|
-
AptDependencies.ensure!,
|
|
9
|
-
SpecifiedRuby.ensure!,
|
|
10
|
-
SpecifiedBundler.ensure!,
|
|
11
|
-
"bin/rake bootstrap",
|
|
12
|
-
].join(" && ")
|
|
13
|
-
end
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
module SpecifiedBundler
|
|
2
|
-
extend self
|
|
3
|
-
|
|
4
|
-
def ensure!
|
|
5
|
-
system("gem install bundler --conservative --version=#{bundler_version}") or raise "Cannot install bundler!"
|
|
6
|
-
"(bundle check || bundle install)"
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
def bundler_version
|
|
12
|
-
lines = File.readlines("Gemfile.lock")
|
|
13
|
-
lines.last.strip if lines[-2] == "BUNDLED WITH\n"
|
|
14
|
-
end
|
|
15
|
-
end
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
module SpecifiedRuby
|
|
2
|
-
extend self
|
|
3
|
-
|
|
4
|
-
def ensure!
|
|
5
|
-
return "true" if native?
|
|
6
|
-
install unless installed?
|
|
7
|
-
restart unless current?
|
|
8
|
-
"true"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
def native?
|
|
14
|
-
begin
|
|
15
|
-
require "rvm"
|
|
16
|
-
false
|
|
17
|
-
rescue LoadError
|
|
18
|
-
native_version == version
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def native_version
|
|
23
|
-
"ruby-#{`ruby -e 'puts RUBY_VERSION'`.chomp}"
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def version
|
|
27
|
-
File.read(".ruby-version").chomp
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def gemset
|
|
31
|
-
File.read(".ruby-gemset").chomp
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def installed?
|
|
35
|
-
installed_rubies = `rvm list strings`.split("\n")
|
|
36
|
-
installed_rubies.include?(version)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def install
|
|
40
|
-
system("rvm install #{version}") or exit 1
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def current?
|
|
44
|
-
require "rvm"
|
|
45
|
-
RVM.use_from_path!(".")
|
|
46
|
-
RVM.current.environment_name == [version, gemset].join("@")
|
|
47
|
-
rescue RVM::IncompatibleRubyError
|
|
48
|
-
false
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def restart
|
|
52
|
-
command = "rvm-exec #{$0}"
|
|
53
|
-
unless %w[staging production].include?(ENV["RAILS_ENV"])
|
|
54
|
-
command += " && rvm-exec $SHELL"
|
|
55
|
-
end
|
|
56
|
-
exec command
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
data/lib/bard/plugins/install.rb
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
class Bard::CLI
|
|
2
|
-
desc "install", "copies bin/setup and bin/ci scripts into current project."
|
|
3
|
-
def install
|
|
4
|
-
install_files_path = File.expand_path("install", __dir__)
|
|
5
|
-
|
|
6
|
-
system "cp -R #{install_files_path}/* bin/"
|
|
7
|
-
system "cp -R #{install_files_path}/.github ./"
|
|
8
|
-
end
|
|
9
|
-
end
|
data/lib/bard/plugins/open.rb
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
require "bard/plugins/url"
|
|
2
|
-
|
|
3
|
-
class Bard::CLI
|
|
4
|
-
desc "open [target=production]", "opens the url in the web browser."
|
|
5
|
-
def open(target = :production)
|
|
6
|
-
exec "xdg-open #{open_url target}"
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
no_commands do
|
|
10
|
-
def open_url(target)
|
|
11
|
-
if target.to_sym == :ci
|
|
12
|
-
"https://github.com/botandrosedesign/#{project_name}/actions/workflows/ci.yml"
|
|
13
|
-
else
|
|
14
|
-
t = config[target]
|
|
15
|
-
t.require_capability!(:url)
|
|
16
|
-
t.url
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
require "net/http"
|
|
2
|
-
require "uri"
|
|
3
|
-
|
|
4
|
-
module Bard
|
|
5
|
-
class Ping < Struct.new(:target)
|
|
6
|
-
def self.call target
|
|
7
|
-
new(target).call
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def call
|
|
11
|
-
target.ping.reject { |url| reachable?(url) }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
private
|
|
15
|
-
|
|
16
|
-
def reachable?(url)
|
|
17
|
-
attempts = 0
|
|
18
|
-
begin
|
|
19
|
-
attempts += 1
|
|
20
|
-
response = get_response_with_redirect(url)
|
|
21
|
-
response.is_a?(Net::HTTPSuccess)
|
|
22
|
-
rescue StandardError
|
|
23
|
-
retry if attempts < 2
|
|
24
|
-
false
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def get_response_with_redirect uri_str, limit=5
|
|
29
|
-
uri = URI(uri_str)
|
|
30
|
-
response = http_get(uri)
|
|
31
|
-
|
|
32
|
-
case response
|
|
33
|
-
when Net::HTTPRedirection
|
|
34
|
-
if limit == 0
|
|
35
|
-
puts "too many HTTP redirects"
|
|
36
|
-
response
|
|
37
|
-
else
|
|
38
|
-
location = response["location"]
|
|
39
|
-
return response unless location
|
|
40
|
-
|
|
41
|
-
next_uri = begin
|
|
42
|
-
uri + location
|
|
43
|
-
rescue URI::InvalidURIError
|
|
44
|
-
URI(location)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
get_response_with_redirect(next_uri, limit - 1)
|
|
48
|
-
end
|
|
49
|
-
else
|
|
50
|
-
response
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def http_get(uri)
|
|
55
|
-
Net::HTTP.start(
|
|
56
|
-
uri.host,
|
|
57
|
-
uri.port,
|
|
58
|
-
use_ssl: uri.scheme == "https",
|
|
59
|
-
open_timeout: 5,
|
|
60
|
-
read_timeout: 5,
|
|
61
|
-
) do |http|
|
|
62
|
-
http.get(uri.request_uri)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
data/lib/bard/plugins/ping.rb
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
require "bard/plugins/ping/target_methods"
|
|
2
|
-
|
|
3
|
-
class Bard::CLI
|
|
4
|
-
desc "ping [target=production]", "hits the target over http to verify that its up."
|
|
5
|
-
def ping(target = :production)
|
|
6
|
-
down_urls = Bard::Ping.call(config[target])
|
|
7
|
-
down_urls.each { |url| puts "#{url} is down!" }
|
|
8
|
-
exit 1 if down_urls.any?
|
|
9
|
-
end
|
|
10
|
-
end
|
data/lib/bard/plugins/run.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
require "bard/command"
|
|
2
|
-
|
|
3
|
-
class Bard::CLI
|
|
4
|
-
# HACK: we don't use Thor::Base#run, so its okay to stomp on it here
|
|
5
|
-
original_verbose, $VERBOSE = $VERBOSE, nil
|
|
6
|
-
Thor::THOR_RESERVED_WORDS -= ["run"]
|
|
7
|
-
$VERBOSE = original_verbose
|
|
8
|
-
|
|
9
|
-
option :target, type: :string, default: "production"
|
|
10
|
-
option :home, type: :boolean
|
|
11
|
-
desc "run <command>", "run the given command on the specified target"
|
|
12
|
-
def run(*args)
|
|
13
|
-
target = config[options[:target].to_sym]
|
|
14
|
-
target.run!(*args.join(" "), verbose: true, home: options[:home])
|
|
15
|
-
rescue Bard::Command::Error => e
|
|
16
|
-
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
|
17
|
-
exit 1
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/bard/plugins/setup.rb
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
require "uri"
|
|
2
|
-
require "bard/plugins/url"
|
|
3
|
-
|
|
4
|
-
class Bard::CLI
|
|
5
|
-
desc "setup", "installs app in nginx"
|
|
6
|
-
def setup
|
|
7
|
-
path = "/etc/nginx/sites-available/#{project_name}"
|
|
8
|
-
system "sudo tee #{path} >/dev/null <<-'EOF'\n#{nginx_config}EOF"
|
|
9
|
-
|
|
10
|
-
dest_path = path.sub("sites-available", "sites-enabled")
|
|
11
|
-
system "sudo ln -sf #{path} #{dest_path}" if !File.exist?(dest_path)
|
|
12
|
-
|
|
13
|
-
system "sudo service nginx restart"
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
no_commands do
|
|
17
|
-
def nginx_config
|
|
18
|
-
case ENV["RAILS_ENV"]
|
|
19
|
-
when "production" then nginx_production_config
|
|
20
|
-
else nginx_development_config
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def nginx_development_config
|
|
25
|
-
<<~EOF
|
|
26
|
-
server {
|
|
27
|
-
include /etc/nginx/snippets/common.conf;
|
|
28
|
-
server_name #{nginx_server_name};
|
|
29
|
-
root #{Dir.pwd}/public;
|
|
30
|
-
}
|
|
31
|
-
EOF
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def nginx_production_config
|
|
35
|
-
<<~EOF
|
|
36
|
-
upstream puma {
|
|
37
|
-
server 127.0.0.1:3000 fail_timeout=5;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
server {
|
|
41
|
-
listen 80;
|
|
42
|
-
server_name #{nginx_server_name};
|
|
43
|
-
root #{Dir.pwd}/public;
|
|
44
|
-
|
|
45
|
-
try_files $uri @app;
|
|
46
|
-
|
|
47
|
-
location @app {
|
|
48
|
-
proxy_pass http://puma;
|
|
49
|
-
proxy_set_header Host $host;
|
|
50
|
-
proxy_set_header X-Real-IP $remote_addr;
|
|
51
|
-
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
52
|
-
proxy_set_header X-Forwarded-Proto $scheme;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
location ~* \\-[0-9a-f]\\{64\\}\\.(ico|css|js|gif|jpe?g|png|webp)$ {
|
|
56
|
-
access_log off;
|
|
57
|
-
expires max;
|
|
58
|
-
add_header Cache-Control public;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
gzip_static on;
|
|
62
|
-
}
|
|
63
|
-
EOF
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def nginx_server_name
|
|
67
|
-
case ENV["RAILS_ENV"]
|
|
68
|
-
when "production"
|
|
69
|
-
"*.#{URI.parse(config[:production].url).host} _"
|
|
70
|
-
when "staging" then "#{project_name}.botandrose.com"
|
|
71
|
-
else "#{project_name}.localhost"
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
require "uri"
|
|
2
|
-
require "bard/copy"
|
|
3
|
-
require "bard/command"
|
|
4
|
-
|
|
5
|
-
module Bard
|
|
6
|
-
module SSH
|
|
7
|
-
class Copy < Bard::Copy
|
|
8
|
-
def self.can_handle?(from, to)
|
|
9
|
-
from.has_capability?(:ssh) || to.has_capability?(:ssh)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def file
|
|
13
|
-
if from.key == :local
|
|
14
|
-
scp_using_local :to, to
|
|
15
|
-
elsif to.key == :local
|
|
16
|
-
scp_using_local :from, from
|
|
17
|
-
else
|
|
18
|
-
scp_as_mediator
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def scp_using_local direction, target
|
|
23
|
-
ssh_server = target.server
|
|
24
|
-
|
|
25
|
-
gateway = ssh_server.gateway ? "-oProxyCommand='ssh #{ssh_server.gateway} -W %h:%p'" : ""
|
|
26
|
-
|
|
27
|
-
ssh_key = ssh_server.ssh_key ? "-i #{ssh_server.ssh_key}" : ""
|
|
28
|
-
|
|
29
|
-
ssh_opts = "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=ERROR"
|
|
30
|
-
|
|
31
|
-
port = ssh_server.port
|
|
32
|
-
port_opt = port && port.to_s != "22" ? "-P #{port}" : ""
|
|
33
|
-
|
|
34
|
-
from_and_to = [path, target.scp_uri(path).to_s]
|
|
35
|
-
from_and_to.reverse! if direction == :from
|
|
36
|
-
|
|
37
|
-
command = ["scp", ssh_opts, gateway, ssh_key, port_opt, *from_and_to].reject(&:empty?).join(" ")
|
|
38
|
-
Bard::Command.run! command, verbose: verbose
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def scp_as_mediator
|
|
42
|
-
from_server = from.server
|
|
43
|
-
to_server = to.server
|
|
44
|
-
|
|
45
|
-
raise NotImplementedError if from_server.gateway || to_server.gateway || from_server.ssh_key || to_server.ssh_key
|
|
46
|
-
command = "scp -o ForwardAgent=yes #{from.scp_uri(path)} #{to.scp_uri(path)}"
|
|
47
|
-
Bard::Command.run! command, verbose: verbose
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def dir
|
|
51
|
-
if from.key == :local
|
|
52
|
-
rsync_using_local :to, to
|
|
53
|
-
elsif to.key == :local
|
|
54
|
-
rsync_using_local :from, from
|
|
55
|
-
else
|
|
56
|
-
rsync_as_mediator
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def rsync_using_local direction, target
|
|
61
|
-
ssh_server = target.server
|
|
62
|
-
|
|
63
|
-
ssh_uri = ssh_server.ssh_uri
|
|
64
|
-
|
|
65
|
-
gateway = ssh_server.gateway ? "-oProxyCommand=\"ssh #{ssh_server.gateway} -W %h:%p\"" : ""
|
|
66
|
-
|
|
67
|
-
ssh_key = ssh_server.ssh_key ? "-i #{ssh_server.ssh_key}" : ""
|
|
68
|
-
ssh = "-e'ssh #{gateway} -p#{ssh_uri.port || 22}'"
|
|
69
|
-
|
|
70
|
-
from_and_to = ["./#{path}", target.rsync_uri(path)]
|
|
71
|
-
from_and_to.reverse! if direction == :from
|
|
72
|
-
from_and_to[-1].sub! %r(/[^/]+$), '/'
|
|
73
|
-
|
|
74
|
-
command = "rsync #{ssh} --delete --info=progress2 -az #{from_and_to.join(" ")}"
|
|
75
|
-
Bard::Command.run! command, verbose: verbose
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def rsync_as_mediator
|
|
79
|
-
from_server = from.server
|
|
80
|
-
to_server = to.server
|
|
81
|
-
|
|
82
|
-
raise NotImplementedError if from_server.gateway || to_server.gateway || from_server.ssh_key || to_server.ssh_key
|
|
83
|
-
|
|
84
|
-
from_uri = from_server.ssh_uri
|
|
85
|
-
to_uri = to_server.ssh_uri
|
|
86
|
-
|
|
87
|
-
from_str = "-p#{from_uri.port || 22} #{from_uri.user}@#{from_uri.host}"
|
|
88
|
-
to_str = to.rsync_uri(path).sub(%r(/[^/]+$), '/')
|
|
89
|
-
|
|
90
|
-
command = %(ssh -A #{from_str} 'rsync -e \"ssh -A -p#{to_uri.port || 22} -o StrictHostKeyChecking=no -o LogLevel=ERROR\" --delete --info=progress2 -az #{from.path}/#{path} #{to_str}')
|
|
91
|
-
Bard::Command.run! command, verbose: verbose
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
end
|
data/lib/bard/plugins/ssh.rb
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
require "bard/plugins/ssh/target_methods"
|
|
2
|
-
require "bard/plugins/ssh/copy"
|
|
3
|
-
|
|
4
|
-
class Bard::CLI
|
|
5
|
-
option :home, type: :boolean
|
|
6
|
-
desc "ssh [to=production]", "logs into the specified server via SSH"
|
|
7
|
-
def ssh(to = :production)
|
|
8
|
-
config[to].exec! "exec $SHELL -l", home: options[:home]
|
|
9
|
-
end
|
|
10
|
-
end
|
data/lib/bard/plugins/vim.rb
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
class Bard::CLI
|
|
2
|
-
desc "vim [branch=master]", "open all files that have changed since master"
|
|
3
|
-
def vim(branch = "master")
|
|
4
|
-
exec "vim -p `(git diff #{branch} --name-only; git ls-files --others --exclude-standard) | grep -v '^app/assets/images/' | grep -v '^app/assets/stylesheets/' | while read f; do [ -f \"$f\" ] && ! file -b \"$f\" | grep -q \"binary\" && echo \"$f\"; done | tac`"
|
|
5
|
-
end
|
|
6
|
-
end
|
data/lib/bard/retryable.rb
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
module Bard
|
|
2
|
-
module Retryable
|
|
3
|
-
MAX_RETRIES = 5
|
|
4
|
-
INITIAL_DELAY = 1
|
|
5
|
-
|
|
6
|
-
def retry_with_backoff(max_retries: MAX_RETRIES)
|
|
7
|
-
retries = 0
|
|
8
|
-
delay = INITIAL_DELAY
|
|
9
|
-
|
|
10
|
-
begin
|
|
11
|
-
yield
|
|
12
|
-
rescue => e
|
|
13
|
-
if retries < max_retries
|
|
14
|
-
retries += 1
|
|
15
|
-
puts " Network error (attempt #{retries}/#{max_retries}): #{e.message}. Retrying in #{delay}s..."
|
|
16
|
-
sleep(delay)
|
|
17
|
-
delay *= 2
|
|
18
|
-
retry
|
|
19
|
-
else
|
|
20
|
-
raise "Network error after #{max_retries} attempts: #{e.message}"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
data/lib/bard/secrets.rb
DELETED
data/spec/acceptance/.gitignore
DELETED