Class: Fastlane::GooglePlayTrackUpdater::GooglePlayClient

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlane/plugin/google_play_track_updater/client.rb

Constant Summary collapse

AndroidPublisher =
Google::Apis::AndroidpublisherV3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(json_file_path: nil, json_key_data: nil) ⇒ GooglePlayClient

Initializes a new GooglePlayClient instance with authentication credentials

Parameters:

  • json_file_path (String, nil) (defaults to: nil)

    Path to a file containing service account or external account JSON

  • json_key_data (String, nil) (defaults to: nil)

    Service account or external account JSON data as a string

Raises:

  • (FastlaneCore::Interface::FastlaneError)

    If neither or both authentication parameters are provided

  • (FastlaneCore::Interface::FastlaneError)

    If the JSON type is not ‘service_account’ or ‘external_account’



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
# File 'lib/fastlane/plugin/google_play_track_updater/client.rb', line 18

def initialize(json_file_path: nil, json_key_data: nil)
  env_credentials_path = ENV.fetch('GOOGLE_APPLICATION_CREDENTIALS', nil)

  if json_file_path.nil? && json_key_data.nil? && env_credentials_path.nil?
    UI.user_error!('Specify exactly one of \'json_file_path: \' or \'json_key_data: \' for service/external account authentication, or set GOOGLE_APPLICATION_CREDENTIALS environment variable.')
  end

   = nil
  if env_credentials_path
    UI.message("Using credentials from GOOGLE_APPLICATION_CREDENTIALS environment variable: #{env_credentials_path}")
     = File.open(File.expand_path(env_credentials_path))
  elsif json_file_path
    UI.message("Using credentials from json_file_path: #{json_file_path}")
     = File.open(File.expand_path(json_file_path))
  elsif json_key_data
    UI.message("Using credentials from json_key_data")
     = StringIO.new(json_key_data)
  end
   = JSON.parse(.read)
  .rewind

  case ['type']
  when 'external_account'
    auth_client = Google::Auth::ExternalAccount::Credentials.make_creds(json_key_io: , scope: AndroidPublisher::AUTH_ANDROIDPUBLISHER)
  when 'service_account'
    auth_client = Google::Auth::ServiceAccountCredentials.make_creds(json_key_io: , scope: AndroidPublisher::AUTH_ANDROIDPUBLISHER)
  else
    UI.user_error!("Invalid Google Credentials JSON: type: #{['type']} is not available.")
  end

  auth_client.fetch_access_token!

  service = AndroidPublisher::AndroidPublisherService.new
  service.authorization = auth_client
  self.android_publisher_service = service
end

Instance Attribute Details

#android_publisher_serviceObject

Returns the value of attribute android_publisher_service.



8
9
10
# File 'lib/fastlane/plugin/google_play_track_updater/client.rb', line 8

def android_publisher_service
  @android_publisher_service
end

Instance Method Details

#halt_release(package_name:, track:, version_name:) ⇒ Object

Halts an active staged rollout or completed release for a specific version on a Google Play track

Parameters:

  • package_name (String)

    The package name of the application (e.g., ‘com.example.app’)

  • track (String)

    The track of the application (production, beta, alpha, internal)

  • version_name (String)

    The version name to halt (e.g., ‘1.0.0’)

Raises:

  • (FastlaneCore::Interface::FastlaneError)

    If the release with the specified version is not found

  • (Google::Apis::Error)

    If the API request fails



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
# File 'lib/fastlane/plugin/google_play_track_updater/client.rb', line 62

def halt_release(package_name:, track:, version_name:)
  validate_inputs_release_status(package_name: package_name, track: track, version_name: version_name)

  begin
    edit = android_publisher_service.insert_edit(package_name)
    edit_id = edit.id

    current_track = android_publisher_service.get_edit_track(package_name, edit_id, track)

    target_releases = current_track.releases.select do |release|
      release.name == version_name
    end

    if target_releases.empty?
      UI.user_error!("Could not find a release with version '#{version_name}' on track: '#{track}'.")
    end

    is_halted = false

    target_releases.each do |release|
      next unless release.status == 'completed' || release.status == 'inProgress'

      release.status = 'halted'
      UI.message("Preparing to halt release for version '#{version_name}' on track: #{track}...")
      is_halted = true
    end

    if is_halted
      android_publisher_service.update_edit_track(package_name, edit_id, track, current_track)
      android_publisher_service.commit_edit(package_name, edit_id)
      UI.success("Successfully changed status to 'halted' for version '#{version_name}' on track: #{track}.")
    else
      UI.message("No releases found to halt for version '#{version_name}' on track: #{track}.")
    end
  rescue Google::Apis::Error => e
    UI.error!("Failed to halt release for version '#{version_name}' on track: #{track}. Google Api Error: #{e.message}")
  end
