Class: Fastlane::Actions::XcodeServerGetAssetsAction::XcodeServer

Inherits:
Object
  • Object
show all
Defined in:
fastlane/lib/fastlane/actions/xcode_server_get_assets.rb

Instance Method Summary collapse

Constructor Details

#initialize(host, username, password) ⇒ XcodeServer

Returns a new instance of XcodeServer.



109
110
111
112
113
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 109

def initialize(host, username, password)
  @host = host.start_with?('https://') ? host : "https://#{host}"
  @username = username
  @password = password
end

Instance Method Details

#fetch_all_botsObject



115
116
117
118
119
120
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 115

def fetch_all_bots
  response = get_endpoint('/bots')
  UI.user_error!("You are unauthorized to access data on #{@host}, please check that you're passing in a correct username and password.") if response.status == 401
  UI.user_error!("Failed to fetch Bots from Xcode Server at #{@host}, response: #{response.status}: #{response.body}.") if response.status != 200
  JSON.parse(response.body)['results']
end

#fetch_assets(integration_id, target_folder, action) ⇒ Object



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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 128

def fetch_assets(integration_id, target_folder, action)
  # create a temp folder and a file, stream the download into it
  Dir.mktmpdir do |dir|
    temp_file = File.join(dir, "tmp_download.#{rand(1_000_000)}")
    f = open(temp_file, 'w')
    streamer = lambda do |chunk, remaining_bytes, total_bytes|
      if remaining_bytes && total_bytes
        UI.important("Downloading: #{100 - (100 * remaining_bytes.to_f / total_bytes.to_f).to_i}%")
      else
        UI.error(chunk.to_s)
      end
      f.write(chunk)
    end

    response = self.get_endpoint("/integrations/#{integration_id}/assets", streamer)
    f.close

    UI.user_error!("Integration doesn't have any assets (it probably never ran).") if response.status == 500
    UI.user_error!("Failed to fetch Assets zip for Integration #{integration_id} from Xcode Server at #{@host}, response: #{response.status}: #{response.body}") if response.status != 200

    # unzip it, it's a .tar.gz file
    out_folder = File.join(dir, "out_#{rand(1_000_000)}")
    FileUtils.mkdir_p(out_folder)

    action.sh("cd \"#{out_folder}\"; cat \"#{temp_file}\" | gzip -d | tar -x")

    # then pull the real name from headers
    asset_filename = response.headers['Content-Disposition'].split(';')[1].split('=')[1].delete('"')
    asset_foldername = asset_filename.split('.')[0]

    # rename the folder in out_folder to asset_foldername
    found_folder = Dir.entries(out_folder).select { |item| item != '.' && item != '..' }[0]

    UI.user_error!("Internal error, couldn't find unzipped folder") if found_folder.nil?

    unzipped_folder_temp_name = File.join(out_folder, found_folder)
    unzipped_folder = File.join(out_folder, asset_foldername)

    # rename to destination name
    FileUtils.mv(unzipped_folder_temp_name, unzipped_folder)

    target_folder = File.absolute_path(target_folder)

    # create target folder if it doesn't exist
    FileUtils.mkdir_p(target_folder)

    # and move+rename it to the destination place
    FileUtils.cp_r(unzipped_folder, target_folder)
    out = File.join(target_folder, asset_foldername)
    return out
  end
  return nil
end

#fetch_integrations(bot_id) ⇒ Object



122
123
124
125
126
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 122

def fetch_integrations(bot_id)
  response = get_endpoint("/bots/#{bot_id}/integrations?last=10")
  UI.user_error!("Failed to fetch Integrations for Bot #{bot_id} from Xcode Server at #{@host}, response: #{response.status}: #{response.body}") if response.status != 200
  JSON.parse(response.body)['results']
end

#get_endpoint(endpoint, response_block = nil) ⇒ Object



197
198
199
200
201
202
203
204
205
206
207
208
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 197

def get_endpoint(endpoint, response_block = nil)
  url = url_for_endpoint(endpoint)
  headers = self.headers || {}

  if response_block
    response = Excon.get(url, response_block: response_block, headers: headers)
  else
    response = Excon.get(url, headers: headers)
  end

  return response
end

#headersObject



182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'fastlane/lib/fastlane/actions/xcode_server_get_assets.rb', line 182

def headers
  require 'base64'
  headers = {
    'User-Agent' => 'fastlane-xcode_server_get_assets', # XCS wants user agent. for some API calls. not for others. sigh.
    'X-XCSAPIVersion' => 1 # XCS API version with this API, Xcode needs this otherwise it explodes in a 500 error fire. Currently Xcode 7 Beta 5 is on Version 5.
  }

  if @username && @password
    userpass = "#{@username}:#{@password}"
    headers['Authorization'] = "Basic #{Base64.strict_encode64(userpass)}"
  end

  return headers
end