class Supply::Client
Constants
- SCOPE
- SERVICE
Attributes
Editing something Reference to the entry we’re currently editing. Might be nil if don’t have one open
Package name of the currently edited element
Public Class Methods
@!group Login
Supply::AbstractGoogleServiceClient::service_account_authentication
# File supply/lib/supply/client.rb, line 120 def self.service_account_authentication(params: nil) if params[:json_key] || params[:json_key_data] super(params: params) elsif params[:key] && params[:issuer] require 'google/api_client/auth/key_utils' UI.important("This type of authentication is deprecated. Please consider using JSON authentication instead") key = Google::APIClient::KeyUtils.load_from_pkcs12(File.expand_path(params[:key]), 'notasecret') cred_json = { private_key: key.to_s, client_email: params[:issuer] } service_account_json = StringIO.new(JSON.dump(cred_json)) service_account_json else UI.user_error!("No authentication parameters were specified. These must be provided in order to authenticate with Google") end end
Public Instance Methods
Get a list of all AAB version codes - returns the list of version codes
# File supply/lib/supply/client.rb, line 261 def aab_version_codes ensure_active_edit! result = call_google_api { client.list_edit_bundles(current_package_name, current_edit.id) } return Array(result.bundles).map(&:version_code) end
Aborts the current edit deleting all pending changes
# File supply/lib/supply/client.rb, line 152 def abort_current_edit ensure_active_edit! call_google_api { client.delete_edit(current_package_name, current_edit.id) } self.current_edit = nil self.current_package_name = nil end
Get a list of all APK version codes - returns the list of version codes
# File supply/lib/supply/client.rb, line 252 def apks_version_codes ensure_active_edit! result = call_google_api { client.list_edit_apks(current_package_name, current_edit.id) } return Array(result.apks).map(&:version_code) end
Begin modifying a certain package
# File supply/lib/supply/client.rb, line 143 def begin_edit(package_name: nil) UI.user_error!("You currently have an active edit") if @current_edit self.current_edit = call_google_api { client.insert_edit(package_name) } self.current_package_name = package_name end
Remove a specific screenshot of a given image_type and language from the store listing
@param [String] image_type (e.g. phoneScreenshots, sevenInchScreenshots, …) @param [String] language localization code (i.e. BCP-47 language tag as in ‘pt-BR`) @param [String] image_id The id of the screenshot to remove (as per `ImageListing#id`)
# File supply/lib/supply/client.rb, line 610 def clear_screenshot(image_type: nil, language: nil, image_id: nil) ensure_active_edit! call_google_api do client.delete_edit_image( current_package_name, current_edit.id, language, image_type, image_id ) end end
Remove all screenshots of a given image_type and language from the store listing
@param [String] image_type (e.g. phoneScreenshots, sevenInchScreenshots, …) @param [String] language localization code (i.e. BCP-47 language tag as in ‘pt-BR`)
# File supply/lib/supply/client.rb, line 591 def clear_screenshots(image_type: nil, language: nil) ensure_active_edit! call_google_api do client.deleteall_edit_image( current_package_name, current_edit.id, language, image_type ) end end
Commits the current edit saving all pending changes on Google Play
# File supply/lib/supply/client.rb, line 169 def commit_current_edit! ensure_active_edit! call_google_api do begin client.commit_edit( current_package_name, current_edit.id, changes_not_sent_for_review: Supply.config[:changes_not_sent_for_review] ) rescue Google::Apis::ClientError => e unless Supply.config[:rescue_changes_not_sent_for_review] raise end error = begin JSON.parse(e.body) rescue nil end if error message = error["error"] && error["error"]["message"] else message = e.body end if message.include?("The query parameter changesNotSentForReview must not be set") client.commit_edit( current_package_name, current_edit.id ) elsif message.include?("Please set the query parameter changesNotSentForReview to true") client.commit_edit( current_package_name, current_edit.id, changes_not_sent_for_review: true ) else raise end end end self.current_edit = nil self.current_package_name = nil end
Download a Universal APK generated by Google for a particular version code
@param [Supply::GeneratedUniversalApk] generated_universal_apk
The GeneratedUniversalApk object retrieved from a call to `list_generated_universal_apks`
@param [IO, String] destination
IO stream or filename to receive content download
# File supply/lib/supply/client.rb, line 337 def download_generated_universal_apk(generated_universal_apk:, destination:) call_google_api { client.download_generatedapk( generated_universal_apk.package_name, generated_universal_apk.version_code, generated_universal_apk.download_id, download_dest: destination ) } end
Fetch all the images of a given type and for a given language of your store listing
@param [String] image_type Typically one of the elements of either Supply::IMAGES_TYPES or Supply::SCREENSHOT_TYPES @param [String] language Localization code (a BCP-47 language tag; for example, “de-AT” for Austrian German). @return [Array<ImageListing>] A list of ImageListing
instances describing each image with its id, sha256 and url
# File supply/lib/supply/client.rb, line 548 def fetch_images(image_type: nil, language: nil) ensure_active_edit! result = call_google_api do client.list_edit_images( current_package_name, current_edit.id, language, image_type ) end (result.images || []).map do |row| full_url = "#{row.url}=s0" # '=s0' param ensures full image size is returned (https://github.com/fastlane/fastlane/pull/14322#issuecomment-473012462) ImageListing.new(row.id, row.sha1, row.sha256, full_url) end end
# File supply/lib/supply/client.rb, line 302 def latest_version(track) latest_version = tracks.select { |t| t.track == Supply::Tracks::DEFAULT }.map(&:releases).flatten.reject { |r| r.name.nil? }.max_by(&:name) # Check if user specified '--track' option if version information from 'production' track is nil if latest_version.nil? && track == Supply::Tracks::DEFAULT UI.user_error!(%(Unable to find latest version information from "#{Supply::Tracks::DEFAULT}" track. Please specify track information by using the '--track' option.)) else latest_version = tracks.select { |t| t.track == track }.map(&:releases).flatten.reject { |r| r.name.nil? }.max_by(&:name) end return latest_version end
Get the list of Universal APKs generated by Google from the AAB for a particular version code
@param [Fixnum] version_code
Version code of the app bundle.
@raise [FastlaneError] (Google Api Error) If no APK was found for the provided ‘package_name` and `version_code` @return [Array<GeneratedUniversalApk>]
# File supply/lib/supply/client.rb, line 322 def list_generated_universal_apks(package_name:, version_code:) result = call_google_api { client.list_generatedapks(package_name, version_code) } result.generated_apks.map do |row| GeneratedUniversalApk.new(package_name, version_code, row.certificate_sha256_hash, row.generated_universal_apk.download_id) end end
Returns the listing for the given language filled with the current values if it already exists
# File supply/lib/supply/client.rb, line 234 def listing_for_language(language) ensure_active_edit! begin result = client.get_edit_listing( current_package_name, current_edit.id, language ) return Listing.new(self, language, result) rescue Google::Apis::ClientError => e return Listing.new(self, language) if e.status_code == 404 # create a new empty listing raise end end
Get a list of all languages - returns the list make sure to have an active edit
# File supply/lib/supply/client.rb, line 223 def listings ensure_active_edit! result = call_google_api { client.list_edit_listings(current_package_name, current_edit.id) } return result.listings.map do |row| Listing.new(self, row.language, row) end end
# File supply/lib/supply/client.rb, line 269 def release_listings(version) ensure_active_edit! # Verify that tracks have releases filtered_tracks = tracks.select { |t| !t.releases.nil? && t.releases.any? { |r| r.name == version } } if filtered_tracks.length > 1 # Prefer tracks in production, beta, alpha, internal order # E.g.: A release might've been promoted from Alpha/Beta track. This means the release will be present in two or more tracks filtered_tracks = filtered_tracks.sort_by { |t| Supply::Tracks::DEFAULTS.index(t.track) || Float::INFINITY } end filtered_track = filtered_tracks.first if filtered_track.nil? UI.user_error!("Unable to find version '#{version}' for '#{current_package_name}' in all tracks. Please double check the version number.") return nil else UI.message("Found '#{version}' in '#{filtered_track.track}' track.") end filtered_release = filtered_track.releases.first { |r| !r.name.nil? && r.name == version } # Since we can release on Internal/Alpha/Beta without release notes. if filtered_release.release_notes.nil? UI.message("Version '#{version}' for '#{current_package_name}' does not seem to have any release notes. Nothing to download.") return [] end return filtered_release.release_notes.map do |row| Supply::ReleaseListing.new(filtered_track, filtered_release.name, filtered_release.version_codes, row.language, row.text) end end
Get list of release names for track
# File supply/lib/supply/client.rb, line 492 def track_releases(track) ensure_active_edit! begin result = client.get_edit_track( current_package_name, current_edit.id, track ) return result.releases || [] rescue Google::Apis::ClientError => e return [] if e.status_code == 404 && e.to_s.include?("trackEmpty") raise end end
Get list of version codes for track
# File supply/lib/supply/client.rb, line 475 def track_version_codes(track) ensure_active_edit! begin result = client.get_edit_track( current_package_name, current_edit.id, track ) return result.releases.flat_map(&:version_codes) || [] rescue Google::Apis::ClientError => e return [] if e.status_code == 404 && (e.to_s.include?("trackEmpty") || e.to_s.include?("Track not found")) raise end end
Get a list of all tracks - returns the list
# File supply/lib/supply/client.rb, line 448 def tracks(*tracknames) ensure_active_edit! all_tracks = call_google_api { client.list_edit_tracks(current_package_name, current_edit.id) }.tracks all_tracks = [] unless all_tracks if tracknames.length > 0 all_tracks = all_tracks.select { |track| tracknames.include?(track.track) } end return all_tracks end
Updates or creates the listing for the specified language
# File supply/lib/supply/client.rb, line 353 def update_listing_for_language(language: nil, title: nil, short_description: nil, full_description: nil, video: nil) ensure_active_edit! listing = AndroidPublisher::Listing.new( language: language, title: title, full_description: full_description, short_description: short_description, video: video ) call_google_api do client.update_edit_listing( current_package_name, current_edit.id, language, listing ) end end
# File supply/lib/supply/client.rb, line 521 def update_obb(apk_version_code, expansion_file_type, references_version, file_size) ensure_active_edit! call_google_api do client.update_edit_expansionfile( current_package_name, current_edit.id, apk_version_code, expansion_file_type, AndroidPublisher::ExpansionFile.new( references_version: references_version, file_size: file_size ) ) end end
# File supply/lib/supply/client.rb, line 461 def update_track(track_name, track_object) ensure_active_edit! call_google_api do client.update_edit_track( current_package_name, current_edit.id, track_name, track_object ) end end
# File supply/lib/supply/client.rb, line 374 def upload_apk(path_to_apk) ensure_active_edit! result_upload = call_google_api do client.upload_edit_apk( current_package_name, current_edit.id, upload_source: path_to_apk ) end return result_upload.version_code end
# File supply/lib/supply/client.rb, line 388 def upload_apk_to_internal_app_sharing(package_name, path_to_apk) # NOTE: This Google API is a little different. It doesn't require an active edit. result_upload = call_google_api do client.uploadapk_internalappsharingartifact( package_name, upload_source: path_to_apk, content_type: "application/octet-stream" ) end return result_upload.download_url end
# File supply/lib/supply/client.rb, line 418 def upload_bundle(path_to_aab) ensure_active_edit! result_upload = call_google_api do client.upload_edit_bundle( current_package_name, self.current_edit.id, upload_source: path_to_aab, content_type: "application/octet-stream", ack_bundle_installation_warning: Supply.config[:ack_bundle_installation_warning] ) end return result_upload.version_code end
# File supply/lib/supply/client.rb, line 434 def upload_bundle_to_internal_app_sharing(package_name, path_to_aab) # NOTE: This Google API is a little different. It doesn't require an active edit. result_upload = call_google_api do client.uploadbundle_internalappsharingartifact( package_name, upload_source: path_to_aab, content_type: "application/octet-stream" ) end return result_upload.download_url end
# File supply/lib/supply/client.rb, line 508 def upload_changelogs(track, track_name) ensure_active_edit! call_google_api do client.update_edit_track( current_package_name, self.current_edit.id, track_name, track ) end end
Upload an image or screenshot of a specific type for a given language to your store listing
@param [String] image_type (e.g. phoneScreenshots, sevenInchScreenshots, …) @param [String] language localization code (i.e. BCP-47 language tag as in ‘pt-BR`)
# File supply/lib/supply/client.rb, line 571 def upload_image(image_path: nil, image_type: nil, language: nil) ensure_active_edit! call_google_api do client.upload_edit_image( current_package_name, current_edit.id, language, image_type, upload_source: image_path, content_type: 'image/*' ) end end
# File supply/lib/supply/client.rb, line 401 def upload_mapping(path_to_mapping, apk_version_code) ensure_active_edit! extension = File.extname(path_to_mapping).downcase call_google_api do client.upload_edit_deobfuscationfile( current_package_name, current_edit.id, apk_version_code, extension == ".zip" ? "nativeCode" : "proguard", upload_source: path_to_mapping, content_type: "application/octet-stream" ) end end
# File supply/lib/supply/client.rb, line 624 def upload_obb(obb_file_path: nil, apk_version_code: nil, expansion_file_type: nil) ensure_active_edit! call_google_api do client.upload_edit_expansionfile( current_package_name, current_edit.id, apk_version_code, expansion_file_type, upload_source: obb_file_path, content_type: 'application/octet-stream' ) end end
Validates the current edit - does not change data on Google Play
# File supply/lib/supply/client.rb, line 162 def validate_current_edit! ensure_active_edit! call_google_api { client.validate_edit(current_package_name, current_edit.id) } end
Private Instance Methods
# File supply/lib/supply/client.rb, line 641 def ensure_active_edit! UI.user_error!("You need to have an active edit, make sure to call `begin_edit`") unless @current_edit end