afterlife 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +46 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +16 -0
- data/README.md +30 -0
- data/Rakefile +17 -0
- data/afterlife.gemspec +37 -0
- data/config.ru +25 -0
- data/exe/afterlife +8 -0
- data/lib/afterlife/base_cli.rb +39 -0
- data/lib/afterlife/bump/semver.rb +60 -0
- data/lib/afterlife/bump.rb +6 -0
- data/lib/afterlife/cdn/cli.rb +59 -0
- data/lib/afterlife/cdn/server.rb +46 -0
- data/lib/afterlife/cdn.rb +31 -0
- data/lib/afterlife/cli.rb +117 -0
- data/lib/afterlife/config.rb +29 -0
- data/lib/afterlife/deploy/cdn_deployment.rb +53 -0
- data/lib/afterlife/deploy/deployment.rb +28 -0
- data/lib/afterlife/deploy.rb +44 -0
- data/lib/afterlife/environment.rb +65 -0
- data/lib/afterlife/exec.rb +43 -0
- data/lib/afterlife/release/change_version.rb +50 -0
- data/lib/afterlife/release/cli.rb +44 -0
- data/lib/afterlife/release/create_helper.rb +79 -0
- data/lib/afterlife/release/helper.rb +26 -0
- data/lib/afterlife/release/pre_helper.rb +55 -0
- data/lib/afterlife/release.rb +6 -0
- data/lib/afterlife/repo.rb +158 -0
- data/lib/afterlife/stage.rb +11 -0
- data/lib/afterlife/version.rb +5 -0
- data/lib/afterlife.rb +56 -0
- data/logs/.keep +0 -0
- data/yarn.lock +260 -0
- metadata +167 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c8dfb530dade840c8e03042de3ba5508eec1002830c0b978ab42aa1f88b83fab
|
4
|
+
data.tar.gz: 39452459ace3d25eb5270e0e83295e0919f97b11813128b98a6deb39b407431b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 30fb609ce63cd5038050a2afae03741fd9d8739d4d014cfbd85ca09a0c1f44a9eb3521b85866b64763bfeea287891ea6d00c84491bf39f4bbf6cea152b8ef8d5
|
7
|
+
data.tar.gz: e94831df012dfe22f833e277b0fbc5b6c11ae5c9c85d9897068d14b05171c4ab7fd542b2f578d0c95fd17feef9419e0c7abb8aeb50421b29e9e93322bd17fa47
|
data/.rspec
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-rspec
|
3
|
+
- rubocop-rake
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
NewCops: enable
|
7
|
+
TargetRubyVersion: 2.7
|
8
|
+
|
9
|
+
Lint/ConstantDefinitionInBlock:
|
10
|
+
Enabled: false
|
11
|
+
|
12
|
+
Layout/IndentationConsistency:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
Layout/HashAlignment:
|
16
|
+
Enabled: false
|
17
|
+
|
18
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
Style/HashAsLastArrayItem:
|
22
|
+
EnforcedStyle: no_braces
|
23
|
+
|
24
|
+
Style/OptionalBooleanParameter:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Style/Documentation:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Layout/EmptyLinesAroundBlockBody:
|
31
|
+
Enabled: false
|
32
|
+
|
33
|
+
Style/TrailingCommaInArguments:
|
34
|
+
EnforcedStyleForMultiline: consistent_comma
|
35
|
+
|
36
|
+
Style/TrailingCommaInArrayLiteral:
|
37
|
+
EnforcedStyleForMultiline: consistent_comma
|
38
|
+
|
39
|
+
Style/TrailingCommaInHashLiteral:
|
40
|
+
EnforcedStyleForMultiline: consistent_comma
|
41
|
+
|
42
|
+
Layout/AccessModifierIndentation:
|
43
|
+
EnforcedStyle: outdent
|
44
|
+
|
45
|
+
Style/SignalException:
|
46
|
+
EnforcedStyle: semantic
|
data/.ruby-gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
afterlife
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.0.5
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# Afterlife
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/afterlife`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text abovxe, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
1. Execute `bin/install` in the repository root
|
10
|
+
2. Put a `env.yml` on ~/.afterlife/env.yml based on the AWS credentials found on mifiel's bitwarden vault
|
11
|
+
3. Install AWS CLI following the [official guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
Run `afterlife help` for a list of all available commands
|
15
|
+
|
16
|
+
|
17
|
+
## About CDN
|
18
|
+
Logs can be found on `~/.afterlife/logs/cdn.log`
|
19
|
+
|
20
|
+
Running `afterlife cdn start` will run the CDN web server in the background. Running in foreground using `afterlife cdn start --foreground` will display errors and content normally found in logs in console instead.
|
21
|
+
|
22
|
+
## Development
|
23
|
+
|
24
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
25
|
+
|
26
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/afterlife.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
|
6
|
+
RSpec::Core::RakeTask.new(:spec)
|
7
|
+
|
8
|
+
require 'rubocop/rake_task'
|
9
|
+
|
10
|
+
RuboCop::RakeTask.new
|
11
|
+
|
12
|
+
desc 'start a console'
|
13
|
+
task :console do
|
14
|
+
exec 'pry -r afterlife -I ./lib'
|
15
|
+
end
|
16
|
+
|
17
|
+
task default: %i[spec rubocop]
|
data/afterlife.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/afterlife/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'afterlife'
|
7
|
+
spec.version = Afterlife::VERSION
|
8
|
+
spec.authors = ['Genaro Madrid']
|
9
|
+
spec.email = ['genmadrid@gmail.com']
|
10
|
+
|
11
|
+
spec.summary = 'Devops tools for Mifiel'
|
12
|
+
spec.description = 'Afterlife helps you setup your development environment and deploy code easily'
|
13
|
+
spec.required_ruby_version = '>= 2.6'
|
14
|
+
|
15
|
+
spec.metadata['source_code_uri'] = 'https://bitbucket.org/volabit/afterlife'
|
16
|
+
spec.metadata['changelog_uri'] = 'https://bitbucket.org/volabit/afterlife/src/master/CHANGELOG.md'
|
17
|
+
|
18
|
+
# Specify which files should be added to the gem when it is released.
|
19
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
20
|
+
spec.files = Dir.chdir(__dir__) do
|
21
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
22
|
+
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_dependency 'activesupport'
|
30
|
+
spec.add_dependency 'git'
|
31
|
+
spec.add_dependency 'puma'
|
32
|
+
spec.add_dependency 'rackup'
|
33
|
+
spec.add_dependency 'thor'
|
34
|
+
spec.add_dependency 'zeitwerk'
|
35
|
+
|
36
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
37
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'logger'
|
4
|
+
require 'rack/directory'
|
5
|
+
|
6
|
+
logger_file = File.open(Afterlife::Cdn.log_path, 'a')
|
7
|
+
logger_file.sync = true
|
8
|
+
|
9
|
+
class AssetHeaders
|
10
|
+
def initialize(app)
|
11
|
+
@app = app
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(env)
|
15
|
+
response = @app.call(env)
|
16
|
+
response[1]['access-control-allow-origin'] = '*'
|
17
|
+
response
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
use AssetHeaders
|
22
|
+
use Rack::CommonLogger, Logger.new(logger_file)
|
23
|
+
run do |env|
|
24
|
+
Rack::Directory.new(Afterlife::Cdn.local_path).call(env)
|
25
|
+
end
|
data/exe/afterlife
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Afterlife
|
6
|
+
module BaseCli
|
7
|
+
def log_success(message)
|
8
|
+
say set_color(message, :green)
|
9
|
+
say "\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
def log_error(message)
|
13
|
+
say set_color(message, :red)
|
14
|
+
say "\n"
|
15
|
+
end
|
16
|
+
|
17
|
+
def log_info(message)
|
18
|
+
say set_color(message, :cyan)
|
19
|
+
say "\n"
|
20
|
+
end
|
21
|
+
|
22
|
+
def log_interrupted
|
23
|
+
say ''
|
24
|
+
fatal! 'Interrupted'
|
25
|
+
end
|
26
|
+
|
27
|
+
def sure?(msg)
|
28
|
+
say msg
|
29
|
+
return true if yes?('Are you sure? [y/n]')
|
30
|
+
|
31
|
+
fatal! 'Good bye'
|
32
|
+
end
|
33
|
+
|
34
|
+
def fatal!(msg)
|
35
|
+
log_error "ERROR: #{msg}"
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterlife
|
4
|
+
module Bump
|
5
|
+
module Semver
|
6
|
+
module_function
|
7
|
+
|
8
|
+
DEFAULT_PRERELEASE_NAME = 'rc'
|
9
|
+
VERSION_REGEX = /(\d+\.\d+\.\d+(?:-(?:.+))?)/.freeze
|
10
|
+
|
11
|
+
def calculate_next(part, pre = nil) # rubocop:disable Metrics/MethodLength
|
12
|
+
x, y, z = release
|
13
|
+
case part.to_sym
|
14
|
+
when :major
|
15
|
+
"#{x + 1}.0.0"
|
16
|
+
when :minor
|
17
|
+
"#{x}.#{y + 1}.0"
|
18
|
+
when :patch
|
19
|
+
"#{x}.#{y}.#{z + 1}"
|
20
|
+
when :pre
|
21
|
+
name, ver = parse_prerelease(pre)
|
22
|
+
"#{x}.#{y}.#{z}-#{name}.#{ver + 1}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def parse_prerelease(name)
|
27
|
+
curr_name, curr_ver = curr_prerelease
|
28
|
+
|
29
|
+
if name
|
30
|
+
# if the user specifies a name different than the current one, reseting the current version
|
31
|
+
curr_ver = -1 if name != curr_name
|
32
|
+
curr_name = name
|
33
|
+
end
|
34
|
+
|
35
|
+
[curr_name, curr_ver]
|
36
|
+
end
|
37
|
+
|
38
|
+
def release
|
39
|
+
version_chunks[0].split('.').map(&:to_i)
|
40
|
+
end
|
41
|
+
|
42
|
+
def curr_prerelease
|
43
|
+
return [DEFAULT_PRERELEASE_NAME, -1] unless version_chunks[1]
|
44
|
+
|
45
|
+
name, ver = version_chunks[1].split('.')
|
46
|
+
[name, ver.to_i]
|
47
|
+
end
|
48
|
+
|
49
|
+
def version_chunks
|
50
|
+
@version_chunks ||= version.split('-')
|
51
|
+
end
|
52
|
+
|
53
|
+
def version
|
54
|
+
result = %x(git describe --tags `git rev-list --tags --max-count=1`).chomp
|
55
|
+
# remove the first 'v' if exists, all mifiel tags always have it
|
56
|
+
result[0] == 'v' ? result[1..] : result
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module Afterlife
|
6
|
+
module Cdn
|
7
|
+
class Cli < Thor
|
8
|
+
include BaseCli
|
9
|
+
def self.exit_on_failure?
|
10
|
+
true
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'start', 'Start the CDN server'
|
14
|
+
option :port,
|
15
|
+
type: :numeric,
|
16
|
+
aliases: '-p',
|
17
|
+
default: 5000
|
18
|
+
option :foreground,
|
19
|
+
type: :boolean,
|
20
|
+
aliases: '-f'
|
21
|
+
option 'no-link', type: :boolean
|
22
|
+
def start
|
23
|
+
Cdn.link unless options['no-link']
|
24
|
+
say_status 'Starting', "http://localhost:#{options[:port]}"
|
25
|
+
Cdn::Server.start(options.symbolize_keys.slice(:port, :foreground))
|
26
|
+
log_success "The server started at http://localhost:#{options[:port]}"
|
27
|
+
rescue Afterlife::Error => e
|
28
|
+
log_error(e)
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'stop', 'stop the CDN server'
|
32
|
+
def stop
|
33
|
+
say_status 'Stopping', nil
|
34
|
+
Server.kill
|
35
|
+
log_success 'The server stopped'
|
36
|
+
rescue Afterlife::Error => e
|
37
|
+
log_error(e)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc 'restart', 'restart the CDN server'
|
41
|
+
def restart
|
42
|
+
invoke :stop if Server.running?
|
43
|
+
invoke :start
|
44
|
+
end
|
45
|
+
|
46
|
+
desc 'logs', 'tail the logs of the CDN server'
|
47
|
+
def logs
|
48
|
+
exec("tail -f #{Afterlife::Cdn.log_path}")
|
49
|
+
end
|
50
|
+
|
51
|
+
desc 'link', 'create symlinks in .cdn directory. ' \
|
52
|
+
'Usually you dont need to run this script by itself'
|
53
|
+
def link
|
54
|
+
Cdn.link
|
55
|
+
log_success('Repos successfully linked to local CDN path')
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rackup'
|
4
|
+
|
5
|
+
module Afterlife
|
6
|
+
module Cdn
|
7
|
+
class Server
|
8
|
+
attr_reader :instance
|
9
|
+
|
10
|
+
def self.pid_file
|
11
|
+
Afterlife.local_path.join('pids/server.pid')
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.kill
|
15
|
+
fail Afterlife::Error, 'The server is not running' unless running?
|
16
|
+
|
17
|
+
Process.kill('INT', pid_file.read.to_i)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.start(args)
|
21
|
+
fail Afterlife::Error, 'A server is already running' if running?
|
22
|
+
|
23
|
+
new(args).start
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.running?
|
27
|
+
pid_file.exist?
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(args)
|
31
|
+
@instance = Rackup::Server.new(
|
32
|
+
environment: ENV['RACK_ENV'] || 'development',
|
33
|
+
quiet: true, # we setup log in config.ru
|
34
|
+
Port: args[:port],
|
35
|
+
config: Afterlife.root.join('config.ru').to_s,
|
36
|
+
pid: Server.pid_file.to_s,
|
37
|
+
daemonize: !args[:foreground],
|
38
|
+
)
|
39
|
+
end
|
40
|
+
|
41
|
+
def start
|
42
|
+
instance.start
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterlife
|
4
|
+
module Cdn
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def url(repo = nil)
|
8
|
+
return Afterlife.current_stage.cdn_url unless repo
|
9
|
+
|
10
|
+
"#{url}/#{repo.full_name}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def log_path
|
14
|
+
Afterlife.local_path.join('logs/cdn.log')
|
15
|
+
end
|
16
|
+
|
17
|
+
def local_path
|
18
|
+
Afterlife.local_path.join('cdn')
|
19
|
+
end
|
20
|
+
|
21
|
+
def link
|
22
|
+
FileUtils.rm_rf(Afterlife::Cdn.local_path)
|
23
|
+
FileUtils.mkdir_p(Afterlife::Cdn.local_path)
|
24
|
+
Repo.all.each do |repo|
|
25
|
+
dest = Afterlife::Cdn.local_path.join(repo.full_name)
|
26
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
27
|
+
FileUtils.ln_sf(repo.dist_path, dest)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Afterlife
|
6
|
+
class Cli < Thor
|
7
|
+
include BaseCli
|
8
|
+
def self.exit_on_failure?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
package_name 'Afterlife'
|
13
|
+
class_option :quiet, type: :boolean, group: :runtime
|
14
|
+
class_option :verbose, type: :boolean, group: :runtime
|
15
|
+
|
16
|
+
desc 'init', 'Init afterlife'
|
17
|
+
def init
|
18
|
+
FileUtils.mkdir_p(Afterlife.local_path.join('logs'))
|
19
|
+
FileUtils.mkdir_p(Afterlife.local_path.join('pids'))
|
20
|
+
FileUtils.mkdir_p(Afterlife::Cdn.local_path)
|
21
|
+
FileUtils.touch(Afterlife::Config.file)
|
22
|
+
log_success 'afterlife is ready!'
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'config <path>', 'get config options'
|
26
|
+
def config(path) # rubocop:disable Metrics/MethodLength
|
27
|
+
path = path.split('.').map(&:to_sym)
|
28
|
+
result = repo.conf.dig(*path)
|
29
|
+
case result
|
30
|
+
when Hash
|
31
|
+
say JSON.generate(result)
|
32
|
+
when Array
|
33
|
+
result.each do |item|
|
34
|
+
say item
|
35
|
+
end
|
36
|
+
else
|
37
|
+
say result
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'cdn', 'CDN stuff'
|
42
|
+
subcommand 'cdn', Cdn::Cli
|
43
|
+
|
44
|
+
desc 'deploy <stage>', 'Deploy current directory'
|
45
|
+
option 'no-build', type: :boolean
|
46
|
+
option 'no-install', type: :boolean
|
47
|
+
option 'dry-run', type: :boolean
|
48
|
+
option 'skip-after-hooks', type: :boolean
|
49
|
+
option :yes, type: :boolean
|
50
|
+
# this only has logic for CDN deployments
|
51
|
+
# TODO: Add logic for different deployment types
|
52
|
+
def deploy(stage) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
53
|
+
Afterlife.cli = self
|
54
|
+
Afterlife.current_stage = Afterlife.config.stages[stage.to_sym]
|
55
|
+
fill_env
|
56
|
+
ask_confirmation(repo.confirmation_message) unless options['yes']
|
57
|
+
install_dependencies unless options['no-install']
|
58
|
+
build unless options['no-build']
|
59
|
+
|
60
|
+
say_status 'Deploying', repo.dist_path
|
61
|
+
output = Deploy.call
|
62
|
+
say_status 'Deployed', output
|
63
|
+
rescue Deploy::Error => e
|
64
|
+
fatal!(e.message)
|
65
|
+
rescue Interrupt
|
66
|
+
log_interrupted
|
67
|
+
end
|
68
|
+
|
69
|
+
desc 'release', 'Releases management'
|
70
|
+
subcommand 'release', Release::Cli
|
71
|
+
|
72
|
+
map %w[-v --version] => :version
|
73
|
+
desc 'version', 'Prints afterlife version'
|
74
|
+
def version
|
75
|
+
say Afterlife::VERSION
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def fill_env
|
81
|
+
repo.env.merge!(
|
82
|
+
'DIST_PATH' => repo.dist_path.to_s,
|
83
|
+
'CURRENT_BRANCH' => repo.current_branch,
|
84
|
+
'AFTERLIFE_STAGE' => Afterlife.current_stage.name,
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def install_dependencies
|
89
|
+
return unless repo.install_dependencies_command
|
90
|
+
|
91
|
+
say_status 'Installing', '*' * 20
|
92
|
+
Exec.run(repo.install_dependencies_command)
|
93
|
+
end
|
94
|
+
|
95
|
+
def build
|
96
|
+
return unless repo.build_command
|
97
|
+
|
98
|
+
say_status 'Building', '*' * 20
|
99
|
+
Exec.run(repo.build_command)
|
100
|
+
end
|
101
|
+
|
102
|
+
def ask_confirmation(message)
|
103
|
+
if message
|
104
|
+
say message
|
105
|
+
else
|
106
|
+
say set_color("You're about to deploy the contents of '#{repo.dist_path}' to")
|
107
|
+
say set_color(Cdn.url(repo), :bold)
|
108
|
+
say set_color("\nWARNING: Please be aware that this may be a destructive operation", :yellow)
|
109
|
+
end
|
110
|
+
exit 1 unless yes?('Are you sure? [y/n]')
|
111
|
+
end
|
112
|
+
|
113
|
+
def repo
|
114
|
+
Afterlife.current_repo
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterlife
|
4
|
+
class Config
|
5
|
+
def self.file
|
6
|
+
Afterlife.local_path.join('config.yml')
|
7
|
+
end
|
8
|
+
|
9
|
+
def respond_to_missing?(sym, include_all)
|
10
|
+
config.key?(sym) || super
|
11
|
+
end
|
12
|
+
|
13
|
+
def method_missing(sym, *args, &block)
|
14
|
+
config.key?(sym) ? config[sym] : super
|
15
|
+
end
|
16
|
+
|
17
|
+
def stages
|
18
|
+
@stages ||= config.delete(:stages)&.to_h do |name, val|
|
19
|
+
[name, Stage.new(val.merge(name: name.to_s))]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def config
|
26
|
+
@config ||= YAML.load_file(Config.file).deep_symbolize_keys
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterlife
|
4
|
+
class Deploy
|
5
|
+
class CdnDeployment < Deployment
|
6
|
+
def run
|
7
|
+
Exec.run(commands)
|
8
|
+
Cdn.url(repo)
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
repo.env.merge!(
|
13
|
+
'AWS_PROFILE' => Afterlife.config.credentials.dig(:aws, :profile),
|
14
|
+
'AWS_BUCKET' => Afterlife.current_stage.bucket,
|
15
|
+
'AWS_REGION' => Afterlife.current_stage.region,
|
16
|
+
'S3_FULL_PATH' => s3_full_path,
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def commands
|
23
|
+
[
|
24
|
+
repo_command || javascripts,
|
25
|
+
revision,
|
26
|
+
].flatten
|
27
|
+
end
|
28
|
+
|
29
|
+
def javascripts
|
30
|
+
# by default we use no-cache, if something else is needed
|
31
|
+
# do it in the deploy.command option
|
32
|
+
<<-BASH
|
33
|
+
aws s3 sync
|
34
|
+
%<DIST_PATH>s
|
35
|
+
%<S3_FULL_PATH>s
|
36
|
+
--exclude '*.ts'
|
37
|
+
--exclude '*.tsx'
|
38
|
+
--cache-control 'no-cache'
|
39
|
+
BASH
|
40
|
+
end
|
41
|
+
|
42
|
+
def revision
|
43
|
+
<<-BASH
|
44
|
+
echo "#{repo.current_revision}" | aws s3 cp --content-type text/plain - %<S3_FULL_PATH>s/revision
|
45
|
+
BASH
|
46
|
+
end
|
47
|
+
|
48
|
+
def s3_full_path
|
49
|
+
"s3://#{Afterlife.current_stage.bucket}/#{repo.full_name}"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Afterlife
|
4
|
+
class Deploy
|
5
|
+
class Deployment
|
6
|
+
def self.run
|
7
|
+
deployment = new.tap(&:setup)
|
8
|
+
deployment.run
|
9
|
+
end
|
10
|
+
|
11
|
+
def run
|
12
|
+
fail NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
def repo_command
|
16
|
+
Array(repo.conf.dig(:deploy, :command))
|
17
|
+
end
|
18
|
+
|
19
|
+
def setup; end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def repo
|
24
|
+
Afterlife.current_repo
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|