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

Inherits:
Object
  • Object
show all
Defined in:
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.



112
113
114
115
116
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 112

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

Instance Method Details

#fetch_all_botsObject



118
119
120
121
122
123
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 118

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



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
181
182
183
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 131

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(1000000)}")
    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(1000000)}")
    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



125
126
127
128
129
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 125

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



200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 200

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



185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/fastlane/actions/xcode_server_get_assets.rb', line 185

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 and @password
    userpass = "#{@username}:#{@password}"
    headers['Authorization'] = "Basic #{Base64.strict_encode64(userpass)}"
  end

  return headers
end