afterlife 1.4.0 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 50bb80b8a5c213397eb84b52d78f39fc6ff72491a45df415e0c7700d1c2eb4bc
4
- data.tar.gz: d6a8963da3e0d48f511e182d4bcf5c49f20e4e7449e29e9d8cc1f35c2a43fcc8
3
+ metadata.gz: 92e4638508e3ce213a3fa2153f379d4ec46f4853f2e3e5e51de581ce67895c2a
4
+ data.tar.gz: 8f390b018a8317bbd7c34be245e7515ed86da8305b1c8277ef8845def65e5b87
5
5
  SHA512:
6
- metadata.gz: '0594d2bce7f949b133c67536d8a3115b2bcdc3a12dc6826135335d6aa5d1cd5e0bd938088a5437bb0381aef2b509b06f990c5268b5a21e8d667882b1355ed274'
7
- data.tar.gz: 8b40060493294350391a2aec32c866cadd04a7aaf087ada970fb267430e836c3f724b4dc1ef683beb3337e59cd8b3a77f420afd168830d6972b7c8ee301e8fb8
6
+ metadata.gz: 4393072985a2d8ed6d91cd33dc46ccb2c9ab14474f42aaedc7925e4623ff690a465059799b7dcbf1e59111350e0b7c5368520b68fd0b5909d155ea49e907dabb
7
+ data.tar.gz: 1331c720e2f79068e2ea72734b92336f9cf6468e24f64d94c8bbfcd5511b40f556d7c0dacda9f4562a6221542caafaf4e62297fcabf9511a9971e43eefc224f8
data/lib/afterlife/cli.rb CHANGED
@@ -32,6 +32,7 @@ module Afterlife
32
32
  option 'no-build', type: :boolean
33
33
  option 'no-install', type: :boolean
34
34
  option 'no-auth', type: :boolean
35
+ option 'no-apply', type: :boolean
35
36
  option 'dry-run', type: :boolean
36
37
  option 'skip-after-hooks', type: :boolean
37
38
  option :yes, type: :boolean
@@ -23,6 +23,10 @@ module Afterlife
23
23
  end
24
24
  end
25
25
 
26
+ def deploy_notification_url
27
+ config[:deploy_notification_url]
28
+ end
29
+
26
30
  private
27
31
 
28
32
  def config
@@ -20,6 +20,7 @@ module Afterlife
20
20
  --exclude '*.ts'
21
21
  --exclude '*.tsx'
22
22
  --exclude '*.esm.js'
23
+ --exclude '*.map'
23
24
  --size-only
24
25
  --cache-control 'public, max-age=31540000'
25
26
  BASH
@@ -13,10 +13,8 @@ module Afterlife
13
13
  Afterlife.cli = self
14
14
  Deploy.call(stage, options) do |deployment|
15
15
  setup_deploy(deployment)
16
- say_status 'Deploying', deployment.initial_message
17
- deployment.run
18
- say_status 'Deployed', deployment.output
19
- run_after_hooks
16
+ process_deploy(deployment)
17
+ Notify.call(Afterlife.current_repo.name, Afterlife.current_stage.name)
20
18
  end
21
19
  rescue Afterlife::Error => e
22
20
  fatal!(e.message)
@@ -24,6 +22,13 @@ module Afterlife
24
22
 
25
23
  private
26
24
 
25
+ def process_deploy(deployment)
26
+ say_status 'Deploying', deployment.initial_message
27
+ deployment.run
28
+ say_status 'Deployed', deployment.output
29
+ run_after_hooks
30
+ end
31
+
27
32
  def run_after_hooks
28
33
  return if options['skip-after-hooks']
29
34
 
@@ -3,7 +3,6 @@
3
3
  module Afterlife
4
4
  module Deploy
5
5
  class Deployment
6
-
7
6
  attr_reader :options
8
7
 
9
8
  def initialize(options)
@@ -27,7 +27,6 @@ module Afterlife
27
27
  authenticate_command,
28
28
  build_command,
29
29
  set_image_command,
30
- local_stage? ? delete_kubernetes_resource : nil,
31
30
  apply_kubernetes_settings,
32
31
  ].flatten.compact
33
32
  end
@@ -35,40 +34,47 @@ module Afterlife
35
34
  # commands
36
35
 
37
36
  def authenticate_command
38
- return if options['no-auth']
37
+ return if options['no-auth'] || local_stage?
39
38
 
40
- <<-BASH
41
- echo "#{aws_ecr_token}" | docker login --username AWS --password-stdin #{registry} &&
42
- kubectl delete secret regcred &&
43
- kubectl create secret docker-registry regcred
44
- --docker-server=#{registry}
45
- --docker-username=AWS
46
- --docker-password=#{aws_ecr_token}
47
- --docker-email=devs@mifiel.com
48
- BASH
39
+ AwsAuth.new(registry).commands
49
40
  end
50
41
 
51
42
  def build_command
52
43
  return if options['no-build']
53
44
 
54
45
  <<-BASH
55
- docker buildx bake -f docker-bake.hcl #{local_stage? ? '--load' : '--push'}
46
+ docker buildx bake -f docker-bake.hcl #{targets.join(' ')} #{local_stage? ? '--load' : '--push'}
56
47
  BASH
57
48
  end
58
49
 
59
50
  def set_image_command
60
51
  <<-BASH
61
- $(cd #{kubelocation} && kustomize edit set image #{image_name}:latest=#{full_image_name})
52
+ cd #{kubelocation} &&
53
+ #{
54
+ targets.map do |target|
55
+ "kustomize edit set image #{full_image_name(target)}:latest=#{registry_image_name(target)}"
56
+ end.join(' && ')
57
+ }
62
58
  BASH