end

#resume_release(package_name:, track:, version_name:) ⇒ Object

Resumes a halted staged rollout for a specific version on a Google Play track

Changes the status from ‘halted’ to either ‘completed’ (if no user_fraction is set) or ‘inProgress’ (if user_fraction is set for staged rollout)

Parameters:

  • package_name (String)

    The package name of the application (e.g., ‘com.example.app’)

  • track (String)

    The track of the application (production, beta, alpha, internal)

  • version_name (String)

    The version name to resume (e.g., ‘1.0.0’)

Raises:

  • (FastlaneCore::Interface::FastlaneError)

    If the release with the specified version is not found

  • (Google::Apis::Error)

    If the API request fails



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
# File 'lib/fastlane/plugin/google_play_track_updater/client.rb', line 111

def resume_release(package_name:, track:, version_name:)
  validate_inputs_release_status(package_name: package_name, track: track, version_name: version_name)

  begin
    edit = android_publisher_service.insert_edit(package_name)
    edit_id = edit.id

    completed_changed = false
    in_progress_changed = false

    current_track = android_publisher_service.get_edit_track(package_name, edit_id, track)

    target_releases = current_track.releases.select do |release|
      release.name == version_name
    end

    if target_releases.empty?
      UI.user_error!("Could not find a release with version '#{version_name}' on track: '#{track}'.")
    end

    target_releases.each do |release|
      next unless release.status == 'halted'

      if release.user_fraction.nil?
        release.status = 'completed'
        completed_changed = true
      else
        release.status = 'inProgress'
        in_progress_changed = true
      end
      UI.message("Preparing to resume release for version '#{version_name}' on track: #{track}...")
    end

    if completed_changed || in_progress_changed
      android_publisher_service.update_edit_track(package_name, edit_id, track, current_track)
      android_publisher_service.commit_edit(package_name, edit_id)
      changed_release = if in_progress_changed
                          'inProgress'
                        elsif completed_changed
                          'completed'
                        end
      UI.success("Successfully changed status to #{changed_release || 'completed'} for version '#{version_name}' on track: #{track}.")
    else
      UI.message("No halted releases found for version '#{version_name}' on track: #{track}.")
    end
  rescue Google::Apis::Error => e
    UI.error!("Failed to resume release for '#{version_name}' on track: #{track}. Google Api Error: #{e.message}")
  end
end

#update_rollout(package_name:, track:, version_name:, user_fraction:) ⇒ Object

Updates the rollout percentage for a staged rollout on a Google Play track

Only updates releases with ‘inProgress’ status

Parameters:

  • package_name (String)

    The package name of the application (e.g., ‘com.example.app’)

  • track (String)

    The track of the application (production, beta, alpha, internal)

  • version_name (String)

    The version name to update (e.g., ‘1.0.0’)

  • user_fraction (Float)

    The rollout percentage as a fraction (0.0 to 1.0, exclusive). e.g., 0.1 for 10% rollout

Raises:

  • (FastlaneCore::Interface::FastlaneError)

    If the release with the specified version is not found

  • (FastlaneCore::Interface::FastlaneError)

    If user_fraction is not within the valid range (0.0, 1.0)

  • (Google::Apis::Error)

    If the API request fails



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
200
201
202
203
204
205
206
207
208
209
# File 'lib/fastlane/plugin/google_play_track_updater/client.rb', line 172

def update_rollout(package_name:, track:, version_name:, user_fraction:)
  validate_inputs_rollout(package_name: package_name, track: track, version_name: version_name, user_fraction: user_fraction)

  begin
    edit = android_publisher_service.insert_edit(package_name)
    edit_id = edit.id

    current_track = android_publisher_service.get_edit_track(package_name, edit_id, track)

    target_releases = current_track.releases.select do |release|
      release.name == version_name
    end

    if target_releases.empty?
      UI.user_error!("Could not find a release with version '#{version_name}' on track: '#{track}'.")
    end

    is_rollout_updated = false

    target_releases.each do |release|
      next unless release.status == 'inProgress'

      release.user_fraction = user_fraction.to_f
      UI.verbose("Preparing to update rollout to #{user_fraction} for version '#{version_name}' on track: #{track}...")
      is_rollout_updated = true
    end

    if is_rollout_updated
      android_publisher_service.update_edit_track(package_name, edit_id, track, current_track)
      android_publisher_service.commit_edit(package_name, edit_id)
      UI.success("Successfully updated rollout to #{user_fraction} for version '#{version_name}' on track: #{track}.")
    else
      UI.message("No inProgress releases found to update rollout for version '#{version_name}' on track: #{track}.")
    end
  rescue Google::Apis::Error => e
    UI.error!("Failed to update rollout for version '#{version_name}' on track: #{track}. Google Api Error: #{e.message}")
  end
end