Module: CiCd::Builder

Defined in:
lib/cicd/builder/version.rb,
lib/cicd/builder.rb,
lib/cicd/builder/mixlib/repo.rb,
lib/cicd/builder/mixlib/build.rb,
lib/cicd/builder/mixlib/utils.rb,
lib/cicd/builder/mixlib/errors.rb,
lib/cicd/builder/mixlib/options.rb,
lib/cicd/builder/mixlib/repo/S3.rb,
lib/cicd/builder/mixlib/constants.rb,
lib/cicd/builder/mixlib/repo/base.rb,
lib/cicd/builder/mixlib/environment.rb,
lib/cicd/builder/mixlib/repo/artifactory.rb

Overview

noinspection ALL

Defined Under Namespace

Modules: Errors, Repo Classes: BuilderBase

Constant Summary collapse

ENV_IGNORED =
%w(LS_COLORS AWS_ACCESS_KEY AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SECRET_KEY)
VERSION =
version
MAJOR =
major
MINOR =
minor
TINY =
tiny
PATCH =
TINY
LOGLEVELS =

noinspection RubyStringKeysInHashInspection

{
	'crit'     => :fatal,
	'critical' => :fatal,
	'err'      => :error,
	'error'    => :error,
	'warn'     => :warn,
	'warning'  => :warn,
	'info'     => :info,
	'debug'    => :debug,
}
MYNAME =
File.basename(__FILE__)

Instance Method Summary collapse

Instance Method Details

#addArtifact(artifacts, script, prefix, opts = {}) ⇒ Object




27
28
29
30
31
32
33
34
# File 'lib/cicd/builder/mixlib/utils.rb', line 27

def addArtifact(artifacts, script, prefix, opts = {})
  key = "#{@vars[:project_name]}/#{@vars[:variant]}/#{@vars[:build_nam]}/#{script.gsub(%r|^#{prefix}|, '')}"
  # Store the artifact - be sure to inherit possible overrides in pkg name and ext but dictate the drawer!
  artifacts << {
      key: key,
      data: {:file => script}.merge(opts),
  }
end

#calcLocalETag(etag, local, size = nil) ⇒ Object




178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/cicd/builder/mixlib/build.rb', line 178

def calcLocalETag(etag, local, size = nil)
  if size == nil
    stat = File.stat(local)
    size = stat.size
  end
  @logger.debug "Calculate etag to match #{etag}"
  match = etag.match(%r'-(\d+)$')
  check = if match
            require 's3etag'
            parts = match[1].to_i
            chunk = size.to_f / parts.to_f
            mbs = (chunk.to_f / 1024 /1024 + 0.5).to_i
            part_size = mbs * 1024 * 1024
            chkit = S3Etag.calc(file: local, threshold: part_size, min_part_size: part_size, max_parts: parts)
            @logger.debug "S3Etag Calculated #{chkit} : (#{size} / #{part_size}) <= #{parts}"
            chunks = size / part_size
            while chkit != etag and chunks <= parts and chunks > 0 and (size > part_size)
              # Go one larger if a modulus remains and we have the right number of parts
              mbs += 1
              part_size = mbs * 1024 * 1024
              chunks = size.to_f / part_size
              chkit = S3Etag.calc(file: local, threshold: part_size, min_part_size: part_size, max_parts: parts)
              @logger.debug "S3Etag Calculated #{chkit} : (#{size} / #{part_size}) <= #{parts}"
            end
            @logger.warn "Unable to match etag #{etag}!" if chkit != etag
            chkit
          else
            Digest::MD5.file(local).hexdigest
          end
end

#checkEnvironmentObject




6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/cicd/builder/mixlib/environment.rb', line 6

def checkEnvironment()
    @logger.step __method__.to_s
	# [2013-12-30 Christo] Detect CI ...
	unless ENV.has_key?('JENKINS_HOME')
		@logger.error "Sorry, your CI environment is not supported at this time (2013-12-30) ... Christo De Lange\n"+
		'This script is developed for Jenkins so either you are not using Jenkins or you ran me outside of the CI ecosystem ...'
		return 99
	end

	# Check for the necessary environment variables
	map_keys = {}

	@options[:env_keys].each { |k|
		map_keys[k]= (not ENV.has_key?(k) or ENV[k].empty?)
	}
	missing = map_keys.keys.select{ |k| map_keys[k] }

	if missing.count() > 0
		# ap missing
		#raise Exception.new("Need these environment variables: #{missing}")
		puts("Need these environment variables: #{missing.ai}")
      return 1
	end
	0
