Class: Shiplane::CheckoutArtifact

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/shiplane/checkout_artifact.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sha, config: nil) ⇒ CheckoutArtifact

Returns a new instance of CheckoutArtifact.



12
13
14
15
16
17
18
19
# File 'lib/shiplane/checkout_artifact.rb', line 12

def initialize(sha, config: nil)
  @sha = sha
  @shiplane_config = config || Shiplane::Configuration.new

  # call this before changing directories.
  # This prevents race conditions where the config file is accessed before being downloaded
  @shiplane_config
end

Instance Attribute Details

#shaObject

Returns the value of attribute sha.



7
8
9
# File 'lib/shiplane/checkout_artifact.rb', line 7

def sha
  @sha
end

#shiplane_configObject (readonly)

Returns the value of attribute shiplane_config.



8
9
10
# File 'lib/shiplane/checkout_artifact.rb', line 8

def shiplane_config
  @shiplane_config
end

Class Method Details

.checkout!(sha, config: nil) ⇒ Object



254
255
256
# File 'lib/shiplane/checkout_artifact.rb', line 254

def self.checkout!(sha, config: nil)
  new(sha, config: config).checkout!
end

Instance Method Details

#app_directoryObject



70
71
72
# File 'lib/shiplane/checkout_artifact.rb', line 70

def app_directory
  @app_directory ||= File.join(Dir.pwd, 'docker_builds', appname)
end

#appnameObject



21
22
23
# File 'lib/shiplane/checkout_artifact.rb', line 21

def appname
  @appname ||= project_config['appname']
end

#archive_and_unpack_commitObject



141
142
143
144
145
146
147
148
149
150
# File 'lib/shiplane/checkout_artifact.rb', line 141

def archive_and_unpack_commit
  puts "Creating archive from local git repo in #{archive_filename}..."
  success = system("git archive --format=tar.gz -o #{archive_path} #{sha}")

  puts "Unpacking archive to #{build_directory}..."
  FileUtils.rm_rf(build_directory) if File.directory?(build_directory)
  FileUtils.mkdir_p build_directory

  success && system("(cd #{app_directory} && tar -xzf #{appname}-#{sha}.tar.gz -C #{build_directory})")
end

#archive_filenameObject



107
108
109
# File 'lib/shiplane/checkout_artifact.rb', line 107

def archive_filename
  @archive_filename ||= "#{appname}-#{sha}.tar.gz"
end

#archive_pathObject



111
112
113
# File 'lib/shiplane/checkout_artifact.rb', line 111

def archive_path
  @archive_path ||= File.join(app_directory, archive_filename)
end

#bitbucket_origin?Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/shiplane/checkout_artifact.rb', line 37

def bitbucket_origin?
  project_config['version_control_host'] == 'bitbucket'
end

#bitbucket_tokenObject



49
50
51
# File 'lib/shiplane/checkout_artifact.rb', line 49

def bitbucket_token
  @bitbucket_token ||= ENV['BITBUCKET_TOKEN']
end

#bitbucket_urlObject



66
67
68
# File 'lib/shiplane/checkout_artifact.rb', line 66

def bitbucket_url
  "https://#{bitbucket_token ? "#{bitbucket_username}:#{bitbucket_token}@" : ''}bitbucket.org/#{project_config['origin']}/get/#{sha}.tar.gz"
end

#bitbucket_usernameObject



53
54
55
# File 'lib/shiplane/checkout_artifact.rb', line 53

def bitbucket_username
  @bitbucket_username ||= ENV['BITBUCKET_USERNAME']
end

#build_directoryObject



74
75
76
# File 'lib/shiplane/checkout_artifact.rb', line 74

def build_directory
  @build_directory ||= File.join(app_directory, "#{appname}-#{sha}")
end

#checkout!Object



82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/shiplane/checkout_artifact.rb', line 82

