envirobly 0.5.2 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7cbc25ee0033c84e86fd94e67a3be65ee43c8fbcfd86cd962ecf9e5f616bf042
4
- data.tar.gz: e07002a42e3490bd841f6538ab7cd565990bf55e159fe8d7ce033cff62f6c38d
3
+ metadata.gz: a2750aa4a83c0407fbba1c7db3aa5b7cebaa6ea08fd2112064a4c6c5d88aad4c
4
+ data.tar.gz: 464b4a65da73a81d6a62c1f2fa35f4dd927bd790e16cc3f0f58e3d1048e0d87c
5
5
  SHA512:
6
- metadata.gz: eb490ba6309b3775f548522596c6a5d42504ba2ca878ef8c74b530af12733b9a9ac1ce016ece2afdb7d6c616f4121ca418a49ef3037e06790a9e3da3b916ba93
7
- data.tar.gz: 7abc4689844be2617b74bb425c0ba8136b793d5c0c36600d58defdeadf8a84e9b31715442467c1e912b8988ee1c708c61eedb0192a2af3eadf9fc0b54bf0a327
6
+ metadata.gz: '09321732787c09ee02ca9c4071fb916930db737f07dee8a2cd0ffe482620f3f61586a01d796df4a8452b5c7e2b4f6186e8f9ad7ad9feb633f2f5135c5ce7aefb'
7
+ data.tar.gz: 44513ce52f34fef1310f54095589dec1ab05a0233c1a16f77309ebc9c3cbce2cacf1dea70b01a63fafeab26ae7005de6b9ecb46e8d6b25aa6d938d8e939bcc81
@@ -4,6 +4,25 @@ class Envirobly::Cli::Main < Envirobly::Base
4
4
  puts Envirobly::VERSION
5
5
  end
6
6
 
7
+ desc "validate", "Validates config"
8
+ def validate
9
+ commit = Envirobly::Git::Unstaged.new
10
+ config = Envirobly::Config.new(commit)
11
+ config.validate
12
+
13
+ if config.errors.any?
14
+ puts "Issues found validating `#{Envirobly::Config::PATH}`:"
15
+ puts
16
+ config.errors.each_with_index do |error, index|
17
+ puts " #{index + 1}. #{error}"
18
+ end
19
+ puts
20
+ exit 1
21
+ else
22
+ puts "All checks pass."
23
+ end
24
+ end
25
+
7
26
  desc "deploy ENVIRONMENT", "Deploy to environment identified by name or URL"
8
27
  method_option :commit, type: :string, default: "HEAD"
9
28
  method_option :dry_run, type: :boolean, default: false
@@ -15,7 +34,9 @@ class Envirobly::Cli::Main < Envirobly::Base
15
34
  desc "set_access_token TOKEN", "Save and use an access token generated at Envirobly"
16
35
  def set_access_token
17
36
  token = ask("Access Token:", echo: false).strip
18
- if token == ""
37
+
38
+ if token.blank?
39
+ $stderr.puts
19
40
  $stderr.puts "Token can't be empty."
20
41
  exit 1
21
42
  end
@@ -11,9 +11,10 @@ class Envirobly::Config
11
11
  def initialize(commit)
12
12
  @commit = commit
13
13
  @errors = []
14
- @result = nil
14
+ @result = {}
15
15
  @project_url = nil
16
16
  @raw = @commit.file_content PATH
17
+ @project = parse
17
18
  end
18
19
 
19
20
  def dig(*args)
@@ -22,14 +23,21 @@ class Envirobly::Config
22
23
  nil
23
24
  end
24
25
 
26
+ def validate
27
+ return unless @project
28
+ validate_top_level_keys
29
+ validate_services @project.fetch(:services)
30
+ validate_environments
31
+ end
32
+
25
33
  def compile(environment = nil)
34
+ return unless @project
26
35
  @environment = environment
27
- return unless @project = parse
36
+ @result = @project.slice(:services)
28
37
  set_project_url
29
38
  merge_environment_overrides! unless @environment.nil?