63
59
  end
64
60
 
65
- def delete_kubernetes_resource
66
- <<-BASH
67
- kubectl delete -k #{kubelocation}
68
- BASH
61
+ def targets
62
+ repo.conf.dig(:deploy, :targets) || %w[app]
63
+ end
64
+
65
+ def registry_image_name(target)
66
+ "#{registry}/#{full_image_name(target)}:#{repo.current_revision}"
67
+ end
68
+
69
+ def full_image_name(target)
70
+ return image_name if target == 'app'
71
+
72
+ "#{image_name}-#{target}"
69
73
  end
70
74
 
71
75
  def apply_kubernetes_settings
76
+ return if options['no-apply']
77
+
72
78
  <<-BASH
73
79
  kubectl apply -k #{kubelocation}
74
80
  BASH
@@ -88,12 +94,10 @@ module Afterlife
88
94
  ".afterlife/#{Afterlife.current_stage.name}"
89
95
  end
90
96
 
91
- def full_image_name
92
- "#{registry}/#{image_name}:#{repo.current_revision}"
93
- end
94
-
95
97
  def image_name
96
- @image_name ||= repo.conf.dig(:deploy, :image_name)
98
+ @image_name ||= repo.conf.dig(:deploy, :image_name).tap do |result|
99
+ fail Error, 'deploy.image_name for kubernetes deployments' unless result
100
+ end
97
101
  end
98
102
 
99
103
  # Priority:
@@ -106,10 +110,30 @@ module Afterlife
106
110
  @registry ||= Afterlife.current_repo.variable('deploy.registry') || Afterlife.current_stage.registry
107
111
  end
108
112
 
109
- # command outputs
113
+ class AwsAuth
114
+ attr_reader :registry
115
+
116
+ def initialize(registry)
117
+ @registry = registry
118
+ end
119
+
120
+ def commands
121
+ [docker_login]
122
+ end
123
+
124
+ def docker_login
125
+ <<-BASH
126
+ echo "#{aws_ecr_token}" | docker login --username AWS --password-stdin #{registry}
127
+ BASH
128
+ end
129
+
130
+ def aws_ecr_token
131
+ @aws_ecr_token ||= Exec.result("aws ecr get-login-password --region #{region}")
132
+ end
110
133
 
111
- def aws_ecr_token
112
- @aws_ecr_token ||= `aws ecr get-login-password --region us-west-2`.strip
134
+ def region
135
+ @region ||= registry.gsub(/[^.]+\.dkr\.ecr\.([^.]+)\.amazonaws\.com/, '\1')
136
+ end
113
137
  end
114
138
  end
115
139
  end
@@ -5,7 +5,11 @@ require 'active_support/core_ext/string'
5
5
 
6
6
  module Afterlife
7
7
  class Exec
8
- Error = Class.new StandardError
8
+ def self.result(arg)
9
+ fail Error, 'Exec.result only accepts strings' unless arg.is_a?(String)
10
+
11
+ new(arg).run(result: true).first
12
+ end
9
13
 
10
14
  def self.run(arg)
11
15
  new(arg).run
@@ -23,11 +27,14 @@ module Afterlife
23
27
  @commands = Array(arg)
24
28
  end
25
29
 
26
- def run
27
- parsed_commands.each do |command|
30
+ def run(result: false)
31
+ parsed_commands.map do |command|
28
32
  Afterlife.cli.log_info(command) if Afterlife.cli.options['verbose']
29
- system(env_hash, command.squish, exception: true) unless Afterlife.cli.options['dry-run']
30
- end
33
+ next if Afterlife.cli.options['dry-run']
34
+ next `#{command}`.squish if result
35
+
36
+ system(env_hash, command.squish, exception: true)
37
+ end.compact
31
38
  rescue RuntimeError => e
32
39
  raise Error, e
33
40
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+
5
+ module Afterlife
6
+ module Notify
7
+ module_function
8
+
9
+ def call(repository, branch)
10
+ return if notification_url.empty?
11
+
12
+ response = send_request(repository, branch)
13
+
14
+ return if response.code == '200'
15
+
16
+ fail Error,
17
+ "The deploy notification URL returned a #{response.code} status code, " \
18
+ 'and the notification may not have been sent.'
19
+ end
20
+
21
+ def notification_url
22
+ @notification_url ||= ENV.fetch('AFTERLIFE_DEPLOY_NOTIFICATION_URL', nil) \
23
+ || Afterlife.config.deploy_notification_url \
24
+ || Afterlife.current_repo.conf.dig(:deploy, :deploy_notification_url) \
25
+ || ''
26
+ end
27
+
28
+ def send_request(repository, branch)
29
+ uri = URI(notification_url)
30
+ body = {
31
+ branch: branch,
32
+ repository: repository,
33
+ }
34
+ headers = { 'Content-Type': 'application/json' }
35
+ Net::HTTP.post(uri, body.to_json, headers)
36
+ end
37
+ end
38
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Afterlife
4
- VERSION = '1.4.0'
4
+ VERSION = '1.6.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: afterlife
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genaro Madrid
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-01-19 00:00:00.000000000 Z
11
+ date: 2024-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -133,6 +133,7 @@ files:
133
133
  - lib/afterlife/deploy/kubernetes_deployment.rb
134
134
  - lib/afterlife/environment.rb
135
135
  - lib/afterlife/exec.rb
136
+ - lib/afterlife/notify.rb
136
137
  - lib/afterlife/release.rb
137
138
  - lib/afterlife/release/change_version.rb
138
139
  - lib/afterlife/release/cli.rb