end

#cleanupBuildObject




7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/cicd/builder/mixlib/build.rb', line 7

def cleanupBuild()
    @logger.step __method__.to_s
    [ :build_pkg, :build_chk, :build_mdf, :build_mff ].each do |fil|
      if File.exists?(@vars[fil])
        begin
          FileUtils.rm_f(@vars[fil])
        rescue => e
          @logger.error e.to_s
          #raise e
          return Errors::CLEANUPBUILD_EXCEPTION
        end
      end
    end
	if Dir.exists?(@vars[:build_dir])
		begin
			FileUtils.rm_r(@vars[:build_dir])
		rescue => e
			@logger.error e.to_s
			#raise e
			return Errors::CLEANUPBUILD_EXCEPTION
		end
	end
	0
end

#createMetaDataObject




224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/cicd/builder/mixlib/build.rb', line 224

def ()
  @logger.step __method__.to_s
  @vars[:build_mdd].merge!({
                            :Generation => @options[:gen],
                            :Project => @vars[:project_name],
                            :Variant => @vars[:variant],
                            :Build => @vars[:build_num],
                            :Date => @vars[:build_dte],
                            :Builder => VERSION,

                                  })
  json = JSON.pretty_generate( @vars[:build_mdd], { indent: "\t", space: ' '})
  unless IO.write(@vars[:build_mdf], json) > 0
    @logger.error "Unable to store metadata in '#{@vars[:build_mdf]}'"
    @vars[:return_code] = Errors::STORING_BUILD_METADATA
  end
  @vars[:return_code]
end

#downcaseHashKeys(hash) ⇒ Object




12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/cicd/builder/mixlib/utils.rb', line 12

def downcaseHashKeys(hash)
	down = {}
	hash.each{|k,v|
		if v.is_a?(Hash)
			v = downcaseHashKeys(v)
		end
		if k.to_s.match(/[A-Z]/)
			k = k.to_s.downcase.to_sym
		end
		down[k] = v
	}
	down
end

#downcaseKey(hash, key) ⇒ Object




5
6
7
8
9
# File 'lib/cicd/builder/mixlib/utils.rb', line 5

def downcaseKey(hash,key)
	hash[key.to_s.downcase.to_sym] = hash[key]
	hash.delete(key)
	hash
end

#getArtifactsDefinitionObject




99
100
101
# File 'lib/cicd/builder/mixlib/repo.rb', line 99

def getArtifactsDefinition()
  nil
end

#getLatestObject




78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/cicd/builder/mixlib/environment.rb', line 78

def getLatest
  ret = 0
  @vars[:vars_fil] = "#{@vars[:build_store]}/#{ENV['JOB_NAME']}-#{@vars[:variant]}.env"
  @vars[:latest_fil] = "#{@vars[:build_store]}/#{ENV['JOB_NAME']}-#{@vars[:variant]}.latest"
  @vars[:latest_ver] = ''
  @vars[:latest_sha] = ''
  @vars[:latest_pkg] = ''
  @vars[:latest_ext] = @vars[:build_ext]
  if @vars[:build_nam]
    @vars[:latest_pkg] = "#{@vars[:build_store]}/#{@vars[:build_nam]}.#{@vars[:latest_ext]}"
    unless File.exists?(@vars[:latest_pkg])
      if File.exists?("#{@vars[:build_store]}/#{@vars[:build_nam]}.tar.gz")
        @vars[:latest_ext] = 'tar.gz'
        @vars[:latest_pkg] = "#{@vars[:build_store]}/#{@vars[:build_nam]}.#{@vars[:latest_ext]}"
      end
    end
  end
  ret = loadLatestVarsFile
  ret
end

#getNamingDefinitionObject




104
105
106
# File 'lib/cicd/builder/mixlib/repo.rb', line 104

def getNamingDefinition()
  nil
end

#getRepoClass(type = nil) ⇒ Object




14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/cicd/builder/mixlib/repo.rb', line 14