30
39
  transform_env_var_values!
31
40
  append_image_tags!
32
- @result = @project.slice(:services)
33
41
  end
34
42
 
35
43
  def to_deployment_params
@@ -58,16 +66,13 @@ class Envirobly::Config
58
66
 
59
67
  def set_project_url
60
68
  @project_url = dig :project
61
- if @project_url.blank?
62
- @errors << "Missing `project: <url>` top level attribute."
63
- end
64
69
  end
65
70
 
66
71
  def transform_env_var_values!
67
- @project.fetch(:services, {}).each do |name, service|
72
+ @result[:services].each do |name, service|
68
73
  service.fetch(:env, {}).each do |key, value|
69
74
  if value.is_a?(Hash) && value.has_key?(:file)
70
- @project[:services][name][:env][key] = @commit.file_content(value.fetch(:file)).strip
75
+ @result[:services][name][:env][key] = @commit.file_content(value.fetch(:file)).strip
71
76
  end
72
77
  end
73
78
  end
@@ -79,21 +84,19 @@ class Envirobly::Config
79
84
  build_context: [ ".", :dir_exists? ]
80
85
  }
81
86
  def append_image_tags!
82
- @project.fetch(:services, {}).each do |name, service|
87
+ @result[:services].each do |name, service|
83
88
  next if NON_BUILDABLE_TYPES.include?(service[:type]) || service[:image].present?
84
89
  checksums = []
85
90
 
86
91
  BUILD_DEFAULTS.each do |attribute, options|
87
92
  value = service.fetch(attribute, options.first)
88
- unless @commit.public_send(options.second, value)
89
- @errors << "Service `#{name}` specifies `#{attribute}` as `#{value}` which doesn't exist in this commit."
90
- else
93
+ if @commit.public_send(options.second, value)
91
94
  checksums << @commit.objects_with_checksum_at(value)
92
95
  end
93
96
  end
94
97
 
95
98
  if checksums.size == 2
96
- @project[:services][name][:image_tag] = Digest::SHA1.hexdigest checksums.to_json
99
+ @result[:services][name][:image_tag] = Digest::SHA1.hexdigest checksums.to_json
97
100
  end
98
101
  end
99
102
  end
@@ -102,13 +105,103 @@ class Envirobly::Config
102
105
  return unless services = @project.dig(:environments, @environment.to_sym)
103
106
  services.each do |name, service|
104
107
  service.each do |attribute, value|
105
- if value.is_a?(Hash) && @project[:services][name][attribute].is_a?(Hash)
106
- @project[:services][name][attribute].merge! value
107
- @project[:services][name][attribute].compact!
108
+ if value.is_a?(Hash) && @result[:services][name][attribute].is_a?(Hash)
109
+ @result[:services][name][attribute].merge! value
110
+ @result[:services][name][attribute].compact!
108
111
  else
109
- @project[:services][name][attribute] = value
112
+ @result[:services][name][attribute] = value
110
113
  end
111
114
  end
112
115
  end
113
116
  end
