cicd-builder 0.9.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +35 -0
- data/ChangeLog.md +4 -0
- data/Gemfile +7 -0
- data/LICENSE +201 -0
- data/LICENSE.txt +203 -0
- data/README.md +4 -0
- data/Rakefile +30 -0
- data/cicd-builder.gemspec +33 -0
- data/features/.gitkeep +0 -0
- data/features/ci-cd-builder.feature +1 -0
- data/features/cicd-builder.feature +1 -0
- data/features/step_definitions/.gitkeep +0 -0
- data/features/step_definitions/ci-cd-builder_steps.rb +1 -0
- data/features/step_definitions/cicd-builder_steps.rb +1 -0
- data/lib/cicd/builder.rb +87 -0
- data/lib/cicd/builder/mixlib/build.rb +160 -0
- data/lib/cicd/builder/mixlib/constants.rb +18 -0
- data/lib/cicd/builder/mixlib/environment.rb +194 -0
- data/lib/cicd/builder/mixlib/errors.rb +12 -0
- data/lib/cicd/builder/mixlib/options.rb +86 -0
- data/lib/cicd/builder/mixlib/repo.rb +428 -0
- data/lib/cicd/builder/mixlib/utils.rb +27 -0
- data/lib/cicd/builder/version.rb +12 -0
- metadata +240 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
module CiCd
|
2
|
+
module Builder
|
3
|
+
|
4
|
+
# ---------------------------------------------------------------------------------------------------------------
|
5
|
+
def parseOptions()
|
6
|
+
# Parse options
|
7
|
+
@options = {
|
8
|
+
log_level: :warn,
|
9
|
+
#dry_run: false,
|
10
|
+
|
11
|
+
gen: '3.0.0',
|
12
|
+
}.merge @default_options
|
13
|
+
|
14
|
+
opt_parser = OptionParser.new do |opts|
|
15
|
+
opts.banner = "Usage: #{MYNAME} [@options]"
|
16
|
+
|
17
|
+
opts.on('-l', '--log_level LEVEL', '--log-level LEVEL', [:trace, :debug, :info, :note, :warn, :error, :fatal, :todo], "Log level ([:trace, :debug, :info, :step, :warn, :error, :fatal, :todo])") do |v|
|
18
|
+
@options[:log_level] = v
|
19
|
+
end
|
20
|
+
opts.on("-f", "--inifile FILE", "INI file with settings") do |v|
|
21
|
+
@options[:inifile] = v
|
22
|
+
end
|
23
|
+
#opts.on("-n", "--[no-]dry-run", "Do a dry run, Default --no-dry-run") do |v|
|
24
|
+
# @options[:dry_run] = v
|
25
|
+
#end
|
26
|
+
end
|
27
|
+
|
28
|
+
opt_parser.parse!
|
29
|
+
|
30
|
+
# Set up logger
|
31
|
+
Logging.init :trace, :debug, :info, :note, :warn, :error, :fatal, :todo
|
32
|
+
@logger = Logging.logger(STDOUT,
|
33
|
+
:pattern => "%#{::Logging::MAX_LEVEL_LENGTH}l: %m\n",
|
34
|
+
:date_pattern => '%Y-%m-%d %H:%M:%S')
|
35
|
+
@logger.level = @options[:log_level]
|
36
|
+
|
37
|
+
if @options.key?(:inifile)
|
38
|
+
@options[:inifile] = File.expand_path(@options[:inifile])
|
39
|
+
unless File.exist?(@options[:inifile])
|
40
|
+
raise StandardError.new("#{@options[:inifile]} not found!")
|
41
|
+
end
|
42
|
+
begin
|
43
|
+
# ENV.each{ |key,_|
|
44
|
+
# ENV.delete(key)
|
45
|
+
# }
|
46
|
+
ini = IniFile.load(@options[:inifile])
|
47
|
+
ini['global'].each{ |key,value|
|
48
|
+
ENV[key]=value
|
49
|
+
}
|
50
|
+
def _expand(k,v,regex,rerun)
|
51
|
+
matches = v.match(regex)
|
52
|
+
if matches
|
53
|
+
var = matches[1]
|
54
|
+
if ENV.has_key?(var)
|
55
|
+
ENV[k]=v.gsub(/\$\{#{var}\}/,ENV[var]).gsub(/\$#{var}/,ENV[var])
|
56
|
+
else
|
57
|
+
rerun[var] = 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
pending = nil
|
63
|
+
rerun = {}
|
64
|
+
begin
|
65
|
+
pending = rerun
|
66
|
+
rerun = {}
|
67
|
+
ENV.to_hash.each{|k,v|
|
68
|
+
if v.match(/\$/)
|
69
|
+
_expand(k,v,%r'[^\\]\$\{(\w+)\}', rerun)
|
70
|
+
_expand(k,v,%r'[^\\]\$(\w+)', rerun)
|
71
|
+
end
|
72
|
+
}
|
73
|
+
# Should break out the first time that we make no progress!
|
74
|
+
end while pending != rerun
|
75
|
+
rescue IniFile::Error => e
|
76
|
+
# noop
|
77
|
+
rescue Exception => e
|
78
|
+
@logger.error "#{e.class.name} #{e.message}"
|
79
|
+
raise e
|
80
|
+
end
|
81
|
+
end
|
82
|
+
@options
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,428 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module CiCd
|
4
|
+
module Builder
|
5
|
+
|
6
|
+
# ---------------------------------------------------------------------------------------------------------------
|
7
|
+
def getS3Bucket()
|
8
|
+
unless @s3
|
9
|
+
@s3 = AWS::S3.new(
|
10
|
+
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
|
11
|
+
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
|
12
|
+
end
|
13
|
+
unless @s3_bucket
|
14
|
+
@s3_bucket = @s3.buckets[ENV['AWS_S3_BUCKET']]
|
15
|
+
end
|
16
|
+
@s3_bucket
|
17
|
+
end
|
18
|
+
|
19
|
+
# ---------------------------------------------------------------------------------------------------------------
|
20
|
+
def uploadToS3(artifacts)
|
21
|
+
bucket = getS3Bucket()
|
22
|
+
artifacts.each{|art|
|
23
|
+
# makes no request, returns an AWS::S3::S3Object
|
24
|
+
s3_obj = bucket.objects[art[:key]]
|
25
|
+
upload = true
|
26
|
+
if art[:data].has_key?(:file)
|
27
|
+
md5 = Digest::MD5.file(art[:data][:file]).hexdigest
|
28
|
+
else
|
29
|
+
#noinspection RubyArgCount
|
30
|
+
md5 = Digest::MD5.hexdigest(art[:data][:data])
|
31
|
+
end
|
32
|
+
if s3_obj.exists?
|
33
|
+
@logger.info "s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]} exists"
|
34
|
+
etag = s3_obj.etag.gsub(/"/,'')
|
35
|
+
unless etag == md5
|
36
|
+
checksum = s3_obj.metadata[:checksum]
|
37
|
+
unless checksum and checksum == md5
|
38
|
+
@logger.warn "s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]} is different from our #{art[:key]}(#{s3_obj.etag} <=> #{md5})"
|
39
|
+
upload = true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if upload
|
45
|
+
@logger.info "Upload new s3://#{ENV['AWS_S3_BUCKET']}/#{art[:key]}"
|
46
|
+
# Get size before upload changes our object
|
47
|
+
if art[:data].has_key?(:file)
|
48
|
+
size = File.size(art[:data][:file])
|
49
|
+
else
|
50
|
+
size = art[:data][:data].length
|
51
|
+
end
|
52
|
+
art[:data][:metadata] = {checksum: md5}
|
53
|
+
s3_obj.write(art[:data])
|
54
|
+
if art.has_key?(:public_url)
|
55
|
+
@vars[art[:public_url]] = s3_obj.public_url
|
56
|
+
end
|
57
|
+
if art.has_key?(:read_url)
|
58
|
+
@vars[art[:read_url]] = s3_obj.url_for(:read) if art.has_key?(:read_url)
|
59
|
+
end
|
60
|
+
@logger.info "#{art[:label]}: #{@vars[art[:public_url]]}" if art.has_key?(:public_url)
|
61
|
+
# if size > 16 * 1024 * 1024
|
62
|
+
# if size < 5 * 1024 * 1024 * 1000
|
63
|
+
# @logger.debug "#{art[:label]}: Multipart etag: #{s3_obj.etag}"
|
64
|
+
# s3_obj.copy_to("#{art[:key]}.copy")
|
65
|
+
# s3_obj = bucket.objects["#{art[:key]}.copy"]
|
66
|
+
# s3_obj.move_to(art[:key])
|
67
|
+
# s3_obj = bucket.objects[art[:key]]
|
68
|
+
# @logger.debug "#{art[:label]}: Revised etag: #{s3_obj.etag}"
|
69
|
+
# else
|
70
|
+
# @logger.warn "#{art[:label]}: Multipart etag: #{s3_obj.etag} on asset > 5Gb"
|
71
|
+
# end
|
72
|
+
# end
|
73
|
+
end
|
74
|
+
}
|
75
|
+
0
|
76
|
+
end
|
77
|
+
|
78
|
+
# ---------------------------------------------------------------------------------------------------------------
|
79
|
+
def getArtifactsDefinition()
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
|
83
|
+
# ---------------------------------------------------------------------------------------------------------------
|
84
|
+
def getNamingDefinition()
|
85
|
+
nil
|
86
|
+
end
|
87
|
+
|
88
|
+
# ---------------------------------------------------------------------------------------------------------------
|
89
|
+
def initInventory()
|
90
|
+
|
91
|
+
hash =
|
92
|
+
{
|
93
|
+
id: "#{@vars[:project_name]}",
|
94
|
+
# In case future generations introduce incompatible features
|
95
|
+
gen: "#{@options[:gen]}",
|
96
|
+
container: {
|
97
|
+
artifacts: %w(assembly metainfo checksum),
|
98
|
+
naming: '<product>-<major>.<minor>.<patch>-<branch>-release-<number>-build-<number>.<extension>',
|
99
|
+
assembly: {
|
100
|
+
extension: 'tar.gz',
|
101
|
+
type: 'targz'
|
102
|
+
},
|
103
|
+
metainfo: {
|
104
|
+
extension: 'MANIFEST.json',
|
105
|
+
type: 'json'
|
106
|
+
},
|
107
|
+
checksum: {
|
108
|
+
extension: 'checksum',
|
109
|
+
type: 'Digest::SHA256'
|
110
|
+
},
|
111
|
+
variants: {
|
112
|
+
:"#{@vars[:variant]}" => {
|
113
|
+
latest: {
|
114
|
+
build: 0,
|
115
|
+
branch: 0,
|
116
|
+
version: 0,
|
117
|
+
release: 0,
|
118
|
+
},
|
119
|
+
versions: [ "#{@vars[:build_ver]}" ],
|
120
|
+
branches: [ "#{@vars[:build_bra]}" ],
|
121
|
+
builds: [
|
122
|
+
{
|
123
|
+
drawer: @vars[:build_nam],
|
124
|
+
build_name: @vars[:build_rel],
|
125
|
+
build_number: @vars[:build_num],
|
126
|
+
release: @vars[:release],
|
127
|
+
}
|
128
|
+
],
|
129
|
+
}
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
artifacts = getArtifactsDefinition()
|
134
|
+
naming = getNamingDefinition()
|
135
|
+
|
136
|
+
# By default we use the internal definition ...
|
137
|
+
if artifacts
|
138
|
+
artifacts.each do |name,artifact|
|
139
|
+
hash[:container][name] = artifact
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
# By default we use the internal definition ...
|
144
|
+
if naming
|
145
|
+
hash[:container][:naming] = naming
|
146
|
+
end
|
147
|
+
JSON.pretty_generate( hash, { indent: "\t", space: ' '})
|
148
|
+
end
|
149
|
+
|
150
|
+
# ---------------------------------------------------------------------------------------------------------------
|
151
|
+
def takeInventory()
|
152
|
+
def _update(hash, key, value)
|
153
|
+
h = {}
|
154
|
+
i = -1
|
155
|
+
hash[key].each { |v| h[v] = i+=1 }
|
156
|
+
unless h.has_key?(value)
|
157
|
+
h[value] = h.keys.size # No -1 because this is evaluated BEFORE we make the addition!
|
158
|
+
end
|
159
|
+
s = h.sort_by { |_, v| v }
|
160
|
+
s = s.map { |v| v[0] }
|
161
|
+
hash[key] = s
|
162
|
+
h[value]
|
163
|
+
end
|
164
|
+
|
165
|
+
# Read and parse in JSON
|
166
|
+
json_s = ''
|
167
|
+
json = nil
|
168
|
+
varianth = nil
|
169
|
+
|
170
|
+
bucket = getS3Bucket()
|
171
|
+
key = "#{@vars[:project_name]}/INVENTORY.json"
|
172
|
+
s3_obj = bucket.objects[key]
|
173
|
+
# If the inventory has started then add to it
|
174
|
+
if s3_obj.exists?
|
175
|
+
s3_obj.read(){|chunk|
|
176
|
+
json_s << chunk
|
177
|
+
}
|
178
|
+
json = Yajl::Parser.parse(json_s)
|
179
|
+
over = false
|
180
|
+
# Is the inventory format up to date ...
|
181
|
+
# TODO: [2014-07-27 Christo] Use semver gem ...
|
182
|
+
require 'chef/exceptions'
|
183
|
+
require 'chef/version_constraint'
|
184
|
+
require 'chef/version_class'
|
185
|
+
|
186
|
+
begin
|
187
|
+
version = Chef::Version.new(json['gen'])
|
188
|
+
rescue Chef::Exceptions::InvalidCookbookVersion => e
|
189
|
+
json['gen'] = "#{json['gen']}.0.0"
|
190
|
+
version = Chef::Version.new(json['gen'])
|
191
|
+
end
|
192
|
+
|
193
|
+
begin
|
194
|
+
our_ver = Chef::Version.new(@options[:gen])
|
195
|
+
constraint = Chef::VersionConstraint.new("<= #{@options[:gen]}")
|
196
|
+
rescue Chef::Exceptions::InvalidVersionConstraint => e
|
197
|
+
raise CiCd::Builder::Errors::InvalidVersionConstraint.new e.message
|
198
|
+
rescue Chef::Exceptions::InvalidCookbookVersion => e
|
199
|
+
raise CiCd::Builder::Errors::InvalidVersion.new e.message
|
200
|
+
end
|
201
|
+
|
202
|
+
unless constraint.include?(version)
|
203
|
+
raise CiCd::Builder::Errors::InvalidVersion.new "The inventory generation is newer than I can manage: #{version} <=> #{our_ver}"
|
204
|
+
end
|
205
|
+
if json['container'] and json['container']['variants']
|
206
|
+
# but does not have our variant then add it
|
207
|
+
variants = json['container']['variants']
|
208
|
+
unless variants[@vars[:variant]]
|
209
|
+
variants[@vars[:variant]] = {}
|
210
|
+
varianth = variants[@vars[:variant]]
|
211
|
+
varianth['builds'] = []
|
212
|
+
varianth['branches'] = []
|
213
|
+
varianth['versions'] = []
|
214
|
+
varianth['releases'] = []
|
215
|
+
varianth['latest'] = {
|
216
|
+
branch: -1,
|
217
|
+
version: -1,
|
218
|
+
build: -1,
|
219
|
+
release: -1,
|
220
|
+
}
|
221
|
+
end
|
222
|
+
varianth = variants[@vars[:variant]]
|
223
|
+
# If the inventory 'latest' format is up to date ...
|
224
|
+
unless varianth['latest'] and
|
225
|
+
varianth['latest'].is_a?(Hash)
|
226
|
+
# Start over ... too old/ incompatible
|
227
|
+
over = true
|
228
|
+
end
|
229
|
+
else
|
230
|
+
# Start over ... too old/ incompatible
|
231
|
+
over = true
|
232
|
+
end
|
233
|
+
else
|
234
|
+
# Start a new inventory
|
235
|
+
over = true
|
236
|
+
end
|
237
|
+
# Starting fresh ?
|
238
|
+
if over or json.nil?
|
239
|
+
json_s = initInventory()
|
240
|
+
else
|
241
|
+
raise CiCd::Builder::Errors::Internal.new sprintf('Internal logic error! %s::%d', __FILE__,__LINE__) if varianth.nil?
|
242
|
+
# Add the new build if we don't have it
|
243
|
+
unless varianth['builds'].map { |b| b['build_name'] }.include?(@vars[:build_rel])
|
244
|
+
#noinspection RubyStringKeysInHashInspection
|
245
|
+
varianth['builds'] <<
|
246
|
+
{
|
247
|
+
'drawer' => @vars[:build_nam],
|
248
|
+
'build_name' => @vars[:build_rel],
|
249
|
+
'build_number' => @vars[:build_num],
|
250
|
+
'release' => @vars[:release],
|
251
|
+
}
|
252
|
+
end
|
253
|
+
build_lst = (varianth['builds'].size-1)
|
254
|
+
build_rel = build_lst
|
255
|
+
i = -1
|
256
|
+
varianth['builds'].each{ |h|
|
257
|
+
i += 1
|
258
|
+
convert_build(h)
|
259
|
+
convert_build(varianth['builds'][build_rel])
|
260
|
+
if h['release'].to_i > varianth['builds'][build_rel]['release'].to_i
|
261
|
+
build_rel = i
|
262
|
+
elsif h['release'] == varianth['builds'][build_rel]['release']
|
263
|
+
build_rel = i if h['build_number'].to_i > varianth['builds'][build_rel]['build_number'].to_i
|
264
|
+
end
|
265
|
+
}
|
266
|
+
|
267
|
+
# Add new branch ...
|
268
|
+
build_bra = _update(varianth, 'branches', @vars[:build_bra])
|
269
|
+
# Add new version ...
|
270
|
+
build_ver = _update(varianth, 'versions', @vars[:build_ver])
|
271
|
+
|
272
|
+
# Set latest
|
273
|
+
varianth['latest'] = {
|
274
|
+
branch: build_bra,
|
275
|
+
version: build_ver,
|
276
|
+
build: build_lst,
|
277
|
+
release: build_rel,
|
278
|
+
}
|
279
|
+
json['gen'] = @options[:gen]
|
280
|
+
json_s = JSON.pretty_generate( json, { indent: "\t", space: ' '})
|
281
|
+
end
|
282
|
+
begin
|
283
|
+
resp = s3_obj.write(:data => json_s)
|
284
|
+
case resp.class.name
|
285
|
+
when %r'^AWS::S3::(S3Object|ObjectVersion)'
|
286
|
+
return 0
|
287
|
+
else
|
288
|
+
return 1
|
289
|
+
end
|
290
|
+
rescue Exception => e
|
291
|
+
return -1
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
def convert_build(h)
|
296
|
+
if h.has_key?('number')
|
297
|
+
h['build_number'] = h['number']
|
298
|
+
h.delete 'number'
|
299
|
+
elsif h.has_key?('build_number')
|
300
|
+
h.delete 'number'
|
301
|
+
else
|
302
|
+
h_build = h.has_key?('build') ? h['build'] : h['build_name']
|
303
|
+
h_number = h_build.gsub(/^.*?-build-([0-9]+)$/, '\1').to_i
|
304
|
+
|
305
|
+
h['build_number'] = h_number
|
306
|
+
h['build_name'] = h_build
|
307
|
+
h.delete 'build'
|
308
|
+
h.delete 'number'
|
309
|
+
end
|
310
|
+
if h.has_key?('build')
|
311
|
+
h_build = h.has_key?('build')
|
312
|
+
h_number = h_build.gsub(/^.*?-build-([0-9]+)$/, '\1').to_i
|
313
|
+
|
314
|
+
h['build_number'] = h_number
|
315
|
+
h['build_name'] = h_build
|
316
|
+
h.delete 'build'
|
317
|
+
h.delete 'number'
|
318
|
+
end
|
319
|
+
h
|
320
|
+
end
|
321
|
+
|
322
|
+
# ---------------------------------------------------------------------------------------------------------------
|
323
|
+
def uploadBuildArtifacts()
|
324
|
+
if @vars.has_key?(:build_dir) and @vars.has_key?(:build_pkg)
|
325
|
+
begin
|
326
|
+
if File.exists?(@vars[:build_pkg])
|
327
|
+
|
328
|
+
artifacts = []
|
329
|
+
|
330
|
+
key = "#{@vars[:project_name]}/#{@vars[:variant]}/#{@vars[:build_nam]}/#{@vars[:build_rel]}"
|
331
|
+
# Store the assembly
|
332
|
+
artifacts << {
|
333
|
+
key: "#{key}.tar.gz",
|
334
|
+
data: {:file => @vars[:build_pkg]},
|
335
|
+
public_url: :build_url,
|
336
|
+
label: 'Package URL'
|
337
|
+
}
|
338
|
+
|
339
|
+
# Store the metadata
|
340
|
+
manifest = manifestMetadata()
|
341
|
+
artifacts << {
|
342
|
+
key: "#{key}.MANIFEST.json",
|
343
|
+
data: {:data => manifest},
|
344
|
+
public_url: :manifest_url,
|
345
|
+
read_url: :manifest_url,
|
346
|
+
label: 'Manifest URL'
|
347
|
+
}
|
348
|
+
|
349
|
+
# Store the checksum
|
350
|
+
artifacts << {
|
351
|
+
key: "#{@vars[:project_name]}/#{@vars[:variant]}/#{@vars[:build_nam]}/#{@vars[:build_rel]}.checksum",
|
352
|
+
data: {:data => @vars[:build_sha]},
|
353
|
+
public_url: :checksum_url,
|
354
|
+
read_url: :checksum_url,
|
355
|
+
label: 'Checksum URL'
|
356
|
+
}
|
357
|
+
|
358
|
+
@vars[:return_code] = uploadToS3(artifacts)
|
359
|
+
if 0 == @vars[:return_code]
|
360
|
+
@vars[:return_code] = takeInventory()
|
361
|
+
end
|
362
|
+
@vars[:return_code]
|
363
|
+
else
|
364
|
+
@vars[:return_code] = 1
|
365
|
+
end
|
366
|
+
rescue => e
|
367
|
+
@logger.error "#{e.class.name} #{e.message}"
|
368
|
+
@vars[:return_code] = -99
|
369
|
+
raise e
|
370
|
+
end
|
371
|
+
else
|
372
|
+
@vars[:return_code] = 2
|
373
|
+
end
|
374
|
+
@vars[:return_code]
|
375
|
+
end
|
376
|
+
|
377
|
+
# ---------------------------------------------------------------------------------------------------------------
|
378
|
+
def manifestMetadata
|
379
|
+
manifest = @vars[:build_mdd].dup
|
380
|
+
|
381
|
+
manifest[:manifest] = getBuilderVersion
|
382
|
+
|
383
|
+
version_major, version_minor, version_patch = manifest[:Version].split('.')
|
384
|
+
|
385
|
+
manifest[:version] = {
|
386
|
+
number: manifest[:Version],
|
387
|
+
major: version_major,
|
388
|
+
minor: version_minor,
|
389
|
+
patch: version_patch,
|
390
|
+
build: @vars[:build_num],
|
391
|
+
branch: @vars[:build_bra],
|
392
|
+
}
|
393
|
+
manifest[:build] = {
|
394
|
+
name: @vars[:build_rel],
|
395
|
+
base: @vars[:build_nam],
|
396
|
+
date: @vars[:build_dte],
|
397
|
+
vrb: @vars[:build_vrb],
|
398
|
+
branch: @vars[:build_bra],
|
399
|
+
checksum: @vars[:build_sha],
|
400
|
+
}
|
401
|
+
# we want lowercase but if we use the existing key we don't have to delete it afterwards ...
|
402
|
+
manifest[:Release] = {
|
403
|
+
number: manifest[:Release],
|
404
|
+
branch: manifest[:Branch],
|
405
|
+
date: manifest[:Date],
|
406
|
+
checksum: @vars[:build_mds],
|
407
|
+
}
|
408
|
+
manifest.delete(:Date)
|
409
|
+
# manifest.delete(:api)
|
410
|
+
# manifest.delete(:core)
|
411
|
+
manifest[:vars] = {}
|
412
|
+
@vars.each { |k, v|
|
413
|
+
unless %w(build_mdd build_txt).include?(k.to_s)
|
414
|
+
manifest[:vars][k.to_s] = v
|
415
|
+
end
|
416
|
+
}
|
417
|
+
manifest = downcaseHashKeys(manifest)
|
418
|
+
manifest[:env] = {}
|
419
|
+
ENV.each { |k, v|
|
420
|
+
unless %w(LS_COLORS AWS_ACCESS_KEY AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECRET_KEY).include?(k.to_s)
|
421
|
+
manifest[:env][k.to_s] = v
|
422
|
+
end
|
423
|
+
}
|
424
|
+
JSON.pretty_generate( manifest, { indent: "\t", space: ' '})
|
425
|
+
end
|
426
|
+
|
427
|
+
end
|
428
|
+
end
|