feat(playstore): also publish AAB to closed-testing (alpha) track
Adds the closed-testing (alpha) track to scripts/deploy_playstore.py so every CI publish lands in both internal and closed testing within the same Play edit, removing the manual "Drop app bundles here" step in the Play Console. Closes #535 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
8592bba9e3
commit
b45104f2eb
+1
-1
@@ -544,7 +544,7 @@ tasks:
|
||||
- sops exec-env secrets.enc.yaml 'bash scripts/build_android_bundle_local.sh'
|
||||
|
||||
deploy-android-bundle:
|
||||
desc: Build release AAB and upload to Play Store internal track (local/fvm)
|
||||
desc: Build release AAB and upload to Play Store internal + closed-testing tracks (local/fvm)
|
||||
deps: [build-android-bundle-local]
|
||||
dotenv: [".env"]
|
||||
cmds:
|
||||
|
||||
+1
-1
@@ -896,7 +896,7 @@ func withGoCache(c *dagger.Container) *dagger.Container {
|
||||
WithEnvVariable("GOMODCACHE", "/home/ci/go/pkg/mod")
|
||||
}
|
||||
|
||||
// UploadToPlayStore uploads a pre-built AAB to the Play Store internal track.
|
||||
// UploadToPlayStore uploads a pre-built AAB to the Play Store internal and closed-testing (alpha) tracks.
|
||||
func (m *Ci) UploadToPlayStore(
|
||||
ctx context.Context,
|
||||
aab *dagger.File,
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Upload an Android App Bundle to the Google Play Store internal track."""
|
||||
"""Upload an Android App Bundle to the Google Play Store.
|
||||
|
||||
The bundle is published to every track in ``TRACKS`` within a single Play edit,
|
||||
so internal testing and closed testing share the same version code. ``alpha``
|
||||
is what the Play Console labels "Closed testing"; publishing there removes the
|
||||
need to manually drag-and-drop the AAB into the closed-testing release form.
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
@@ -11,7 +17,7 @@ from google.oauth2 import service_account
|
||||
|
||||
PACKAGE_NAME = "de.sharedinbox.mua"
|
||||
AAB_PATH = "build/app/outputs/bundle/release/app-release.aab"
|
||||
TRACK = "internal"
|
||||
TRACKS = ("internal", "alpha")
|
||||
_BASE = "https://androidpublisher.googleapis.com/androidpublisher/v3/applications"
|
||||
_UPLOAD_BASE = "https://androidpublisher.googleapis.com/upload/androidpublisher/v3/applications"
|
||||
_MAX_UPLOAD_ATTEMPTS = 3
|
||||
@@ -94,19 +100,20 @@ def main():
|
||||
version_code = bundle["versionCode"]
|
||||
print(f"Uploaded AAB, version code: {version_code}")
|
||||
|
||||
track_resp = session.put(
|
||||
f"{_BASE}/{PACKAGE_NAME}/edits/{edit_id}/tracks/{TRACK}",
|
||||
json={"releases": [{"versionCodes": [version_code], "status": "completed"}]},
|
||||
timeout=30,
|
||||
)
|
||||
track_resp.raise_for_status()
|
||||
for track in TRACKS:
|
||||
track_resp = session.put(
|
||||
f"{_BASE}/{PACKAGE_NAME}/edits/{edit_id}/tracks/{track}",
|
||||
json={"releases": [{"versionCodes": [version_code], "status": "completed"}]},
|
||||
timeout=30,
|
||||
)
|
||||
track_resp.raise_for_status()
|
||||
|
||||
commit_resp = session.post(
|
||||
f"{_BASE}/{PACKAGE_NAME}/edits/{edit_id}:commit",
|
||||
timeout=30,
|
||||
)
|
||||
commit_resp.raise_for_status()
|
||||
print(f"Deployed version {version_code} to {TRACK} track")
|
||||
print(f"Deployed version {version_code} to tracks: {', '.join(TRACKS)}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -95,6 +95,30 @@ class TestMainHappyPath(unittest.TestCase):
|
||||
track_call = session.put.call_args_list[0]
|
||||
self.assertIn("/tracks/", track_call[0][0])
|
||||
|
||||
def test_updates_all_configured_tracks(self):
|
||||
session = self._run_main()
|
||||
track_urls = [c[0][0] for c in session.put.call_args_list]
|
||||
self.assertEqual(len(track_urls), len(deploy_playstore.TRACKS))
|
||||
for track in deploy_playstore.TRACKS:
|
||||
self.assertTrue(
|
||||
any(url.endswith(f"/tracks/{track}") for url in track_urls),
|
||||
f"no PUT to /tracks/{track} (saw {track_urls})",
|
||||
)
|
||||
|
||||
def test_commits_after_all_track_updates(self):
|
||||
session = self._run_main()
|
||||
# All PUTs are track updates; commit is the second POST after the
|
||||
# initial edit-create. Verify PUTs precede the commit by checking
|
||||
# mock_calls order across both methods.
|
||||
method_order = [c[0] for c in session.method_calls]
|
||||
commit_idx = next(
|
||||
i for i, m in enumerate(method_order)
|
||||
if m == "post" and ":commit" in session.method_calls[i][1][0]
|
||||
)
|
||||
put_indices = [i for i, m in enumerate(method_order) if m == "put"]
|
||||
self.assertEqual(len(put_indices), len(deploy_playstore.TRACKS))
|
||||
self.assertTrue(all(i < commit_idx for i in put_indices))
|
||||
|
||||
|
||||
class TestUploadRetry(unittest.TestCase):
|
||||
def _run_main(self, upload_side_effects, sleep_mock=None):
|
||||
|
||||
Reference in New Issue
Block a user