117
+
118
+ VALID_TOP_LEVEL_KEYS = %i[ project services environments ]
119
+ def validate_top_level_keys
120
+ unless @project.is_a?(Hash)
121
+ @errors << "Config doesn't contain a top level hash structure."
122
+ return
123
+ end
124
+
125
+ @errors << "Missing `project: <url>` top level attribute." if @project[:project].blank?
126
+
127
+ @project.keys.each do |key|
128
+ unless VALID_TOP_LEVEL_KEYS.include?(key)
129
+ @errors << "Top level key `#{key}` is not allowed. Allowed keys: #{VALID_TOP_LEVEL_KEYS.map{ "`#{_1}`" }.join(", ")}."
130
+ end
131
+ end
132
+ end
133
+
134
+ VALID_SERVICE_KEYS = %i[
135
+ type
136
+ image
137
+ engine_version
138
+ instance_type
139
+ volume_size
140
+ volume_mount
141
+ dockerfile
142
+ build_context
143
+ command
144
+ env
145
+ health_check
146
+ private
147
+ aliases
148
+ ]
149
+ NAME_FORMAT = /\A[a-z0-9\-_]+\z/
150
+ def validate_services(services)
151
+ unless services.is_a?(Hash)
152
+ @errors << "`services` key must be a hash."
153
+ return
154
+ end
155
+
156
+ services.each do |name, service|
157
+ unless name =~ NAME_FORMAT
158
+ @errors << "`#{name}` is not a valid service name. Allowed characters: a-z, 0-9, -, _"
159
+ end
160
+
161
+ unless service.is_a?(Hash)
162
+ @errors << "Service `#{name}` must be a hash."
163
+ next
164
+ end
165
+
166
+ service.each do |attribute, value|
167
+ unless VALID_SERVICE_KEYS.include?(attribute)
168
+ @errors << "Service `#{name}` attribute `#{attribute}` is not a valid attribute."
169
+ end
170
+ end
171
+
172
+ BUILD_DEFAULTS.each do |attribute, options|
173
+ value = service.fetch(attribute, options.first)
174
+ unless @commit.public_send(options.second, value)
175
+ @errors << "Service `#{name}` specifies `#{attribute}` as `#{value}` which doesn't exist in this commit."
176
+ end
177
+ end
178
+
179
+ service.fetch(:env, {}).each do |key, value|
180
+ if value.is_a?(Hash) && value.has_key?(:file)
181
+ unless @commit.file_exists?(value.fetch(:file))
182
+ @errors << "Environment variable `#{key}` referring to a file `#{value.fetch(:file)}` doesn't exist in this commit."
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
188
+
189
+ def validate_environments
190
+ return unless @project.has_key?(:environments)
191
+
192
+ environments = @project.fetch :environments, nil
193
+
194
+ unless environments.is_a?(Hash)
195
+ @errors << "`environments` key must be a hash."
196
+ return
197
+ end
198
+
199
+ environments.each do |environment, services|
200
+ unless environment =~ NAME_FORMAT
201
+ @errors << "`#{environment}` is not a valid environment name. Allowed characters: a-z, 0-9, -, _"
202
+ end
203
+
204
+ validate_services services
205
+ end
206
+ end
114
207
  end
@@ -8,7 +8,7 @@ class Envirobly::Deployment
8
8
  end
9
9
 
10
10
  config = Envirobly::Config.new(commit)
11
- config.compile(environment)
11
+ config.validate
12
12
 
13
13
  if config.errors.any?
14
14
  $stderr.puts "Errors found while parsing #{Envirobly::Config::PATH}:"
@@ -21,6 +21,7 @@ class Envirobly::Deployment
21
21
  exit 1
22
22
  end
23
23
 
24
+ config.compile(environment)
24
25
  params = config.to_deployment_params
25
26
 
26
27
  puts "Deployment config:"
@@ -0,0 +1,17 @@
1
+ class Envirobly::Git::Unstaged < Envirobly::Git::Commit
2
+ def initialize(working_dir: Dir.getwd)
3
+ @working_dir = working_dir
4
+ end
5
+
6
+ def file_exists?(path)
7
+ File.exist? path
8
+ end
9
+
10
+ def dir_exists?(path)
11
+ Dir.exist? path
12
+ end
13
+
14
+ def file_content(path)
15
+ File.read path
16
+ end
17
+ end
@@ -1,3 +1,3 @@
1
1
  module Envirobly
2
- VERSION = "0.5.2"
2
+ VERSION = "0.6.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: envirobly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Starsi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-20 00:00:00.000000000 Z
11
+ date: 2024-09-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -130,6 +130,7 @@ files:
130
130
  - lib/envirobly/deployment.rb
131
131
  - lib/envirobly/git.rb
132
132
  - lib/envirobly/git/commit.rb
133
+ - lib/envirobly/git/unstaged.rb
133
134
  - lib/envirobly/version.rb
134
135
  homepage: https://github.com/envirobly/envirobly-cli
135
136
  licenses: