diff --git a/Taskfile.yml b/Taskfile.yml index 9279b97..31d8080 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -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: diff --git a/ci/main.go b/ci/main.go index b3c07df..53f6867 100644 --- a/ci/main.go +++ b/ci/main.go @@ -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, diff --git a/scripts/deploy_playstore.py b/scripts/deploy_playstore.py index 7282fd1..2eac4e3 100755 --- a/scripts/deploy_playstore.py +++ b/scripts/deploy_playstore.py @@ -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__": diff --git a/scripts/test_deploy_playstore.py b/scripts/test_deploy_playstore.py index 352cf5c..7c0d6d6 100644 --- a/scripts/test_deploy_playstore.py +++ b/scripts/test_deploy_playstore.py @@ -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):