def checkout!
  return if File.exist?(File.join(build_directory, Shiplane::SHIPLANE_CONFIG_FILENAME))

  puts "Checking out Application #{appname}[#{sha}]..."
  make_directory

  success = send(checkout_strategy[:method])

  raise "Errors encountered while downloading archive" unless success
  puts "Finished checking out Application"
  tasks.each(&method(:send))
end

#checkout_strategiesObject



95
96
97
98
99
100
101
# File 'lib/shiplane/checkout_artifact.rb', line 95

def checkout_strategies
  @checkout_strategies ||= [
    { method: :archive_and_unpack_commit, conditions: -> { commit_exists? } },
    { method: :download_archive, conditions: -> { !bitbucket_origin? } },
    { method: :checkout_via_git, conditions: -> { true } },
  ]
end

#checkout_strategyObject



103
104
105
# File 'lib/shiplane/checkout_artifact.rb', line 103

def checkout_strategy
  @checkout_strategy ||= checkout_strategies.find{|strategy| strategy[:conditions].call }
end

#checkout_via_gitObject



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/shiplane/checkout_artifact.rb', line 164

def checkout_via_git
  FileUtils.rm_rf(build_directory) if File.directory?(build_directory)
  FileUtils.mkdir_p build_directory

  success = true
  puts "Cloning from #{git_clone_url}..."
  success = success && system("git clone --depth=1 #{git_clone_url} #{build_directory}")
  FileUtils.cd build_directory do
    puts "Fetching Single SHA"
    fetch_success = system("git fetch origin #{sha} && git reset --hard FETCH_HEAD")

    unless fetch_success
      puts "Unable to fetch single commit. Fetching FULL history"
      fetch_success = system("git fetch --unshallow && git fetch origin #{sha} && git reset --hard #{sha}")
    end

    success = success && fetch_success

    puts "Removing Git folders before building..."
    success = success && FileUtils.rm_rf("#{build_directory}/.git")
  end
  success
end

#commit_exists?Boolean

Returns:

  • (Boolean)


160
161
162
# File 'lib/shiplane/checkout_artifact.rb', line 160

def commit_exists?
  system("git rev-parse #{sha}")
end

#copy_current_directoryObject



135
136
137
138
139
# File 'lib/shiplane/checkout_artifact.rb', line 135

def copy_current_directory
  puts "Current directory is target SHA. Copying for build"

  FileUtils.cp_r(".", build_directory)
end

#copy_env_filesObject



212
213
214
215
216
# File 'lib/shiplane/checkout_artifact.rb', line 212

def copy_env_files
  puts "Copying in environment files..."
  FileUtils.cp File.join(Dir.pwd, build_config.fetch('environment_file', '.env')), File.join(build_directory, '.env')
  puts "Environment Files Copied"
end

#copy_erb_file(filepath) ⇒ Object



236
237
238
# File 'lib/shiplane/checkout_artifact.rb', line 236

def copy_erb_file(filepath)
  File.write(File.join(build_directory, filepath.gsub(".erb","")), ERB.new(File.read(filepath)).result, mode: 'w')
end

#copy_insert_on_build_filesObject



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/shiplane/checkout_artifact.rb', line 218

def copy_insert_on_build_files
  puts "Copying application configuration files..."

  if Dir.exist? File.join(build_config.fetch('settings_folder', '.shiplane'), "insert_on_build")
    FileUtils.cd File.join(build_config.fetch('settings_folder', '.shiplane'), "insert_on_build") do
      Dir["*/**"].each do |filepath|
        if File.extname(filepath) == ".erb"
          copy_erb_file(filepath)
        else
          FileUtils.mkdir_p File.join(build_directory, File.dirname(filepath))
          FileUtils.cp filepath, File.join(build_directory, filepath)
        end
      end
    end
  end
  puts "Configuration Files Copied"
end

#current_shaObject



25
26
27
28
29
# File 'lib/shiplane/checkout_artifact.rb', line 25

def current_sha
  stdout, *_ = Open3.capture3("git rev-parse HEAD")

  stdout
end

#current_short_shaObject