def getRepoClass(type = nil)
  @logger.info __method__.to_s
  if type.nil?
    type ||= 'S3'
    if ENV.has_key?('REPO_TYPE')
      type = ENV['REPO_TYPE']
    end
  end

  @logger.info "#{type} repo interface"
  clazz = Object.const_get("CiCd::Builder::Repo::#{type}")
  if block_given?
    if clazz.is_a?(Class) and not clazz.nil?
      yield
    end
  end

  clazz
end

#getVarsObject




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/cicd/builder/mixlib/environment.rb', line 33

def getVars()
    @logger.step __method__.to_s
	@vars               ||= {}
	@vars[:release]     = 'latest'
	@vars[:build_store] = '/tmp'
	@vars[:variant]     = 'SNAPSHOT'

	if ENV.has_key?('PROJECT_NAME')
		@vars[:project_name] = ENV['PROJECT_NAME']
	end

	if ENV.has_key?('RELEASE')
		@vars[:release] = ENV['RELEASE']
    elsif File.exists?((version_file=File.join(ENV['REPO_DIR'], 'RELEASE')))
      lines = File.readlines(version_file)
      @vars[:release] = lines.shift.chomp() if lines.count > 0
    else
      raise "'RELEASE' was not provided in either environment or #{version_file} file"
	end

	if ENV.has_key?('VERSION')
		@vars[:version] = ENV['VERSION']
    elsif File.exists?((version_file=File.join(ENV['REPO_DIR'], 'VERSION')))
      lines = File.readlines(version_file)
      @vars[:version] = lines.shift.chomp() if lines.count > 0
    else
      raise "'VERSION' was not provided in either environment or #{version_file} file"
	end

	if ENV.has_key?('BUILD_STORE')
		@vars[:build_store] = "#{ENV['BUILD_STORE']}"
	end

	if ENV.has_key?('VARIANT')
		@vars[:variant] = "#{ENV['VARIANT']}"
    end

	if ENV.has_key?('BUILD_NUMBER')
		@vars[:build_num] = "#{ENV['BUILD_NUMBER']}"
	end

	@vars[:return_code] = getLatest()
end

#isSameDirectory(pwd, workspace) ⇒ Object



82
83
84
85
86
87
88
89
# File 'lib/cicd/builder.rb', line 82

def isSameDirectory(pwd, workspace)
  pwd = File.realdirpath(File.expand_path(pwd))
  workspace = File.realdirpath(File.expand_path(workspace))
  unless pwd == workspace

  end
  return pwd, workspace
end

#loadCheckSumFileObject




163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/cicd/builder/mixlib/build.rb', line 163

def loadCheckSumFile
  if File.exists?(@vars[:build_chk])
    @vars[:build_sha] = IO.readlines(@vars[:build_chk])
    unless @vars[:build_sha].is_a?(Array)
      @logger.error "Unable to parse build checksum from #{@vars[:build_chk]}"
      @vars[:return_code] = Errors::PARSING_BUILD_CHECKSUM
    end
    @vars[:build_sha] = @vars[:build_sha][0].chomp()
  else
    @vars[:build_sha] = ''
  end
  @vars[:return_code]
end

#loadLatestVarsFileObject




100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/cicd/builder/mixlib/environment.rb', line 100

def loadLatestVarsFile
  ret = 0
  if File.exists?(@vars[:latest_fil])
    @vars[:latest_ver] = IO.readlines(@vars[:latest_fil])
    unless @vars[:latest_ver].is_a?(Array)
      @logger.error "Unable to parse latest version from #{@vars[:latest_fil]}"
      ret = Errors::PARSING_LATEST_VERSION
    end
    @vars[:latest_sha] = @vars[:latest_ver][1].chomp() if (@vars[:latest_ver].length > 1)
    @vars[:latest_ver] = @vars[:latest_ver][0].chomp()
    if @vars[:latest_ver] =~ %r'-\d+$'
      @vars[:latest_ver], @vars[:latest_rel] = @vars[:latest_ver].split(/-/)
    end
  end
  ret
end

#makeBuildObject




107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/cicd/builder/mixlib/build.rb', line 107

