afterlife 1.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 +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
|