bard 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/bard/cli/command.rb +19 -0
- data/lib/bard/cli/deploy.rb +13 -1
- data/lib/bard/cli/new.rb +68 -0
- data/lib/bard/cli/new_rails_template.rb +88 -0
- data/lib/bard/cli.rb +16 -7
- data/lib/bard/config.rb +12 -0
- data/lib/bard/github.rb +20 -1
- data/lib/bard/github_pages.rb +112 -0
- data/lib/bard/server.rb +2 -2
- data/lib/bard/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 50507cf111440a4f0d9f6cd1ee580f6749f81534c1c2f507fb32adcf7d49cbe7
|
4
|
+
data.tar.gz: e0386582b40d92ca6d5d003f1b83f03c34ad19968338b23e468f08778bdec968
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3790197e55287ec52f6f4ee62b4e7df4cb02d148182520a913ac2ca235344cd7bb62f3b3a4ed53bb50e549cb08594d39de72c8a52de00fa441d65c52ecd696c
|
7
|
+
data.tar.gz: 8a6525ca5efc614ed59f51c811d39733bec7d5c5e9c1966510006d221d0d5654402098cb9f492e7ce3289cda3d43748b9af1b726a25a22e9b98718f461ec5c90
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
3
|
+
class Bard::CLI::Command < SimpleDelegator
|
4
|
+
def self.desc command, description
|
5
|
+
@command = command
|
6
|
+
@method = command.split(" ").first.to_sym
|
7
|
+
@description = description
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.setup cli
|
11
|
+
cli.desc @command, @description
|
12
|
+
|
13
|
+
method = @method # put in local variable so next block can capture it
|
14
|
+
cli.define_method method do |*args|
|
15
|
+
command = Bard::CLI::New.new(self)
|
16
|
+
command.send method, *args
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/bard/cli/deploy.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "bard/git"
|
2
2
|
require "bard/command"
|
3
|
+
require "bard/github_pages"
|
3
4
|
|
4
5
|
module Bard::CLI::Deploy
|
5
6
|
def self.included mod
|
@@ -7,6 +8,7 @@ module Bard::CLI::Deploy
|
|
7
8
|
|
8
9
|
option :"skip-ci", type: :boolean
|
9
10
|
option :"local-ci", type: :boolean
|
11
|
+
option :clone, type: :boolean
|
10
12
|
desc "deploy [TO=production]", "checks that current branch is a ff with master, checks with ci, merges into master, deploys to target, and then deletes branch."
|
11
13
|
def deploy to=:production
|
12
14
|
branch = Bard::Git.current_branch
|
@@ -37,7 +39,17 @@ module Bard::CLI::Deploy
|
|
37
39
|
run! "git push github"
|
38
40
|
end
|
39
41
|
|
40
|
-
|
42
|
+
if options[:clone]
|
43
|
+
config[to].run! "git clone git@github.com:botandrosedesign/#{project_name}", home: true
|
44
|
+
invoke :master_key, nil, from: "local", to: to
|
45
|
+
config[to].run! "bin/setup && bard setup"
|
46
|
+
else
|
47
|
+
if config[to].github_pages
|
48
|
+
Bard::GithubPages.new(self).deploy(config[to])
|
49
|
+
else
|
50
|
+
config[to].run! "git pull origin master && bin/setup"
|
51
|
+
end
|
52
|
+
end
|
41
53
|
|
42
54
|
puts green("Deploy Succeeded")
|
43
55
|
|
data/lib/bard/cli/new.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require "bard/cli/command"
|
2
|
+
require "bard/github"
|
3
|
+
|
4
|
+
class Bard::CLI::New < Bard::CLI::Command
|
5
|
+
desc "new <project-name>", "creates new bard app named <project-name>"
|
6
|
+
def new project_name
|
7
|
+
@project_name = project_name
|
8
|
+
validate
|
9
|
+
create_project
|
10
|
+
push_to_github
|
11
|
+
stage
|
12
|
+
puts green("Project #{project_name} created!")
|
13
|
+
puts "Please cd ../#{project_name}"
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_accessor :project_name
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def validate
|
21
|
+
if project_name !~ /^[a-z][a-z0-9]*\Z/
|
22
|
+
puts red("!!! ") + "Invalid project name: #{yellow(project_name)}."
|
23
|
+
puts "The first character must be a lowercase letter, and all following characters must be a lowercase letter or number."
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_project
|
29
|
+
run! <<~BASH
|
30
|
+
env -i bash -lc '
|
31
|
+
export HOME=~
|
32
|
+
cd ..
|
33
|
+
source ~/.rvm/scripts/rvm
|
34
|
+
rvm use --create #{ruby_version}@#{project_name}
|
35
|
+
|
36
|
+
gem list rails -i && gem install rails --no-document
|
37
|
+
rails new #{project_name} --skip-kamal -m #{template_path}
|
38
|
+
'
|
39
|
+
BASH
|
40
|
+
end
|
41
|
+
|
42
|
+
def push_to_github
|
43
|
+
Bard::Github.new(project_name).create_repo
|
44
|
+
run! <<~BASH
|
45
|
+
cd ../#{project_name}
|
46
|
+
git add -A
|
47
|
+
git commit -m"initial commit."
|
48
|
+
git remote add origin git@github.com:botandrosedesign/#{project_name}
|
49
|
+
git push -u origin master
|
50
|
+
BASH
|
51
|
+
end
|
52
|
+
|
53
|
+
def stage
|
54
|
+
run! <<~BASH
|
55
|
+
cd ../#{project_name}
|
56
|
+
bard deploy --provision
|
57
|
+
BASH
|
58
|
+
end
|
59
|
+
|
60
|
+
def ruby_version
|
61
|
+
File.read(".ruby-version").chomp
|
62
|
+
end
|
63
|
+
|
64
|
+
def template_path
|
65
|
+
File.expand_path("new_rails_template.rb", __dir__)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
ruby_version, project_name = (`rvm current name`.chomp).split("@")
|
2
|
+
|
3
|
+
file ".ruby-version", ruby_version
|
4
|
+
file ".ruby-gemset", project_name
|
5
|
+
|
6
|
+
file "Gemfile", <<~RUBY
|
7
|
+
source "https://rubygems.org"
|
8
|
+
|
9
|
+
gem "bootsnap", require: false
|
10
|
+
gem "rails", "~>8.0.0"
|
11
|
+
gem "bard-rails"
|
12
|
+
gem "sqlite3"
|
13
|
+
|
14
|
+
gem "sprockets-rails"
|
15
|
+
gem "dartsass-sprockets"
|
16
|
+
gem "bard-sass"
|
17
|
+
|
18
|
+
gem "importmap-rails"
|
19
|
+
gem "turbo-rails"
|
20
|
+
gem "stimulus-rails"
|
21
|
+
|
22
|
+
gem "solid_cache"
|
23
|
+
gem "solid_queue"
|
24
|
+
gem "solid_cable"
|
25
|
+
|
26
|
+
gem "image_processing"
|
27
|
+
|
28
|
+
group :development do
|
29
|
+
gem "web-console"
|
30
|
+
end
|
31
|
+
|
32
|
+
group :development, :test do
|
33
|
+
gem "debug", require: "debug/prelude"
|
34
|
+
gem "brakeman", require: false
|
35
|
+
gem "rubocop-rails-omakase", require: false
|
36
|
+
end
|
37
|
+
|
38
|
+
group :test do
|
39
|
+
gem "cucumber-rails", require: false
|
40
|
+
gem "cuprite-downloads"
|
41
|
+
gem "capybara-screenshot"
|
42
|
+
gem "database_cleaner"
|
43
|
+
gem "puma"
|
44
|
+
gem "chop"
|
45
|
+
gem "email_spec"
|
46
|
+
gem "timecop"
|
47
|
+
gem "rspec-rails"
|
48
|
+
end
|
49
|
+
|
50
|
+
group :production do
|
51
|
+
gem "foreman-export-systemd_user"
|
52
|
+
gem "puma"
|
53
|
+
end
|
54
|
+
RUBY
|
55
|
+
|
56
|
+
file "app/assets/config/manifest.js", <<~RUBY
|
57
|
+
//= link_tree ../images
|
58
|
+
//= link_directory ../stylesheets .css
|
59
|
+
//= link_tree ../../javascript .js
|
60
|
+
RUBY
|
61
|
+
|
62
|
+
run "rm -f app/assets/stylesheets/application.css"
|
63
|
+
|
64
|
+
file "app/assets/stylesheets/application.sass", <<~SASS
|
65
|
+
body
|
66
|
+
border: 10px solid red
|
67
|
+
SASS
|
68
|
+
|
69
|
+
gsub_file "app/views/layouts/application.html.erb", " <%# Includes all stylesheet files in app/assets/stylesheets %>\n", ''
|
70
|
+
gsub_file "app/views/layouts/application.html.erb", 'stylesheet_link_tag :app,', 'stylesheet_link_tag :application,'
|
71
|
+
|
72
|
+
file "app/views/static/index.html.slim", <<~SLIM
|
73
|
+
h1 #{project_name}
|
74
|
+
SLIM
|
75
|
+
|
76
|
+
insert_into_file "config/database.yml", <<~YAML, after: "database: storage/test.sqlite3"
|
77
|
+
|
78
|
+
staging:
|
79
|
+
<<: *default
|
80
|
+
database: storage/staging.sqlite3
|
81
|
+
YAML
|
82
|
+
|
83
|
+
after_bundle do
|
84
|
+
run "bard install"
|
85
|
+
run "bin/setup"
|
86
|
+
run "bard setup"
|
87
|
+
end
|
88
|
+
|
data/lib/bard/cli.rb
CHANGED
@@ -31,8 +31,24 @@ module Bard
|
|
31
31
|
include const_get(klass)
|
32
32
|
end
|
33
33
|
|
34
|
+
{
|
35
|
+
new: "New",
|
36
|
+
}.each do |command, klass|
|
37
|
+
require "bard/cli/#{command}"
|
38
|
+
const_get(klass).setup(self)
|
39
|
+
end
|
40
|
+
|
34
41
|
def self.exit_on_failure? = true
|
35
42
|
|
43
|
+
no_commands do
|
44
|
+
def run!(...)
|
45
|
+
Bard::Command.run!(...)
|
46
|
+
rescue Bard::Command::Error => e
|
47
|
+
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
48
|
+
exit 1
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
36
52
|
private
|
37
53
|
|
38
54
|
def config
|
@@ -42,13 +58,6 @@ module Bard
|
|
42
58
|
def project_name
|
43
59
|
@project_name ||= File.expand_path(".").split("/").last
|
44
60
|
end
|
45
|
-
|
46
|
-
def run!(...)
|
47
|
-
Bard::Command.run!(...)
|
48
|
-
rescue Bard::Command::Error => e
|
49
|
-
puts red("!!! ") + "Running command failed: #{yellow(e.message)}"
|
50
|
-
exit 1
|
51
|
-
end
|
52
61
|
end
|
53
62
|
end
|
54
63
|
|
data/lib/bard/config.rb
CHANGED
data/lib/bard/github.rb
CHANGED
@@ -19,6 +19,14 @@ module Bard
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
+
def delete path, params={}
|
23
|
+
request(path) do |uri|
|
24
|
+
Net::HTTP::Delete.new(uri).tap do |r|
|
25
|
+
r.body = JSON.dump(params)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
22
30
|
def read_file path, branch: "master"
|
23
31
|
metadata = get("contents/#{path}", ref: branch)
|
24
32
|
Base64.decode64(metadata["content"])
|
@@ -28,6 +36,17 @@ module Bard
|
|
28
36
|
post("keys", title:, key:)
|
29
37
|
end
|
30
38
|
|
39
|
+
def create_repo
|
40
|
+
post("https://api.github.com/orgs/botandrosedesign/repos", {
|
41
|
+
name: project_name,
|
42
|
+
private: true,
|
43
|
+
})
|
44
|
+
end
|
45
|
+
|
46
|
+
def delete_repo
|
47
|
+
delete("https://api.github.com/repos/botandrosedesign/#{project_name}")
|
48
|
+
end
|
49
|
+
|
31
50
|
private
|
32
51
|
|
33
52
|
def github_apikey
|
@@ -63,7 +82,7 @@ module Bard
|
|
63
82
|
response.body
|
64
83
|
end
|
65
84
|
else
|
66
|
-
raise [req.method, req.uri, req.to_hash, response].inspect
|
85
|
+
raise [req.method, req.uri, req.to_hash, response, response.body].inspect
|
67
86
|
end
|
68
87
|
end
|
69
88
|
end
|
@@ -0,0 +1,112 @@
|
|
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
|
+
|
13
|
+
puts "Starting deployment to GitHub Pages..."
|
14
|
+
|
15
|
+
build_site
|
16
|
+
tree_sha = create_tree_from_build
|
17
|
+
new_commit = create_commit(tree_sha)
|
18
|
+
commit_and_push new_commit
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def build_site
|
24
|
+
FileUtils.rm_rf "tmp/github-build-".sub(@sha, "*")
|
25
|
+
run! <<~BASH
|
26
|
+
bundle exec rake assets:clean assets:precompile
|
27
|
+
RAILS_ENV=production bundle exec rails s -p 3000 -d --pid tmp/pids/server.pid
|
28
|
+
|
29
|
+
# Create the output directory and enter it
|
30
|
+
BUILD=#{@build_dir}
|
31
|
+
rm -rf $BUILD
|
32
|
+
mkdir -p $BUILD
|
33
|
+
cp -R public/assets $BUILD/
|
34
|
+
cd $BUILD
|
35
|
+
|
36
|
+
# wait until server responds
|
37
|
+
curl --retry 5 --retry-delay 2 -s -o /dev/null "http://0.0.0.0:3000"
|
38
|
+
|
39
|
+
# Mirror the site to the build folder, ignoring links with query params
|
40
|
+
wget --reject-regex "(.*)\\?(.*)" -FEmnH http://0.0.0.0:3000/
|
41
|
+
echo #{@domain} > CNAME
|
42
|
+
|
43
|
+
# Kill the server
|
44
|
+
cd -
|
45
|
+
cat tmp/pids/server.pid | xargs -I {} kill {}
|
46
|
+
|
47
|
+
# Clean up the assets
|
48
|
+
rm -rf public/assets
|
49
|
+
BASH
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_tree_from_build
|
53
|
+
# Create temporary index
|
54
|
+
git_index_file = ".git/tmp-index"
|
55
|
+
git = "GIT_INDEX_FILE=#{git_index_file} git"
|
56
|
+
run! "#{git} read-tree --empty"
|
57
|
+
|
58
|
+
# Add build files to temporary index
|
59
|
+
Dir.chdir(@build_dir) do
|
60
|
+
Dir.glob('**/*', File::FNM_DOTMATCH).each do |file|
|
61
|
+
next if file == '.' || file == '..'
|
62
|
+
if File.file?(file)
|
63
|
+
run! "#{git} update-index --add --cacheinfo 100644 $(#{git} hash-object -w #{file}) #{file}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Create tree object from index
|
69
|
+
tree_sha = `#{git} write-tree`.chomp
|
70
|
+
|
71
|
+
# Clean up temporary index
|
72
|
+
FileUtils.rm_f(git_index_file)
|
73
|
+
|
74
|
+
tree_sha
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_commit tree_sha
|
78
|
+
# Get parent commit if branch exists
|
79
|
+
parent = get_parent_commit
|
80
|
+
|
81
|
+
# Create commit object
|
82
|
+
message = "'Deploying to #{@branch} from @ #{@sha} 🚀'"
|
83
|
+
args = ['commit-tree', tree_sha]
|
84
|
+
args += ['-p', parent] if parent
|
85
|
+
args += ['-m', message]
|
86
|
+
|
87
|
+
commit_sha = `git #{args.join(' ')}`.chomp
|
88
|
+
|
89
|
+
commit_sha
|
90
|
+
end
|
91
|
+
|
92
|
+
def get_parent_commit
|
93
|
+
sha = Git.sha_of("#{@branch}^{commit}")
|
94
|
+
return sha if $?.success?
|
95
|
+
nil # Branch doesn't exist yet
|
96
|
+
end
|
97
|
+
|
98
|
+
def commit_and_push commit_sha
|
99
|
+
if branch_exists?
|
100
|
+
run! "git update-ref refs/heads/#{@branch} #{commit_sha}"
|
101
|
+
else
|
102
|
+
run! "git branch #{@branch} #{commit_sha}"
|
103
|
+
end
|
104
|
+
run! "git push -f origin #{@branch}:refs/heads/#{@branch}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def branch_exists?
|
108
|
+
system("git show-ref --verify --quiet refs/heads/#{@branch}")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
data/lib/bard/server.rb
CHANGED
@@ -3,7 +3,7 @@ require "bard/command"
|
|
3
3
|
require "bard/copy"
|
4
4
|
|
5
5
|
module Bard
|
6
|
-
class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env)
|
6
|
+
class Server < Struct.new(:project_name, :key, :ssh, :path, :ping, :gateway, :ssh_key, :env, :github_pages)
|
7
7
|
def self.define project_name, key, &block
|
8
8
|
new(project_name, key).tap do |server|
|
9
9
|
server.instance_eval &block
|
@@ -24,7 +24,7 @@ module Bard
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
setting :ssh, :path, :ping, :gateway, :ssh_key, :env
|
27
|
+
setting :ssh, :path, :ping, :gateway, :ssh_key, :env, :github_pages
|
28
28
|
|
29
29
|
def ping(*args)
|
30
30
|
if args.length == 0
|
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.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micah Geisel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
11
|
+
date: 2024-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -139,11 +139,14 @@ files:
|
|
139
139
|
- lib/bard/ci/local.rb
|
140
140
|
- lib/bard/cli.rb
|
141
141
|
- lib/bard/cli/ci.rb
|
142
|
+
- lib/bard/cli/command.rb
|
142
143
|
- lib/bard/cli/data.rb
|
143
144
|
- lib/bard/cli/deploy.rb
|
144
145
|
- lib/bard/cli/hurt.rb
|
145
146
|
- lib/bard/cli/install.rb
|
146
147
|
- lib/bard/cli/master_key.rb
|
148
|
+
- lib/bard/cli/new.rb
|
149
|
+
- lib/bard/cli/new_rails_template.rb
|
147
150
|
- lib/bard/cli/open.rb
|
148
151
|
- lib/bard/cli/ping.rb
|
149
152
|
- lib/bard/cli/provision.rb
|
@@ -157,6 +160,7 @@ files:
|
|
157
160
|
- lib/bard/copy.rb
|
158
161
|
- lib/bard/git.rb
|
159
162
|
- lib/bard/github.rb
|
163
|
+
- lib/bard/github_pages.rb
|
160
164
|
- lib/bard/ping.rb
|
161
165
|
- lib/bard/provision.rb
|
162
166
|
- lib/bard/provision/app.rb
|