31
32
33
34
35
# File 'lib/shiplane/checkout_artifact.rb', line 31

def current_short_sha
  stdout, *_ = Open3.capture3("git rev-parse --short HEAD")

  stdout
end

#download_archiveObject



115
116
117
118
119
120
121
# File 'lib/shiplane/checkout_artifact.rb', line 115

def download_archive
  puts "Downloading #{git_url} --output #{archive_filename}"
  puts "Deploying SHA different from current version. Checking out from Git Repository"

  success = system("curl -L #{git_url} --output #{archive_path}")
  success && unpack_archive
end

#git_clone_urlObject



152
153
154
# File 'lib/shiplane/checkout_artifact.rb', line 152

def git_clone_url
  "https://#{bitbucket_username}:#{bitbucket_token}@#{git_host_url}/#{project_config['origin']}.git"
end

#git_host_urlObject



123
124
125
126
127
128
129
# File 'lib/shiplane/checkout_artifact.rb', line 123

def git_host_url
  return "bitbucket.org" if bitbucket_origin?
  return "github.com" if github_origin?

  # TODO
  raise 'Gitlab needs fixing'
end

#git_urlObject



57
58
59
60
# File 'lib/shiplane/checkout_artifact.rb', line 57

def git_url
  return github_url if github_origin?
  return bitbucket_url if bitbucket_origin?
end

#github_origin?Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/shiplane/checkout_artifact.rb', line 41

def github_origin?
  project_config['version_control_host'] == 'github'
end

#github_tokenObject



45
46
47
# File 'lib/shiplane/checkout_artifact.rb', line 45

def github_token
  @github_token ||= ENV['GITHUB_TOKEN']
end

#github_urlObject



62
63
64
# File 'lib/shiplane/checkout_artifact.rb', line 62

def github_url
  "https://#{github_token ? "#{github_token}@" : ''}github.com/#{project_config['origin']}/archive/#{sha}.tar.gz"
end

#make_directoriesObject



204
205
206
207
208
209
210
# File 'lib/shiplane/checkout_artifact.rb', line 204

def make_directories
  FileUtils.cd build_directory do
    required_directories.each do |directory|
      FileUtils.mkdir_p directory
    end
  end
end

#make_directoryObject



78
79
80
# File 'lib/shiplane/checkout_artifact.rb', line 78

def make_directory
  FileUtils.mkdir_p app_directory
end

#required_directoriesObject



250
251
252
# File 'lib/shiplane/checkout_artifact.rb', line 250

def required_directories
  ['vendor']
end

#target_sha_is_current?Boolean

Returns:

  • (Boolean)


131
132
133
# File 'lib/shiplane/checkout_artifact.rb', line 131

def target_sha_is_current?
  sha == current_short_sha.strip || sha == current_sha.strip
end

#tasksObject



200
201
202
# File 'lib/shiplane/checkout_artifact.rb', line 200

def tasks
  [:make_directories, :copy_env_files, :copy_insert_on_build_files, :unignore_required_directories]
end

#unignore_required_directoriesObject



240
241
242
243
244
245
246
247
248
# File 'lib/shiplane/checkout_artifact.rb', line 240

def unignore_required_directories
  puts "Adding Required Directories as explicit inclusions in ignore file..."
  File.open(File.join(build_directory, '.dockerignore'), 'a') do |file|
    required_directories.each do |directory|
      file.puts "!#{directory}/*"
    end
  end
  puts "Finished including required directories..."
end

#unpack_archiveObject



188
189
190
191
192
193
194
195
196
197
198
# File 'lib/shiplane/checkout_artifact.rb', line 188

def unpack_archive
  puts "Unpacking archive to #{build_directory}..."
  FileUtils.rm_rf(build_directory) if File.directory?(build_directory)
  FileUtils.mkdir_p build_directory

  success = true
  FileUtils.cd app_directory do
    success = success && system("tar -xzf #{appname}-#{sha}.tar.gz -C .")
  end
  success
end