bard 1.3.9 → 1.4.1
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/bard.gemspec +1 -0
- data/install_files/.github/workflows/ci.yml +8 -0
- data/install_files/apt_dependencies.rb +1 -0
- data/lib/bard/cli/new.rb +5 -1
- data/lib/bard/cli/new_rails_template.rb +82 -7
- data/lib/bard/cli/provision.rb +3 -2
- data/lib/bard/git.rb +3 -1
- data/lib/bard/github.rb +56 -2
- data/lib/bard/github_pages.rb +1 -3
- data/lib/bard/provision/mysql.rb +1 -0
- data/lib/bard/provision/user.rb +1 -1
- data/lib/bard/version.rb +1 -1
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b61ad7f978453da17070fecbb92f64e0fc3311f3c8b530d7cb89227f6a72d286
|
4
|
+
data.tar.gz: f0961592b8234b9c71929cfb5f34b9cc9edbf4f75485331bdf25a6a27e620e44
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bb9fa351d2b084dc624909e0691aa0ad698c182bf5d0417c3e5731f63bc9ac2aaa90b23be87ba3c894abb74a4b16baf5a638124789eb3eefd8e2087ba6b71257
|
7
|
+
data.tar.gz: 902e8f5be5ae6c1c47cbf34c771fe77c1e3dc298f345983732c6b7cd74eb7293c9d6c325cf2e90814532a85bbaa22b9825c416e507ee40aec88c9068e1bfd328
|
data/bard.gemspec
CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.add_dependency "thor", ">= 0.19.0"
|
21
21
|
spec.add_dependency "rvm"
|
22
22
|
spec.add_dependency "term-ansicolor", ">= 1.0.3"
|
23
|
+
spec.add_dependency "rbnacl"
|
23
24
|
|
24
25
|
spec.add_development_dependency "byebug"
|
25
26
|
spec.add_development_dependency "rspec"
|
@@ -30,6 +30,14 @@ jobs:
|
|
30
30
|
uses: ruby/setup-ruby@v1
|
31
31
|
with:
|
32
32
|
bundler-cache: true
|
33
|
+
- name: Set up apt packages
|
34
|
+
run: |
|
35
|
+
sudo rm -f /var/lib/man-db/auto-update
|
36
|
+
echo "APT_PACKAGES=$(paste -sd " " Aptfile)" >> $GITHUB_ENV
|
37
|
+
- name: Apt packages
|
38
|
+
uses: awalsh128/cache-apt-pkgs-action@latest
|
39
|
+
with:
|
40
|
+
packages: ${{ env.APT_PACKAGES }}
|
33
41
|
- name: Setup
|
34
42
|
run: bin/setup
|
35
43
|
- name: Run tests
|
@@ -3,6 +3,7 @@ module AptDependencies
|
|
3
3
|
|
4
4
|
def self.ensure!
|
5
5
|
return "true" if deps_to_install.none?
|
6
|
+
return "true" if ENV["APT_PACKAGES"] # already installed via github actions
|
6
7
|
if sudo_password_required? && ENV["RAILS_ENV"] != "development"
|
7
8
|
$stderr.puts "sudo requires password! cannot install #{deps_to_install.join(' ')}"
|
8
9
|
exit 1
|
data/lib/bard/cli/new.rb
CHANGED
@@ -40,7 +40,8 @@ class Bard::CLI::New < Bard::CLI::Command
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def push_to_github
|
43
|
-
Bard::Github.new(project_name)
|
43
|
+
api = Bard::Github.new(project_name)
|
44
|
+
api.create_repo
|
44
45
|
run! <<~BASH
|
45
46
|
cd ../#{project_name}
|
46
47
|
git init -b master
|
@@ -49,6 +50,9 @@ class Bard::CLI::New < Bard::CLI::Command
|
|
49
50
|
git remote add origin git@github.com:botandrosedesign/#{project_name}
|
50
51
|
git push -u origin master
|
51
52
|
BASH
|
53
|
+
api.add_master_key File.read("../#{project_name}/config/master.key")
|
54
|
+
api.add_master_branch_protection
|
55
|
+
api.patch(nil, allow_auto_merge: true)
|
52
56
|
end
|
53
57
|
|
54
58
|
def stage
|
@@ -21,6 +21,9 @@ file ".gitignore", <<~GITIGNORE
|
|
21
21
|
# Ignore master key for decrypting credentials and more.
|
22
22
|
/config/master.key
|
23
23
|
|
24
|
+
# ignore coverage reports
|
25
|
+
/coverage
|
26
|
+
|
24
27
|
# Ignore database dumps
|
25
28
|
/db/data.*
|
26
29
|
|
@@ -39,30 +42,32 @@ file "Gemfile", <<~RUBY
|
|
39
42
|
|
40
43
|
gem "bootsnap", require: false
|
41
44
|
gem "rails", "~>8.0.0"
|
45
|
+
gem "solid_cache"
|
46
|
+
gem "solid_queue"
|
47
|
+
gem "solid_cable"
|
42
48
|
gem "bard-rails"
|
43
49
|
gem "sqlite3"
|
50
|
+
gem "image_processing"
|
51
|
+
gem "puma"
|
52
|
+
gem "exception_notification"
|
44
53
|
|
54
|
+
# css
|
45
55
|
gem "sprockets-rails"
|
46
56
|
gem "dartsass-sprockets"
|
47
57
|
gem "bard-sass"
|
48
58
|
|
59
|
+
# js
|
49
60
|
gem "importmap-rails"
|
50
61
|
gem "turbo-rails"
|
51
62
|
gem "stimulus-rails"
|
52
63
|
|
53
|
-
gem "solid_cache"
|
54
|
-
gem "solid_queue"
|
55
|
-
gem "solid_cable"
|
56
|
-
|
57
|
-
gem "image_processing"
|
58
|
-
gem "puma"
|
59
|
-
|
60
64
|
group :development do
|
61
65
|
gem "web-console"
|
62
66
|
end
|
63
67
|
|
64
68
|
group :development, :test do
|
65
69
|
gem "debug", require: "debug/prelude"
|
70
|
+
gem "parallel_tests", "~>3.9.0" # 3.10 pegs CPU
|
66
71
|
gem "brakeman", require: false
|
67
72
|
gem "rubocop-rails-omakase", require: false
|
68
73
|
end
|
@@ -83,6 +88,64 @@ file "Gemfile", <<~RUBY
|
|
83
88
|
end
|
84
89
|
RUBY
|
85
90
|
|
91
|
+
file "config/initializers/exception_notification.rb", <<~RUBY
|
92
|
+
require "exception_notification/rails"
|
93
|
+
|
94
|
+
ExceptionNotification.configure do |config|
|
95
|
+
config.ignored_exceptions = []
|
96
|
+
|
97
|
+
# Adds a condition to decide when an exception must be ignored or not.
|
98
|
+
# The ignore_if method can be invoked multiple times to add extra conditions.
|
99
|
+
config.ignore_if do |exception, options|
|
100
|
+
not Rails.env.production?
|
101
|
+
end
|
102
|
+
|
103
|
+
config.ignore_if do |exception, options|
|
104
|
+
%w[
|
105
|
+
ActiveRecord::RecordNotFound
|
106
|
+
AbstractController::ActionNotFound
|
107
|
+
ActionController::RoutingError
|
108
|
+
ActionController::InvalidAuthenticityToken
|
109
|
+
ActionView::MissingTemplate
|
110
|
+
ActionController::BadRequest
|
111
|
+
ActionDispatch::Http::Parameters::ParseError
|
112
|
+
ActionDispatch::Http::MimeNegotiation::InvalidType
|
113
|
+
].include?(exception.class.to_s)
|
114
|
+
end
|
115
|
+
|
116
|
+
config.add_notifier :email, {
|
117
|
+
email_prefix: "[\#{File.basename(Dir.pwd)}] ",
|
118
|
+
exception_recipients: "micah@botandrose.com",
|
119
|
+
smtp_settings: Rails.application.credentials.exception_notification_smtp_settings,
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
if defined?(Rake::Application)
|
124
|
+
Rake::Application.prepend Module.new {
|
125
|
+
def display_error_message error
|
126
|
+
ExceptionNotifier.notify_exception(error)
|
127
|
+
super
|
128
|
+
end
|
129
|
+
|
130
|
+
def invoke_task task_name
|
131
|
+
super
|
132
|
+
rescue RuntimeError => exception
|
133
|
+
if exception.message.starts_with?("Don't know how to build task")
|
134
|
+
ExceptionNotifier.notify_exception(exception)
|
135
|
+
end
|
136
|
+
raise exception
|
137
|
+
end
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
ActionController::Live.prepend Module.new {
|
142
|
+
def log_error exception
|
143
|
+
ExceptionNotifier.notify_exception exception, env: request.env
|
144
|
+
super
|
145
|
+
end
|
146
|
+
}
|
147
|
+
RUBY
|
148
|
+
|
86
149
|
file "app/assets/config/manifest.js", <<~RUBY
|
87
150
|
//= link_tree ../images
|
88
151
|
//= link_directory ../stylesheets .css
|
@@ -110,6 +173,18 @@ insert_into_file "config/database.yml", <<~YAML, after: "database: storage/test.
|
|
110
173
|
database: storage/staging.sqlite3
|
111
174
|
YAML
|
112
175
|
|
176
|
+
insert_into_file "config/database.yml", <<-YAML, after: "# database: path/to/persistent/storage/production.sqlite3"
|
177
|
+
|
178
|
+
cable:
|
179
|
+
<<: *default
|
180
|
+
# database: path/to/persistent/storage/production_cable.sqlite3
|
181
|
+
migrations_paths: db/cable_migrate
|
182
|
+
queue:
|
183
|
+
<<: *default
|
184
|
+
# database: path/to/persistent/storage/production_queue.sqlite3
|
185
|
+
migrations_paths: db/queue_migrate
|
186
|
+
YAML
|
187
|
+
|
113
188
|
gsub_file "config/environments/production.rb", / (config\.logger.+STDOUT.*)$/, ' # \1'
|
114
189
|
|
115
190
|
after_bundle do
|
data/lib/bard/cli/provision.rb
CHANGED
@@ -23,10 +23,11 @@ class Bard::CLI::Provision < Bard::CLI::Command
|
|
23
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
24
|
option :steps, type: :array, default: STEPS
|
25
25
|
def provision ssh_url=config[:production].ssh
|
26
|
+
# unfreeze the string for later mutation
|
27
|
+
ssh_url = ssh_url.dup
|
26
28
|
options[:steps].each do |step|
|
27
29
|
require "bard/provision/#{step.downcase}"
|
28
|
-
|
29
|
-
Bard::Provision.const_get(step).call(config, ssh_url.dup)
|
30
|
+
Bard::Provision.const_get(step).call(config, ssh_url)
|
30
31
|
end
|
31
32
|
end
|
32
33
|
end
|
data/lib/bard/git.rb
CHANGED
data/lib/bard/github.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "net/http"
|
2
2
|
require "json"
|
3
3
|
require "base64"
|
4
|
+
require "rbnacl"
|
4
5
|
|
5
6
|
module Bard
|
6
7
|
class Github < Struct.new(:project_name)
|
@@ -19,6 +20,22 @@ module Bard
|
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
23
|
+
def put path, params={}
|
24
|
+
request(path) do |uri|
|
25
|
+
Net::HTTP::Put.new(uri).tap do |r|
|
26
|
+
r.body = JSON.dump(params)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def patch path, params={}
|
32
|
+
request(path) do |uri|
|
33
|
+
Net::HTTP::Patch.new(uri).tap do |r|
|
34
|
+
r.body = JSON.dump(params)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
22
39
|
def delete path, params={}
|
23
40
|
request(path) do |uri|
|
24
41
|
Net::HTTP::Delete.new(uri).tap do |r|
|
@@ -36,6 +53,38 @@ module Bard
|
|
36
53
|
post("keys", title:, key:)
|
37
54
|
end
|
38
55
|
|
56
|
+
def add_master_key master_key
|
57
|
+
response = get("actions/secrets/public-key")
|
58
|
+
public_key, public_key_id = response.values_at("key", "key_id")
|
59
|
+
|
60
|
+
def encrypt_secret(encoded_public_key, secret)
|
61
|
+
decoded_key = Base64.decode64(encoded_public_key)
|
62
|
+
public_key = RbNaCl::PublicKey.new(decoded_key)
|
63
|
+
box = RbNaCl::Boxes::Sealed.from_public_key(public_key)
|
64
|
+
encrypted_secret = box.encrypt(secret)
|
65
|
+
Base64.strict_encode64(encrypted_secret)
|
66
|
+
end
|
67
|
+
|
68
|
+
encrypted_master_key = encrypt_secret(public_key, master_key)
|
69
|
+
|
70
|
+
put("actions/secrets/RAILS_MASTER_KEY", {
|
71
|
+
encrypted_value: encrypted_master_key,
|
72
|
+
key_id: public_key_id,
|
73
|
+
})
|
74
|
+
end
|
75
|
+
|
76
|
+
def add_master_branch_protection
|
77
|
+
put("branches/master/protection", {
|
78
|
+
required_status_checks: {
|
79
|
+
strict: false,
|
80
|
+
contexts: [],
|
81
|
+
},
|
82
|
+
enforce_admins: nil,
|
83
|
+
required_pull_request_reviews: nil,
|
84
|
+
restrictions: nil,
|
85
|
+
})
|
86
|
+
end
|
87
|
+
|
39
88
|
def create_repo
|
40
89
|
post("https://api.github.com/orgs/botandrosedesign/repos", {
|
41
90
|
name: project_name,
|
@@ -44,7 +93,7 @@ module Bard
|
|
44
93
|
end
|
45
94
|
|
46
95
|
def delete_repo
|
47
|
-
delete(
|
96
|
+
delete(nil)
|
48
97
|
end
|
49
98
|
|
50
99
|
private
|
@@ -60,7 +109,12 @@ module Bard
|
|
60
109
|
uri = if path =~ /^http/
|
61
110
|
URI(path)
|
62
111
|
else
|
63
|
-
|
112
|
+
base = "https://api.github.com/repos/botandrosedesign/#{project_name}"
|
113
|
+
if path
|
114
|
+
URI.join(base, path)
|
115
|
+
else
|
116
|
+
URI(base)
|
117
|
+
end
|
64
118
|
end
|
65
119
|
|
66
120
|
req = nil
|
data/lib/bard/github_pages.rb
CHANGED
data/lib/bard/provision/mysql.rb
CHANGED
@@ -8,6 +8,7 @@ class Bard::Provision::MySQL < Bard::Provision
|
|
8
8
|
provision_server.run! [
|
9
9
|
"sudo apt-get install -y mysql-server",
|
10
10
|
%(sudo mysql -uroot -e "ALTER USER \\"'\\"root\\"'\\"@\\"'\\"localhost\\"'\\" IDENTIFIED WITH mysql_native_password BY \\"'\\"\\"'\\", \\"'\\"root\\"'\\"@\\"'\\"localhost\\"'\\" PASSWORD EXPIRE NEVER; FLUSH PRIVILEGES;"),
|
11
|
+
%(mysql -uroot -e "UPDATE mysql.user SET password_lifetime = NULL WHERE user = 'root' AND host = 'localhost';"),
|
11
12
|
].join("; "), home: true
|
12
13
|
end
|
13
14
|
|
data/lib/bard/provision/user.rb
CHANGED
@@ -36,7 +36,7 @@ class Bard::Provision::User < Bard::Provision
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def ssh_with_user? ssh_uri, user: ssh_uri.user
|
39
|
-
system "ssh -o ConnectTimeout=2 -p#{ssh_uri.port || 22} #{user}@#{ssh_uri.host}
|
39
|
+
system "ssh -o ConnectTimeout=2 -p#{ssh_uri.port || 22} #{user}@#{ssh_uri.host} : >/dev/null 2>&1"
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
data/lib/bard/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-02-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 1.0.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rbnacl
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: byebug
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|