def makeBuild()
  @logger.step __method__.to_s
  if @vars.has_key?(:build_dir) and @vars.has_key?(:build_pkg)
    begin
      do_build = false
      loadCheckSumFile()
      if 0 == @vars[:return_code]
        do_build = true if @vars[:build_sha].empty?
        do_build = true unless File.exists?(@vars[:build_pkg]) and (Digest::SHA256.file(@vars[:build_pkg]).hexdigest() == @vars[:build_sha])
        if do_build
          @vars[:return_code] = cleanupBuild()
          if 0 == @vars[:return_code]
            @vars[:build_dte] = DateTime.now.strftime('%F %T%:z')
            ()
            if 0 == @vars[:return_code]
              @vars[:return_code] = packageBuild()
              if 0 == @vars[:return_code]
                @vars[:check_sha] = @vars[:build_sha]
                @vars[:build_sha] = if File.exists?(@vars[:build_pkg])
                                      Digest::SHA256.file(@vars[:build_pkg]).hexdigest()
                                    else
                                      '0'
                                    end
                unless IO.write(@vars[:build_chk], @vars[:build_sha]) > 0
                  @logger.error "Unable to store checksum in '#{@vars[:build_chk]}'"
                  @vars[:return_code] = Errors::STORING_BUILD_CHECKSUM
                end
              end
            end
          end
        end
      end

      # Report status regardless of return code.
      reportStatus()

      if do_build
        reportResult()
      else
        # Was no need to build :) or a failure :(
        @logger.info "NO_CHANGE: #{ENV['JOB_NAME']} #{ENV['BUILD_NUMBER']} #{@vars[:build_nam]} #{@vars[:build_pkg]} #{@vars[:build_chk]} [#{@vars[:build_sha]}]"
        # @vars[:return_code] = 0
        return 1
      end
    rescue => e
      @logger.error "makeBuild failure: #{e.class.name} #{e.message}"
      @vars[:return_code] = Errors::MAKEBUILD_EXCEPTION
    end
  else
    @logger.error ':build_dir or :build_pkg is unknown'
    @vars[:return_code] = Errors::MAKEBUILD_PREPARATION
  end
  @vars[:return_code]
end

#manifestMetadataObject




49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/cicd/builder/mixlib/repo.rb', line 49

def 
	manifest = @vars[:build_mdd].dup

	manifest[:manifest] = getBuilderVersion

	version_major, version_minor, version_patch = manifest[:Version].split('.')

	manifest[:version] = {
		number: manifest[:Version],
		major:  version_major,
		minor:  version_minor,
		patch:  version_patch,
		build:  @vars[:build_num],
		branch: @vars[:build_bra],
	}
	manifest[:build] = {
		name:     @vars[:build_nmn],
		base:     @vars[:build_nam],
		date:     @vars[:build_dte],
		vrb:      @vars[:build_vrb],
		branch:   @vars[:build_bra],
		checksum: @vars[:build_sha],
	}
	# we want lowercase but if we use the existing key we don't have to delete it afterwards ...
	manifest[:Release] = {
		number:   manifest[:Release],
		branch:   manifest[:Branch],
		date:     manifest[:Date],
		checksum: @vars[:build_mds],
	}
	manifest.delete(:Date)
	# manifest.delete(:api)
	# manifest.delete(:core)
	manifest[:vars] = {}
	@vars.sort.each { |k, v|
		unless %w(build_mdd build_txt).include?(k.to_s)
			manifest[:vars][k.to_s] = v
		end
	}
	manifest = downcaseHashKeys(manifest)
	manifest[:env] = {}
	ENV.to_hash.sort.each { |k, v|
		unless ENV_IGNORED.include?(k.to_s)
			manifest[:env][k.to_s] = v
		end
	}
    JSON.pretty_generate( manifest, { indent: "\t", space: ' '})
end

#packageBuildObject




210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/cicd/builder/mixlib/build.rb', line 210

