bard 2.0.0.beta → 2.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/.github/workflows/ci.yml +6 -1
- data/CLAUDE.md +76 -0
- data/MIGRATION_GUIDE.md +24 -9
- data/PLUGINS.md +99 -0
- data/README.md +14 -6
- data/Rakefile +3 -1
- data/bard.gemspec +2 -1
- data/cucumber.yml +1 -0
- data/features/ci.feature +63 -0
- data/features/data.feature +13 -0
- data/features/deploy.feature +14 -0
- data/features/deploy_git_workflow.feature +89 -0
- data/features/run.feature +14 -0
- data/features/step_definitions/bard_steps.rb +136 -0
- data/features/support/bard-coverage +16 -0
- data/features/support/env.rb +14 -39
- data/features/support/test_server.rb +216 -0
- data/lib/bard/cli.rb +14 -31
- data/lib/bard/command.rb +10 -69
- data/lib/bard/config.rb +40 -183
- data/lib/bard/copy.rb +28 -103
- data/lib/bard/plugins/data.rb +56 -0
- data/lib/bard/{ci → plugins/deploy/ci}/github_actions.rb +3 -4
- data/lib/bard/plugins/deploy/ci/jenkins.rb +176 -0
- data/lib/bard/{ci → plugins/deploy/ci}/local.rb +7 -7
- data/lib/bard/{ci → plugins/deploy/ci}/runner.rb +38 -4
- data/lib/bard/plugins/deploy/ci.rb +38 -0
- data/lib/bard/plugins/deploy/ssh_strategy.rb +27 -0
- data/lib/bard/{deploy_strategy.rb → plugins/deploy/strategy.rb} +1 -1
- data/lib/bard/plugins/deploy.rb +240 -0
- data/lib/bard/{git.rb → plugins/git.rb} +6 -3
- data/lib/bard/{github.rb → plugins/github.rb} +4 -6
- data/lib/bard/{deploy_strategy/github_pages.rb → plugins/github_pages/strategy.rb} +13 -6
- data/lib/bard/plugins/github_pages.rb +30 -0
- data/lib/bard/plugins/hurt.rb +13 -0
- data/{install_files → lib/bard/plugins/install}/.github/dependabot.yml +2 -1
- data/{install_files → lib/bard/plugins/install}/.github/workflows/cache-ci.yml +1 -1
- data/{install_files → lib/bard/plugins/install}/.github/workflows/ci.yml +2 -2
- data/lib/bard/plugins/install.rb +9 -0
- data/lib/bard/plugins/open.rb +20 -0
- data/lib/bard/{ping.rb → plugins/ping/check.rb} +4 -4
- data/lib/bard/plugins/ping/target_methods.rb +23 -0
- data/lib/bard/plugins/ping.rb +10 -0
- data/lib/bard/plugins/run.rb +19 -0
- data/lib/bard/plugins/setup.rb +54 -0
- data/lib/bard/plugins/ssh/connection.rb +75 -0
- data/lib/bard/plugins/ssh/copy.rb +95 -0
- data/lib/bard/{ssh_server.rb → plugins/ssh/server.rb} +17 -42
- data/lib/bard/plugins/ssh/target_methods.rb +20 -0
- data/lib/bard/plugins/ssh.rb +10 -0
- data/lib/bard/plugins/url/target_methods.rb +23 -0
- data/lib/bard/plugins/url.rb +1 -0
- data/lib/bard/plugins/vim.rb +6 -0
- data/lib/bard/retryable.rb +25 -0
- data/lib/bard/secrets.rb +10 -0
- data/lib/bard/target.rb +27 -185
- data/lib/bard/version.rb +1 -1
- data/lib/bard.rb +1 -3
- data/spec/acceptance/docker/Dockerfile +3 -2
- data/spec/bard/capability_spec.rb +8 -50
- data/spec/bard/ci/github_actions_spec.rb +117 -14
- data/spec/bard/ci/jenkins_spec.rb +139 -0
- data/spec/bard/ci/runner_spec.rb +61 -0
- data/spec/bard/ci_spec.rb +1 -1
- data/spec/bard/cli/ci_spec.rb +34 -27
- data/spec/bard/cli/data_spec.rb +7 -26
- data/spec/bard/cli/deploy_spec.rb +87 -46
- data/spec/bard/cli/hurt_spec.rb +3 -9
- data/spec/bard/cli/install_spec.rb +5 -11
- data/spec/bard/cli/master_key_spec.rb +5 -19
- data/spec/bard/cli/open_spec.rb +14 -30
- data/spec/bard/cli/ping_spec.rb +8 -23
- data/spec/bard/cli/run_spec.rb +27 -21
- data/spec/bard/cli/setup_spec.rb +10 -27
- data/spec/bard/cli/ssh_spec.rb +10 -25
- data/spec/bard/cli/stage_spec.rb +28 -23
- data/spec/bard/cli/vim_spec.rb +3 -9
- data/spec/bard/command_spec.rb +1 -8
- data/spec/bard/config_spec.rb +78 -98
- data/spec/bard/copy_spec.rb +54 -18
- data/spec/bard/deploy_strategy/ssh_spec.rb +65 -7
- data/spec/bard/deploy_strategy_spec.rb +1 -1
- data/spec/bard/dynamic_dsl_spec.rb +18 -98
- data/spec/bard/git_spec.rb +9 -5
- data/spec/bard/github_spec.rb +2 -2
- data/spec/bard/ping_spec.rb +5 -5
- data/spec/bard/ssh_copy_spec.rb +44 -0
- data/spec/bard/ssh_server_spec.rb +8 -101
- data/spec/bard/target_spec.rb +66 -109
- data/spec/spec_helper.rb +6 -1
- metadata +79 -143
- data/README.rdoc +0 -15
- data/features/bard_check.feature +0 -94
- data/features/bard_deploy.feature +0 -18
- data/features/bard_pull.feature +0 -112
- data/features/bard_push.feature +0 -112
- data/features/podman_testcontainers.feature +0 -16
- data/features/step_definitions/check_steps.rb +0 -47
- data/features/step_definitions/git_steps.rb +0 -73
- data/features/step_definitions/global_steps.rb +0 -56
- data/features/step_definitions/podman_steps.rb +0 -23
- data/features/step_definitions/rails_steps.rb +0 -44
- data/features/step_definitions/submodule_steps.rb +0 -110
- data/features/support/grit_ext.rb +0 -13
- data/features/support/io.rb +0 -32
- data/features/support/podman.rb +0 -153
- data/lib/bard/ci/jenkins.rb +0 -105
- data/lib/bard/ci/retryable.rb +0 -27
- data/lib/bard/ci.rb +0 -50
- data/lib/bard/cli/ci.rb +0 -66
- data/lib/bard/cli/command.rb +0 -26
- data/lib/bard/cli/data.rb +0 -45
- data/lib/bard/cli/deploy.rb +0 -85
- data/lib/bard/cli/hurt.rb +0 -20
- data/lib/bard/cli/install.rb +0 -16
- data/lib/bard/cli/master_key.rb +0 -17
- data/lib/bard/cli/new.rb +0 -101
- data/lib/bard/cli/new_rails_template.rb +0 -197
- data/lib/bard/cli/open.rb +0 -22
- data/lib/bard/cli/ping.rb +0 -18
- data/lib/bard/cli/provision.rb +0 -34
- data/lib/bard/cli/run.rb +0 -24
- data/lib/bard/cli/setup.rb +0 -56
- data/lib/bard/cli/ssh.rb +0 -14
- data/lib/bard/cli/stage.rb +0 -27
- data/lib/bard/cli/vim.rb +0 -13
- data/lib/bard/default_config.rb +0 -35
- data/lib/bard/deploy_strategy/ssh.rb +0 -19
- data/lib/bard/github_pages.rb +0 -134
- data/lib/bard/provision/app.rb +0 -10
- data/lib/bard/provision/apt.rb +0 -16
- data/lib/bard/provision/authorizedkeys.rb +0 -25
- data/lib/bard/provision/data.rb +0 -27
- data/lib/bard/provision/deploy.rb +0 -10
- data/lib/bard/provision/http.rb +0 -16
- data/lib/bard/provision/logrotation.rb +0 -30
- data/lib/bard/provision/masterkey.rb +0 -18
- data/lib/bard/provision/mysql.rb +0 -22
- data/lib/bard/provision/passenger.rb +0 -37
- data/lib/bard/provision/repo.rb +0 -72
- data/lib/bard/provision/rvm.rb +0 -22
- data/lib/bard/provision/ssh.rb +0 -72
- data/lib/bard/provision/swapfile.rb +0 -21
- data/lib/bard/provision/user.rb +0 -42
- data/lib/bard/provision.rb +0 -16
- data/lib/bard/server.rb +0 -117
- data/spec/bard/cli/command_spec.rb +0 -50
- data/spec/bard/cli/new_spec.rb +0 -73
- data/spec/bard/cli/provision_spec.rb +0 -42
- data/spec/bard/github_pages_spec.rb +0 -143
- data/spec/bard/provision/app_spec.rb +0 -33
- data/spec/bard/provision/apt_spec.rb +0 -39
- data/spec/bard/provision/authorizedkeys_spec.rb +0 -40
- data/spec/bard/provision/data_spec.rb +0 -54
- data/spec/bard/provision/deploy_spec.rb +0 -33
- data/spec/bard/provision/http_spec.rb +0 -57
- data/spec/bard/provision/logrotation_spec.rb +0 -34
- data/spec/bard/provision/masterkey_spec.rb +0 -63
- data/spec/bard/provision/mysql_spec.rb +0 -55
- data/spec/bard/provision/passenger_spec.rb +0 -81
- data/spec/bard/provision/repo_spec.rb +0 -208
- data/spec/bard/provision/rvm_spec.rb +0 -49
- data/spec/bard/provision/ssh_spec.rb +0 -229
- data/spec/bard/provision/swapfile_spec.rb +0 -32
- data/spec/bard/provision/user_spec.rb +0 -103
- data/spec/bard/provision_spec.rb +0 -28
- data/spec/bard/server_spec.rb +0 -127
- /data/lib/bard/{ci → plugins/deploy/ci}/state.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/apt_dependencies.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/ci +0 -0
- /data/{install_files → lib/bard/plugins/install}/setup +0 -0
- /data/{install_files → lib/bard/plugins/install}/specified_bundler.rb +0 -0
- /data/{install_files → lib/bard/plugins/install}/specified_ruby.rb +0 -0
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
ruby_version, project_name = (`rvm current name`.chomp).split("@")
|
|
2
|
-
rails_version = Gem.loaded_specs["railties"].version
|
|
3
|
-
|
|
4
|
-
file ".ruby-version", ruby_version
|
|
5
|
-
file ".ruby-gemset", project_name
|
|
6
|
-
file ".gitignore", <<~GITIGNORE
|
|
7
|
-
# See https://help.github.com/articles/ignoring-files for more about ignoring files.
|
|
8
|
-
#
|
|
9
|
-
# If you find yourself ignoring temporary files generated by your text editor
|
|
10
|
-
# or operating system, you probably want to add a global ignore instead:
|
|
11
|
-
# git config --global core.excludesfile '~/.gitignore_global'
|
|
12
|
-
|
|
13
|
-
# Ignore bundler config.
|
|
14
|
-
/.bundle
|
|
15
|
-
|
|
16
|
-
# Ignore all logfiles and tempfiles.
|
|
17
|
-
/log/*
|
|
18
|
-
/tmp/*
|
|
19
|
-
!/log/.keep
|
|
20
|
-
!/tmp/.keep
|
|
21
|
-
|
|
22
|
-
# Ignore master key for decrypting credentials and more.
|
|
23
|
-
/config/master.key
|
|
24
|
-
|
|
25
|
-
# ignore coverage reports
|
|
26
|
-
/coverage
|
|
27
|
-
|
|
28
|
-
# Ignore database dumps
|
|
29
|
-
/db/data.*
|
|
30
|
-
|
|
31
|
-
# Ignore storage (uploaded files in development and any SQLite databases).
|
|
32
|
-
/storage/*
|
|
33
|
-
|
|
34
|
-
# Ignore Syncthing
|
|
35
|
-
.stfolder/
|
|
36
|
-
|
|
37
|
-
# Thank Apple!
|
|
38
|
-
.DS_Store
|
|
39
|
-
GITIGNORE
|
|
40
|
-
|
|
41
|
-
file "Gemfile", <<~RUBY
|
|
42
|
-
source "https://rubygems.org"
|
|
43
|
-
|
|
44
|
-
gem "bootsnap", require: false
|
|
45
|
-
gem "rails", "~> #{rails_version}"
|
|
46
|
-
gem "solid_cache"
|
|
47
|
-
gem "solid_queue"
|
|
48
|
-
gem "solid_cable"
|
|
49
|
-
gem "bard-rails"
|
|
50
|
-
gem "sqlite3"
|
|
51
|
-
gem "image_processing"
|
|
52
|
-
gem "puma"
|
|
53
|
-
gem "exception_notification"
|
|
54
|
-
|
|
55
|
-
# css
|
|
56
|
-
gem "sprockets-rails"
|
|
57
|
-
gem "dartsass-sprockets"
|
|
58
|
-
gem "bard-sass"
|
|
59
|
-
|
|
60
|
-
# js
|
|
61
|
-
gem "importmap-rails"
|
|
62
|
-
gem "turbo-rails"
|
|
63
|
-
gem "stimulus-rails"
|
|
64
|
-
|
|
65
|
-
group :development do
|
|
66
|
-
gem "web-console"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
group :development, :test do
|
|
70
|
-
gem "debug", require: "debug/prelude"
|
|
71
|
-
# gem "parallel_tests", "~>3.9.0" # 3.10 pegs CPU
|
|
72
|
-
gem "brakeman", require: false
|
|
73
|
-
gem "rubocop-rails-omakase", require: false
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
group :test do
|
|
77
|
-
gem "cucumber-rails", require: false
|
|
78
|
-
gem "cuprite-downloads"
|
|
79
|
-
gem "capybara-screenshot"
|
|
80
|
-
gem "database_cleaner"
|
|
81
|
-
gem "chop"
|
|
82
|
-
gem "email_spec"
|
|
83
|
-
gem "timecop"
|
|
84
|
-
gem "rspec-rails"
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
group :production do
|
|
88
|
-
gem "foreman-export-systemd_user"
|
|
89
|
-
end
|
|
90
|
-
RUBY
|
|
91
|
-
|
|
92
|
-
file "config/initializers/exception_notification.rb", <<~RUBY
|
|
93
|
-
require "exception_notification/rails"
|
|
94
|
-
|
|
95
|
-
ExceptionNotification.configure do |config|
|
|
96
|
-
config.ignored_exceptions = []
|
|
97
|
-
|
|
98
|
-
# Adds a condition to decide when an exception must be ignored or not.
|
|
99
|
-
# The ignore_if method can be invoked multiple times to add extra conditions.
|
|
100
|
-
config.ignore_if do |exception, options|
|
|
101
|
-
not Rails.env.production?
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
config.ignore_if do |exception, options|
|
|
105
|
-
%w[
|
|
106
|
-
ActiveRecord::RecordNotFound
|
|
107
|
-
AbstractController::ActionNotFound
|
|
108
|
-
ActionController::RoutingError
|
|
109
|
-
ActionController::InvalidAuthenticityToken
|
|
110
|
-
ActionView::MissingTemplate
|
|
111
|
-
ActionController::BadRequest
|
|
112
|
-
ActionDispatch::Http::Parameters::ParseError
|
|
113
|
-
ActionDispatch::Http::MimeNegotiation::InvalidType
|
|
114
|
-
].include?(exception.class.to_s)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
config.add_notifier :email, {
|
|
118
|
-
email_prefix: "[\#{File.basename(Dir.pwd)}] ",
|
|
119
|
-
exception_recipients: "micah@botandrose.com",
|
|
120
|
-
smtp_settings: Rails.application.credentials.exception_notification_smtp_settings,
|
|
121
|
-
}
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
if defined?(Rake::Application)
|
|
125
|
-
Rake::Application.prepend Module.new {
|
|
126
|
-
def display_error_message error
|
|
127
|
-
ExceptionNotifier.notify_exception(error)
|
|
128
|
-
super
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def invoke_task task_name
|
|
132
|
-
super
|
|
133
|
-
rescue RuntimeError => exception
|
|
134
|
-
if exception.message.starts_with?("Don't know how to build task")
|
|
135
|
-
ExceptionNotifier.notify_exception(exception)
|
|
136
|
-
end
|
|
137
|
-
raise exception
|
|
138
|
-
end
|
|
139
|
-
}
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
ActionController::Live.prepend Module.new {
|
|
143
|
-
def log_error exception
|
|
144
|
-
ExceptionNotifier.notify_exception exception, env: request.env
|
|
145
|
-
super
|
|
146
|
-
end
|
|
147
|
-
}
|
|
148
|
-
RUBY
|
|
149
|
-
|
|
150
|
-
file "app/assets/config/manifest.js", <<~RUBY
|
|
151
|
-
//= link_tree ../images
|
|
152
|
-
//= link_directory ../stylesheets .css
|
|
153
|
-
//= link_tree ../../javascript .js
|
|
154
|
-
RUBY
|
|
155
|
-
|
|
156
|
-
run "rm -f app/assets/stylesheets/application.css"
|
|
157
|
-
|
|
158
|
-
file "app/assets/stylesheets/application.sass", <<~SASS
|
|
159
|
-
body
|
|
160
|
-
border: 10px solid red
|
|
161
|
-
SASS
|
|
162
|
-
|
|
163
|
-
gsub_file "app/views/layouts/application.html.erb", " <%# Includes all stylesheet files in app/assets/stylesheets %>\n", ''
|
|
164
|
-
gsub_file "app/views/layouts/application.html.erb", 'stylesheet_link_tag :app,', 'stylesheet_link_tag :application,'
|
|
165
|
-
|
|
166
|
-
file "app/views/static/index.html.slim", <<~SLIM
|
|
167
|
-
h1 #{project_name}
|
|
168
|
-
SLIM
|
|
169
|
-
|
|
170
|
-
insert_into_file "config/database.yml", <<~YAML, after: "database: storage/test.sqlite3"
|
|
171
|
-
|
|
172
|
-
staging:
|
|
173
|
-
<<: *default
|
|
174
|
-
database: storage/staging.sqlite3
|
|
175
|
-
YAML
|
|
176
|
-
|
|
177
|
-
insert_into_file "config/database.yml", <<-YAML, after: "# database: path/to/persistent/storage/production.sqlite3"
|
|
178
|
-
|
|
179
|
-
cable:
|
|
180
|
-
<<: *default
|
|
181
|
-
# database: path/to/persistent/storage/production_cable.sqlite3
|
|
182
|
-
migrations_paths: db/cable_migrate
|
|
183
|
-
queue:
|
|
184
|
-
<<: *default
|
|
185
|
-
# database: path/to/persistent/storage/production_queue.sqlite3
|
|
186
|
-
migrations_paths: db/queue_migrate
|
|
187
|
-
YAML
|
|
188
|
-
|
|
189
|
-
gsub_file "config/database.yml", "path/to/persistent/", ""
|
|
190
|
-
|
|
191
|
-
gsub_file "config/environments/production.rb", / (config\.logger.+STDOUT.*)$/, ' # \1'
|
|
192
|
-
|
|
193
|
-
after_bundle do
|
|
194
|
-
run "bard install"
|
|
195
|
-
run "bin/setup"
|
|
196
|
-
run "bard setup"
|
|
197
|
-
end
|
data/lib/bard/cli/open.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
module Bard::CLI::Open
|
|
2
|
-
def self.included mod
|
|
3
|
-
mod.class_eval do
|
|
4
|
-
|
|
5
|
-
desc "open [server=production]", "opens the url in the web browser."
|
|
6
|
-
def open server=:production
|
|
7
|
-
exec "xdg-open #{open_url server}"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
private
|
|
11
|
-
|
|
12
|
-
def open_url server
|
|
13
|
-
if server.to_sym == :ci
|
|
14
|
-
"https://github.com/botandrosedesign/#{project_name}/actions/workflows/ci.yml"
|
|
15
|
-
else
|
|
16
|
-
config[server].ping.first
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
|
data/lib/bard/cli/ping.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require "bard/ping"
|
|
2
|
-
|
|
3
|
-
module Bard::CLI::Ping
|
|
4
|
-
def self.included mod
|
|
5
|
-
mod.class_eval do
|
|
6
|
-
|
|
7
|
-
desc "ping [server=production]", "hits the server over http to verify that its up."
|
|
8
|
-
def ping server=:production
|
|
9
|
-
server = config[server]
|
|
10
|
-
down_urls = Bard::Ping.call(config[server])
|
|
11
|
-
down_urls.each { |url| puts "#{url} is down!" }
|
|
12
|
-
exit 1 if down_urls.any?
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
data/lib/bard/cli/provision.rb
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
require "bard/cli/command"
|
|
2
|
-
require "bard/provision"
|
|
3
|
-
|
|
4
|
-
class Bard::CLI::Provision < Bard::CLI::Command
|
|
5
|
-
STEPS = %w[
|
|
6
|
-
SSH
|
|
7
|
-
User
|
|
8
|
-
AuthorizedKeys
|
|
9
|
-
Swapfile
|
|
10
|
-
Apt
|
|
11
|
-
MySQL
|
|
12
|
-
Repo
|
|
13
|
-
MasterKey
|
|
14
|
-
RVM
|
|
15
|
-
App
|
|
16
|
-
Passenger
|
|
17
|
-
HTTP
|
|
18
|
-
LogRotation
|
|
19
|
-
Data
|
|
20
|
-
Deploy
|
|
21
|
-
]
|
|
22
|
-
|
|
23
|
-
desc "provision [ssh_url] --steps=all", "takes an optional ssh url to a raw ubuntu 22.04 install, and readies it in the shape of :production"
|
|
24
|
-
option :steps, type: :array, default: STEPS
|
|
25
|
-
def provision ssh_url=config[:production].ssh
|
|
26
|
-
# unfreeze the string for later mutation
|
|
27
|
-
ssh_url = ssh_url.dup
|
|
28
|
-
options[:steps].each do |step|
|
|
29
|
-
require "bard/provision/#{step.downcase}"
|
|
30
|
-
Bard::Provision.const_get(step).call(config, ssh_url)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
|
data/lib/bard/cli/run.rb
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
require "bard/command"
|
|
2
|
-
|
|
3
|
-
module Bard::CLI::Run
|
|
4
|
-
def self.included mod
|
|
5
|
-
mod.class_eval do
|
|
6
|
-
|
|
7
|
-
# HACK: we don't use Thor::Base#run, so its okay to stomp on it here
|
|
8
|
-
original_verbose, $VERBOSE = $VERBOSE, nil
|
|
9
|
-
Thor::THOR_RESERVED_WORDS -= ["run"]
|
|
10
|
-
$VERBOSE = original_verbose
|
|
11
|
-
|
|
12
|
-
desc "run <command>", "run the given command on production"
|
|
13
|
-
def run *args
|
|
14
|
-
server = config[:production]
|
|
15
|
-
server.run! *args.join(" "), verbose: true
|
|
16
|
-
rescue Bard::Command::Error => e
|
|
17
|
-
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
|
18
|
-
exit 1
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
data/lib/bard/cli/setup.rb
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require "uri"
|
|
2
|
-
|
|
3
|
-
module Bard::CLI::Setup
|
|
4
|
-
def self.included mod
|
|
5
|
-
mod.class_eval do
|
|
6
|
-
|
|
7
|
-
desc "setup", "installs app in nginx"
|
|
8
|
-
def setup
|
|
9
|
-
system "sudo tee /etc/nginx/snippets/common.conf >/dev/null <<-EOF
|
|
10
|
-
listen 80;
|
|
11
|
-
|
|
12
|
-
passenger_enabled on;
|
|
13
|
-
|
|
14
|
-
location ~* \\.(ico|css|js|gif|jp?g|png|webp) {
|
|
15
|
-
access_log off;
|
|
16
|
-
if (\\$request_filename ~ \"-[0-9a-f]{32,}\\.\") {
|
|
17
|
-
expires max;
|
|
18
|
-
add_header Cache-Control public;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
gzip_static on;
|
|
23
|
-
EOF"
|
|
24
|
-
|
|
25
|
-
path = "/etc/nginx/sites-available/#{project_name}"
|
|
26
|
-
system "sudo tee #{path} >/dev/null <<-EOF
|
|
27
|
-
server {
|
|
28
|
-
include /etc/nginx/snippets/common.conf;
|
|
29
|
-
server_name #{nginx_server_name};
|
|
30
|
-
root #{Dir.pwd}/public;
|
|
31
|
-
}
|
|
32
|
-
EOF"
|
|
33
|
-
|
|
34
|
-
dest_path = path.sub("sites-available", "sites-enabled")
|
|
35
|
-
system "sudo ln -sf #{path} #{dest_path}" if !File.exist?(dest_path)
|
|
36
|
-
|
|
37
|
-
system "sudo service nginx restart"
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
private
|
|
41
|
-
|
|
42
|
-
def nginx_server_name
|
|
43
|
-
case ENV["RAILS_ENV"]
|
|
44
|
-
when "production"
|
|
45
|
-
(config[:production].ping.map do |str|
|
|
46
|
-
"*.#{URI.parse(str).host}"
|
|
47
|
-
end + ["_"]).join(" ")
|
|
48
|
-
when "staging" then "#{project_name}.botandrose.com"
|
|
49
|
-
else "#{project_name}.localhost"
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
data/lib/bard/cli/ssh.rb
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module Bard::CLI::SSH
|
|
2
|
-
def self.included mod
|
|
3
|
-
mod.class_eval do
|
|
4
|
-
|
|
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
|
-
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
|
data/lib/bard/cli/stage.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
require "bard/git"
|
|
2
|
-
require "bard/command"
|
|
3
|
-
|
|
4
|
-
module Bard::CLI::Stage
|
|
5
|
-
def self.included mod
|
|
6
|
-
mod.class_eval do
|
|
7
|
-
|
|
8
|
-
desc "stage [branch=HEAD]", "pushes current branch, and stages it"
|
|
9
|
-
def stage branch=Bard::Git.current_branch
|
|
10
|
-
unless config.servers.key?(:production)
|
|
11
|
-
raise Thor::Error.new("`bard stage` is disabled until a production server is defined. Until then, please use `bard deploy` to deploy to the staging server.")
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
run! "git push -u origin #{branch}", verbose: true
|
|
15
|
-
config[:staging].run! "git fetch && git checkout -f origin/#{branch} && bin/setup"
|
|
16
|
-
puts green("Stage Succeeded")
|
|
17
|
-
|
|
18
|
-
ping :staging
|
|
19
|
-
rescue Bard::Command::Error => e
|
|
20
|
-
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
|
21
|
-
exit 1
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
|
data/lib/bard/cli/vim.rb
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
module Bard::CLI::Vim
|
|
2
|
-
def self.included mod
|
|
3
|
-
mod.class_eval do
|
|
4
|
-
|
|
5
|
-
desc "vim [branch=master]", "open all files that have changed since master"
|
|
6
|
-
def vim branch="master"
|
|
7
|
-
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`"
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
data/lib/bard/default_config.rb
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
module Bard
|
|
2
|
-
# Default configuration that is loaded before user's bard.rb
|
|
3
|
-
# Users can override any of these targets in their bard.rb
|
|
4
|
-
DEFAULT_CONFIG = lambda do |config, project_name|
|
|
5
|
-
# Local development target
|
|
6
|
-
config.instance_eval do
|
|
7
|
-
target :local do
|
|
8
|
-
ssh false
|
|
9
|
-
path "./"
|
|
10
|
-
ping "#{project_name}.local"
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
# Bot and Rose cloud server
|
|
14
|
-
target :gubs do
|
|
15
|
-
ssh "botandrose@cloud.hackett.world:22022",
|
|
16
|
-
path: "Sites/#{project_name}"
|
|
17
|
-
ping false
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# CI target (Jenkins)
|
|
21
|
-
target :ci do
|
|
22
|
-
ssh "jenkins@staging.botandrose.com:22022",
|
|
23
|
-
path: "jobs/#{project_name}/workspace"
|
|
24
|
-
ping false
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Staging server
|
|
28
|
-
target :staging do
|
|
29
|
-
ssh "www@staging.botandrose.com:22022",
|
|
30
|
-
path: project_name
|
|
31
|
-
ping "#{project_name}.botandrose.com"
|
|
32
|
-
end
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
require "bard/deploy_strategy"
|
|
2
|
-
|
|
3
|
-
module Bard
|
|
4
|
-
class DeployStrategy
|
|
5
|
-
class SSH < DeployStrategy
|
|
6
|
-
def deploy
|
|
7
|
-
# Require SSH capability
|
|
8
|
-
target.require_capability!(:ssh)
|
|
9
|
-
|
|
10
|
-
# Determine branch
|
|
11
|
-
branch = target.instance_variable_get(:@branch) || "master"
|
|
12
|
-
|
|
13
|
-
# Run git pull and setup on remote server
|
|
14
|
-
target.run! "git pull origin #{branch}"
|
|
15
|
-
target.run! "bin/setup"
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
data/lib/bard/github_pages.rb
DELETED
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
require 'delegate'
|
|
2
|
-
require 'fileutils'
|
|
3
|
-
require 'bard/git'
|
|
4
|
-
|
|
5
|
-
module Bard
|
|
6
|
-
class GithubPages < SimpleDelegator
|
|
7
|
-
def deploy server
|
|
8
|
-
@sha = Git.sha_of(Git.current_branch)
|
|
9
|
-
@build_dir = "tmp/github-build-#{@sha}"
|
|
10
|
-
@branch = "gh-pages"
|
|
11
|
-
@domain = server.ping.first
|
|
12
|
-
@domain = URI.parse(@domain).hostname if @domain
|
|
13
|
-
|
|
14
|
-
puts "Starting deployment to GitHub Pages..."
|
|
15
|
-
|
|
16
|
-
build_site
|
|
17
|
-
tree_sha = create_tree_from_build
|
|
18
|
-
new_commit = create_commit(tree_sha)
|
|
19
|
-
commit_and_push new_commit
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def build_site
|
|
25
|
-
with_locked_port do |port|
|
|
26
|
-
system "rm -rf #{@build_dir.sub(@sha, "*")}"
|
|
27
|
-
run! <<~SH
|
|
28
|
-
set -e
|
|
29
|
-
RAILS_ENV=production bundle exec rails s -p #{port} -d --pid tmp/pids/server.pid
|
|
30
|
-
OUTPUT=$(bundle exec rake assets:clean assets:precompile 2>&1) || echo "$OUTPUT"
|
|
31
|
-
|
|
32
|
-
# Create the output directory and enter it
|
|
33
|
-
BUILD=#{@build_dir}
|
|
34
|
-
rm -rf $BUILD
|
|
35
|
-
mkdir -p $BUILD
|
|
36
|
-
cp -R public/assets $BUILD/
|
|
37
|
-
cd $BUILD
|
|
38
|
-
|
|
39
|
-
# wait until server responds
|
|
40
|
-
echo waiting...
|
|
41
|
-
curl -s --retry 5 --retry-delay 2 http://localhost:#{port} >/dev/null 2>&1
|
|
42
|
-
|
|
43
|
-
echo copying...
|
|
44
|
-
# Mirror the site to the build folder, ignoring links with query params
|
|
45
|
-
wget -nv -r -l inf --no-remove-listing -FEnH --reject-regex "(\\.*)\\?(.*)" http://localhost:#{port}/ 2>&1
|
|
46
|
-
|
|
47
|
-
echo #{@domain} > CNAME
|
|
48
|
-
SH
|
|
49
|
-
ensure # cleanup
|
|
50
|
-
run! <<~SH
|
|
51
|
-
cat tmp/pids/server.pid | xargs -I {} kill {}
|
|
52
|
-
rm -rf public/assets
|
|
53
|
-
SH
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def with_locked_port
|
|
58
|
-
(3000..3020).each do |port|
|
|
59
|
-
lock_file = "/tmp/bard_github_pages_#{port}.lock"
|
|
60
|
-
file = File.open(lock_file, File::RDWR | File::CREAT, 0644)
|
|
61
|
-
if file.flock(File::LOCK_EX | File::LOCK_NB)
|
|
62
|
-
begin
|
|
63
|
-
yield port
|
|
64
|
-
return
|
|
65
|
-
ensure
|
|
66
|
-
file.flock(File::LOCK_UN)
|
|
67
|
-
file.close
|
|
68
|
-
end
|
|
69
|
-
else
|
|
70
|
-
file.close
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
raise "Could not find an available port for GitHub Pages deployment (checked 3000-3020)."
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def create_tree_from_build
|
|
77
|
-
# Create temporary index
|
|
78
|
-
git_index_file = ".git/tmp-index"
|
|
79
|
-
git = "GIT_INDEX_FILE=#{git_index_file} git"
|
|
80
|
-
run! "#{git} read-tree --empty"
|
|
81
|
-
|
|
82
|
-
# Add build files to temporary index
|
|
83
|
-
Dir.chdir(@build_dir) do
|
|
84
|
-
Dir.glob('**/*', File::FNM_DOTMATCH).each do |file|
|
|
85
|
-
next if file == '.' || file == '..'
|
|
86
|
-
if File.file?(file)
|
|
87
|
-
run! "#{git} update-index --add --cacheinfo 100644 $(#{git} hash-object -w #{file}) #{file}"
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Create tree object from index
|
|
93
|
-
tree_sha = `#{git} write-tree`.chomp
|
|
94
|
-
|
|
95
|
-
# Clean up temporary index
|
|
96
|
-
FileUtils.rm_f(git_index_file)
|
|
97
|
-
|
|
98
|
-
tree_sha
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def create_commit tree_sha
|
|
102
|
-
# Get parent commit if branch exists
|
|
103
|
-
parent = get_parent_commit
|
|
104
|
-
|
|
105
|
-
# Create commit object
|
|
106
|
-
message = "'Deploying to #{@branch} from @ #{@sha} 🚀'"
|
|
107
|
-
args = ['commit-tree', tree_sha]
|
|
108
|
-
args += ['-p', parent] if parent
|
|
109
|
-
args += ['-m', message]
|
|
110
|
-
|
|
111
|
-
commit_sha = `git #{args.join(' ')}`.chomp
|
|
112
|
-
|
|
113
|
-
commit_sha
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def get_parent_commit
|
|
117
|
-
Git.sha_of("#{@branch}^{commit}")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def commit_and_push commit_sha
|
|
121
|
-
if branch_exists?
|
|
122
|
-
run! "git update-ref refs/heads/#{@branch} #{commit_sha}"
|
|
123
|
-
else
|
|
124
|
-
run! "git branch #{@branch} #{commit_sha}"
|
|
125
|
-
end
|
|
126
|
-
run! "git push -f origin #{@branch}:refs/heads/#{@branch}"
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def branch_exists?
|
|
130
|
-
system("git show-ref --verify --quiet refs/heads/#{@branch}")
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
data/lib/bard/provision/app.rb
DELETED
data/lib/bard/provision/apt.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# apt sanity
|
|
2
|
-
|
|
3
|
-
class Bard::Provision::Apt < Bard::Provision
|
|
4
|
-
def call
|
|
5
|
-
print "Apt:"
|
|
6
|
-
provision_server.run! [
|
|
7
|
-
%(echo "\\$nrconf{restart} = \\"a\\";" | sudo tee /etc/needrestart/conf.d/90-autorestart.conf),
|
|
8
|
-
"sudo apt-get update -y",
|
|
9
|
-
"sudo apt-get upgrade -y",
|
|
10
|
-
"sudo apt-get install -y curl",
|
|
11
|
-
].join("; "), home: true
|
|
12
|
-
|
|
13
|
-
puts " ✓"
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# install public keys if missing
|
|
2
|
-
|
|
3
|
-
class Bard::Provision::AuthorizedKeys < Bard::Provision
|
|
4
|
-
def call
|
|
5
|
-
print "Authorized Keys:"
|
|
6
|
-
|
|
7
|
-
KEYS.each do |search_text, full_key|
|
|
8
|
-
file = "~/.ssh/authorized_keys"
|
|
9
|
-
provision_server.run! <<~SH, home: true
|
|
10
|
-
if ! grep -F -q "#{search_text}" #{file}; then
|
|
11
|
-
echo "#{full_key}" >> #{file}
|
|
12
|
-
fi
|
|
13
|
-
SH
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
puts " ✓"
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
KEYS = {
|
|
20
|
-
"micah@haku" => "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDAH235mtpxPQucd0bIgdufo1bR3By2+a+NPHiZS1P7SpI73evN9+hY7ri+gLscPLRWeoy1ig/TbyfN1AqJmfqIaskZdYOdcEQdOum4AwDMY5L6OAq2o5NER047RqDxE6Pjm2nfRVVw2Dz38eeco+ouchCI+sY5pJL/wEZItrCpPjKvwo56uln1rL6Smd4Kh98ZBKTGL8xKs95rNmFdBCCq4eUE28JDgkJAiLDZ/4u2LNrgEr7/brkUieZjaZ4BacBi8EQvyvMWmZ0g2MoG+Ptxn/3K2nd1QqdhfINqHBVCi8UbkP08B0Msif/7Dycuxd7DU9cVZ3RgnhLtbIsQ8HaYVj5yCKB6CuX3lv3H4YKBghBC/TnJD5Nq5xcSYTW0BKKrusCb/OoOk5AUV+BGM1+R70fno8reVEBUlZDkWapHxmqgNnf1byL7Aol/L5SWgyfSLT6b5FjI6g/U+dhaecYY9T9g/GWo+JiwZktc094O0ujlQHoibMY2M0csVfvO9Oc= micah@haku",
|
|
21
|
-
"gubs@Theia.local" => "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEApJh0E8ZlaLbMUWGvryAhEBRnnI519ZKz586vdQTuIPlDb9xhe5m3Ys8Fk9LKqJUQNxBV6qCGOXNgNdWySkk2ChmmgDnPfr7/31ZuOAASFbUY0PtaDXUsMVvs1Uu2VhtRU9gSduGonEHG7iBpAuBI23CxU4yPS6o3pv7L9xwnmULes5F9S4/nDvPig15h9byInyHOLDV0XjHFS+2OlSWO/xC8uqH5CdlxXFAmPQ0R69qmILl0rcTPyNMLJGcJGUzb/LMRJX/RDyTpZeJPjH4V+zksQ/4YQ3LWvLrlZL6QLuM285ve4mQa3vBY4WMqNlp4Ig3ZCFOpMKmpvTn7pFUmKw== gubs@Theia.local",
|
|
22
|
-
}
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
|
data/lib/bard/provision/data.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# copy data from production
|
|
2
|
-
|
|
3
|
-
class Bard::Provision::Data < Bard::Provision
|
|
4
|
-
def call
|
|
5
|
-
print "Data:"
|
|
6
|
-
|
|
7
|
-
print " Dumping #{server.key} database to file"
|
|
8
|
-
server.run! "bin/rake db:dump"
|
|
9
|
-
|
|
10
|
-
print " Transfering file from #{server.key},"
|
|
11
|
-
server.copy_file "db/data.sql.gz", to: provision_server, verbose: false
|
|
12
|
-
|
|
13
|
-
print " Loading file into database,"
|
|
14
|
-
provision_server.run! "bin/rake db:load"
|
|
15
|
-
|
|
16
|
-
config.data.each do |path|
|
|
17
|
-
print " Synchronizing files in #{path},"
|
|
18
|
-
server.copy_dir path, to: provision_server, verbose: false
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
puts " ✓"
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|