def packageBuild()
    @logger.step __method__.to_s
	excludes=%w(*.iml *.txt *.sh *.md .gitignore .editorconfig .jshintrc *.deprecated adminer doc)
	excludes = excludes.map{ |e| "--exclude=#{@vars[:build_nam]}/#{e}" }.join(' ')
	cmd = %(cd #{ENV['WORKSPACE']}; tar zcvf #{@vars[:build_pkg]} #{excludes} #{@vars[:build_nam]} 1>#{@vars[:build_pkg]}.manifest)
	@logger.info cmd
	logger_info = %x(#{cmd})
	ret = $?.exitstatus
	@logger.info logger_info
	FileUtils.rmtree(@vars[:build_dir])
	ret
end

#parseOptionsObject




5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/cicd/builder/mixlib/options.rb', line 5

def parseOptions()
	# Parse options
	@options = {
                  log_level:      :warn,
                  #dry_run:       false,
                  trace:          false,
                  gen:            '3.0.0',
                }.merge @default_options

	opt_parser = OptionParser.new do |opts|
		opts.banner = "Usage: #{MYNAME} [@options]"

		opts.on('-l', '--log_level LEVEL', '--log-level LEVEL', [:trace, :debug, :info, :step, :warn, :error, :fatal, :todo], 'Log level ([:trace, :debug, :info, :step, :warn, :error, :fatal, :todo])') do |v|
			@options[:log_level] = v
		end
		opts.on('-f', '--inifile FILE', 'INI file with settings') do |v|
			@options[:inifile] = v
		end
		opts.on('-t', '--[no-]trace', 'Print backtrace in log, Default --no-trace') do |v|
			@options[:trace] = v
		end
	end

	opt_parser.parse!

	# Set up logger
	Logging.init :trace, :debug, :info, :note, :step, :warn, :error, :fatal, :todo
	@logger = Logging.logger(STDOUT,
	                         :pattern      => "%#{::Logging::MAX_LEVEL_LENGTH}l: %m\n",
	                         :date_pattern => '%Y-%m-%d %H:%M:%S')
	@logger.level = @options[:log_level]

    unless @options[:inifile]
      if ENV.has_key?('INIFILE')
        @options[:inifile] = ENV['INIFILE']
      end
    end

    if @options.key?(:inifile)
		@options[:inifile] = File.expand_path(@options[:inifile])
		unless File.exist?(@options[:inifile])
			raise StandardError.new("#{@options[:inifile]} not found!")
		end
		begin
			# ENV.each{ |key,_|
			# 	ENV.delete(key)
			# }
			ini = IniFile.load(@options[:inifile])
			ini['global'].each{ |key,value|
				ENV[key]=value.to_s
			}
			def _expand(k,v,regex,rerun)
				matches = v.match(regex)
				if matches
					var = matches[1]
					if ENV.has_key?(var)
						ENV[k]=v.gsub(/\$\{#{var}\}/,ENV[var]).gsub(/\$#{var}/,ENV[var])
					else
						rerun[var] = 1
					end
				end
			end

			pending = nil
			rerun = {}
			begin
				pending = rerun
				rerun = {}
				ENV.to_hash.each{|k,v|
					if v.match(/\$/)
						_expand(k,v,%r'[^\\]\$\{(\w+)\}', rerun)
						_expand(k,v,%r'[^\\]\$(\w+)',     rerun)
					end
				}
				# Should break out the first time that we make no progress!
			end while pending != rerun
		rescue IniFile::Error => e
			# noop
		rescue Exception => e
			@logger.error "#{e.class.name} #{e.message}"
			raise e
		end
	end
	@options
end

#prepareBuildObject




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cicd/builder/mixlib/build.rb', line 33

def prepareBuild()
  @logger.step __method__.to_s
  meta = {}
  @vars[:return_code] = 0
  %w[ WORKSPACE PROJECT_NAME ].each do |e|
    unless ENV.has_key?(e)
      puts "#{e} environment variable is required"
      @vars[:return_code] = Errors::MISSING_ENV_VAR
    end
  end
  meta[:Version] = @vars[:version]
  meta[:Release] = @vars[:release]

  if @vars[:return_code] == 0

    if File.exists?(ENV['WORKSPACE']) and (File.directory?(ENV['WORKSPACE']) or File.symlink?(ENV['WORKSPACE']))

      place = ''
      begin
        req = 'require "git"'
        eval req

        # Assuming we are in the workspace ...
        place = "Git.open('#{ENV['WORKSPACE']}')"
        git = Git.open(ENV['WORKSPACE'], :log => @logger)
        place = 'git.log'
        meta[:Commit] = git.log[0].sha
        place = 'git.current_branch'
        meta[:Branch] = git.current_branch

        @vars[:build_ext] = 'tar.gz'
        @vars[:build_bra] = meta[:Branch].gsub(%r([/|]),'.')
        @vars[:build_ver] = "#{meta[:Version]}"
        @vars[:build_rel] = "#{meta[:Release]}"
        @vars[:build_vrb] = "#{@vars[:build_ver]}-release-#{meta[:Release]}-#{@vars[:build_bra]}-#{@vars[:variant]}" #
        @vars[:build_nam] = "#{@vars[:project_name]}-#{@vars[:build_vrb]}"
        @vars[:build_nmn] = "#{@vars[:build_nam]}-build-#{@vars[:build_num]}"
        @vars[:build_dir] = "#{ENV['WORKSPACE']}/#{@vars[:build_nmn]}"
        @vars[:latest_pkg]= "#{@vars[:build_store]}/#{@vars[:build_nmn]}.#{@vars[:build_ext]}"
        @vars[:build_pkg] = "#{@vars[:build_nmn]}.#{@vars[:build_ext]}"
        @vars[:build_chk] = "#{@vars[:build_nmn]}.checksum"
        @vars[:build_mff] = "#{@vars[:build_nmn]}.manifest"
        @vars[:build_mdf] = "#{@vars[:build_nmn]}.meta"
        @vars[:build_mdd] = meta.dup
        #noinspection RubyArgCount
        @vars[:build_mds] = Digest::SHA256.hexdigest(meta.to_s)

        @vars[:return_code] = 0

      rescue Exception => e
        @logger.error "#{e.class}:: '#{place}' - #{e.message}"
        @vars[:return_code] = Errors::PREPAREBUILD_EXCEPTION
      end

    else
      puts "Invalid workspace: '#{ENV['WORKSPACE']}'"
      @vars[:return_code] = Errors::INVALID_WORKSPACE
    end
  end

  if @vars[:return_code] == 0
    @vars[:local_dirs] ||= {}
    %w(artifacts latest).each do |dir|
      @vars[:local_dirs][dir] = "#{ENV['WORKSPACE']}/#{dir}"
      unless File.directory?(dir)
        Dir.mkdir(dir)
      end
    end
  end

  @vars[:return_code]
end

#reportResultObject



201
202
203
204
205
206
207
208
# File 'lib/cicd/builder/mixlib/environment.rb', line 201

def reportResult()
  if 0 == @vars[:return_code]
    # NOTE the '.note'!
    @logger.note  "CHANGE:  #{ENV['JOB_NAME']} #{ENV['BUILD_NUMBER']} #{@vars[:build_nam]} (#{@vars[:build_pkg]}) [#{@vars[:check_sha]}] => [#{@vars[:build_sha]}]"
  else
    @logger.error "FAILURE: #{ENV['JOB_NAME']} #{ENV['BUILD_NUMBER']} #{@vars[:build_pkg]} #{@vars[:return_code]}"
  end
end

#reportStatus(ignored = ENV_IGNORED) ⇒ Object




211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
# File 'lib/cicd/builder/mixlib/environment.rb', line 211

def reportStatus(ignored=ENV_IGNORED)
    # [2013-12-30 Christo] Report status,environment, etc.

	if @logger.level < ::Logging::LEVELS['warn']
		@logger.info '='*100
		@logger.info Dir.getwd()
		@logger.info '='*100

		@logger.info "Config:"
		@options.each{|k,v|
			unless ignored.include?(k)
				@logger.info sprintf("%25s: %s", "#{k.to_s}",  "#{v.to_s}")
			end
		}

		@logger.info '='*100

		@logger.info "Parameters:"
		@vars.sort.each{|k,v|
			unless ignored.include?(k)
				@logger.info sprintf("%25s: %s", "#{k.to_s}",  "#{v.to_s}")
			end
		}

		@logger.info '='*100
	end

	if @logger.level < ::Logging::LEVELS['info']
		@logger.debug '='*100
		@logger.debug "Environment:"
		ENV.sort.each{|k,v|
			unless ignored.include?(k)
				@logger.debug sprintf("%25s: %s", "#{k.to_s}",  "#{v.to_s}")
			end
		}

		@logger.debug '='*100
	end
end

#saveBuildObject




138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/cicd/builder/mixlib/environment.rb', line 138

def saveBuild()
  @logger.step __method__.to_s
  begin
    raise 'ERROR: Checksum not read'       unless @vars.has_key?(:latest_sha)
    raise 'ERROR: Checksum not calculated' unless @vars.has_key?(:build_sha)
    change = false
    if @vars[:latest_sha] != @vars[:build_sha]
      change = true
      @logger.info "CHANGE: Checksum [#{@vars[:latest_sha]}] => [#{@vars[:build_sha]}]"
    end
    if @vars[:latest_ver] != @vars[:build_ver]
      change = true
      @logger.info "CHANGE: Version [#{@vars[:latest_ver]}] => [#{@vars[:build_ver]}]"
    end
    if @vars[:latest_rel] != @vars[:build_rel]
      change = true
      @logger.info "CHANGE: Release [#{@vars[:latest_rel]}] => [#{@vars[:build_rel]}]"
    end
    unless File.file?(@vars[:build_pkg])
      change = true
      @logger.info "CHANGE: No #{@vars[:build_pkg]}"
    end
    unless File.symlink?(@vars[:latest_pkg])
      change = true
      @logger.info "CHANGE: No #{@vars[:latest_pkg]}"
    end

    if change
      if @vars[:latest_pkg] != @vars[:build_pkg] and  File.file?(@vars[:build_pkg])
        @logger.info "Link #{@vars[:latest_pkg]} to #{@vars[:build_pkg]}"
        begin
          File.unlink(@vars[:latest_pkg])
        rescue
          # noop
        end
        File.symlink(@vars[:build_pkg], @vars[:latest_pkg])
      else
        @logger.warn "Skipping link #{@vars[:latest_pkg]} to missing '#{@vars[:build_pkg]}'"
      end
      @vars[:return_code] = saveLatestVarsFile()
      unless 0 == @vars[:return_code]
        @logger.error "Failed to save latest vars file: #{@vars[:latest_fil]}"
        return @vars[:return_code]
      end
      @vars[:return_code] = saveEnvironment(ENV_IGNORED)
      unless 0 == @vars[:return_code]
        @logger.error "Failed to save environment vars file: #{@vars[:vars_fil]}"
        return @vars[:return_code]
      end
      # NOTE the '.note'!
      @logger.note "CHANGE: #{ENV['JOB_NAME']} (#{@vars[:build_ver]}-#{@vars[:build_rel]}[#{@vars[:build_sha]}])"
    else
      @logger.info "Artifact #{@vars[:latest_pkg]} unchanged (#{@vars[:latest_ver]}-#{@vars[:latest_rel]} [#{@vars[:latest_sha]}])"
      @logger.note "NO_CHANGE: #{ENV['JOB_NAME']} #{@vars[:latest_ver]}"
    end
    @vars[:return_code] = 0
  rescue => e
    @logger.error "#{e.backtrace[0]}: #{e.class.name} #{e.message}"
    @vars[:return_code] = 2
  end
  @vars[:return_code]
end

#saveEnvironment(ignored = ENV_IGNORED) ⇒ Object




125
126
127
128
129
130
131
132
133
134
135
# File 'lib/cicd/builder/mixlib/environment.rb', line 125

def saveEnvironment(ignored=ENV_IGNORED)
    @logger.step __method__.to_s
	@logger.info "Save environment to #{@vars[:vars_fil]}"
	vstr = ['[global]']
	ENV.to_hash.sort.each{|k,v|
		vstr << %(#{k}="#{v}") unless ignored.include?(k)
	}

    @vars[:return_code] = (IO.write(@vars[:vars_fil], vstr.join("\n")) > 0) ? 0 : Errors::SAVE_ENVIRONMENT_VARS
    return @vars[:return_code]
end

#saveLatestVarsFileObject




118
119
120
121
122
# File 'lib/cicd/builder/mixlib/environment.rb', line 118

def saveLatestVarsFile
  @logger.info "Save latest build info to #{@vars[:latest_fil]}"
  wrote = IO.write(@vars[:latest_fil], "#{@vars[:build_ver]}-#{@vars[:build_rel]}\n#{@vars[:build_sha]}")
  ret = (wrote > 0) ? 0 : Errors::SAVE_LATEST_VARS
end

#uploadBuildArtifactsObject




35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/cicd/builder/mixlib/repo.rb', line 35

def uploadBuildArtifacts()
  @logger.step __method__.to_s
  clazz = getRepoClass()
  if clazz.is_a?(Class) and not clazz.nil?
    @repo = clazz.new(self)
    @vars[:return_code] = @repo.uploadBuildArtifacts()
  else
    @logger.error "CiCd::Builder::Repo::#{type} is not a valid repo class"
    @vars[:return_code] = Errors::BUILDER_REPO_TYPE
  end
  @vars[:return_code]
end