Files
self/app/scripts/upload_to_play_store.py
Justin Hernandez b6d526e5f8 chore: update dev with staging 09/06/25 (#1007)
* update CI

* bump iOS version

* update readme

* update mobile-deploy ci

* bump version iOS

* update workflow to use workload identity federation (#933)

* update workflow to use workload identity federation

* add token permissions

* correct provider name

* chore: incrementing android build version for version 2.6.4 [github action]

---------

Co-authored-by: Self GitHub Actions <action@github.com>

* update ci

* update ci

* update ci

* update ci

* update ci

* fix ci

* fix ci

* fix ci

* remove fastlane use for android

* bump iOS build version

* update CI python script

* iterate on CI

* iterate on CI

* iterate on CI

* Dev (#941)

* SDK Go version (#920)

* feat: helper functions and constant for go-sdk

* feat: formatRevealedDataPacked in go

* chore: refactor

* feat: define struct for selfBackendVerifier

* feat: verify function for selfBackendVerifier

* feat(wip): custom hasher

* feat: SelfVerifierBacked in go

* test(wip): scope and userContextHash is failing

* test: zk proof verified

* fix: MockConfigStore getactionId function

* chore: refactor

* chore: remove abi duplicate files

* chore: move configStore to utils

* chore: modified VcAndDiscloseProof struct

* chore: more review changes

* feat: impl DefaultConfig and InMemoryConfigStore

* chore: refactor and export functions

* fix: module import and README

* chore: remove example folder

* chore: remove pointers from VerificationConfig

* chore: coderabbit review fixes

* chore: more coderabbit review fix

* chore: add license

* fix: convert attestationIdd to int

* chore: remove duplicate code

---------

Co-authored-by: ayman <aymanshaik1015@gmail.com>

* Moving proving Utils to common (#935)

* remove react dom

* moves proving utils to the common

* need to use rn components

* fix imports

* add proving-utils and dedeuplicate entry configs for esm and cjs.

* must wrap in text component

* fix metro bundling

* fix mock import

* fix builds and tests

* please save me

* solution?

* fix test

* Move proving inputs to the common package (#937)

* create ofactTree type to share

* move proving inputs from app to register inputs in common

* missed reexport

* ok

* add some validations as suggested by our ai overlords

* Fix mock passport flow (#942)

* fix dev screens

* add hint

* rename

* fix path

* fix mobile-ci path

* fix: extractMRZ (#938)

* fix: extractMRZ

* yarn nice && yarn types

* fix test: remove unused

* fix mobile ci

* add script

---------

Co-authored-by: Justin Hernandez <transphorm@gmail.com>

* Move Proving attest and cose (#950)

* moved attest and cose utils to common

with cursor converted tests in common to use vitest and converted coseVerify.test to vitest after moving from app to common

what does cryptoLoader do?

* moved away

* get buff

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* SELF-253 feat: add user email feedback (#889)

* feat: add sentry feedback

* add sentry feedback to web

* feat: add custom feedback modal & fix freeze on IOS

* yarn nice

* update lock

* feat: show feedback widget on NFC scan issues (#948)

* feat: show feedback widget on NFC scan issues

* fix ref

* clean up

* fix report issue screen

* abstract send user feedback email logic

* fixes

* change text to Report Issue

* sanitize email and track event messge

* remove unnecessary sanitization

* add sanitize error message tests

* fix tests

* save wip. almost done

* fix screen test

* fix screen test

* remove non working test

---------

Co-authored-by: Justin Hernandez <transphorm@gmail.com>
Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>

* chore: centralize license header checks (#952)

* chore: centralize license header scripts

* chore: run license header checks from root

* add header to other files

* add header to bundle

* add migration script and update check license headers

* convert license to mobile sdk

* migrate license headers

* remove headers from common; convert remaining

* fix headers

* add license header checks

* update unsupported passport screen (#953)

* update unsupported passport screen

* yarn nice

---------

Co-authored-by: Vishalkulkarni45 <109329073+Vishalkulkarni45@users.noreply.github.com>
Co-authored-by: ayman <aymanshaik1015@gmail.com>
Co-authored-by: Aaron DeRuvo <aaron.deruvo@clabs.co>
Co-authored-by: Justin Hernandez <justin.hernandez@self.xyz>
Co-authored-by: Seshanth.S🐺 <35675963+seshanthS@users.noreply.github.com>
Co-authored-by: Justin Hernandez <transphorm@gmail.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* bump version

* bump yarn.lock

* update ci (#966)

* chore: Manually bump and release v2.6.4 (#961)

* update lock files

* bump and build android

* update build artifacts

* show generate mock document button

* update lock

* fix formatting and update failing e2e test

* revert podfile

* fixes

* fix cold start of the app with deeplink

* update ci

* update ci

* Sync MARKETING_VERSION to iOS project files after version bump

* chore: incrementing android build version for version 2.6.4 [github action] (#976)

Co-authored-by: remicolin <98749896+remicolin@users.noreply.github.com>

* chore: add build dependencies step for iOS and Android in mobile deploy workflow

* chore: enhance mobile deploy workflow by adding CMake installation step

* bump android build version

* chore: incrementing android build version for version 2.6.4 [github action] (#985)

Co-authored-by: remicolin <98749896+remicolin@users.noreply.github.com>

* chore: configure Metro bundler for production compatibility in mobile deploy workflow

* chore: incrementing android build version for version 2.6.4 [github action] (#987)

Co-authored-by: remicolin <98749896+remicolin@users.noreply.github.com>

* Revert "chore: configure Metro bundler for production compatibility in mobile deploy workflow"

This reverts commit 60fc1f2580.

* reduce max old space size in mobile-deploy ci

* fix android french id card (#957)

* fix android french id card

* fix common ci cache

* feat: log apdu (#988)

---------

Co-authored-by: Justin Hernandez <transphorm@gmail.com>
Co-authored-by: Seshanth.S🐺 <35675963+seshanthS@users.noreply.github.com>

* unblock ci

* fix merge

* merge fixes

* fix tests

* make ci happy

---------

Co-authored-by: turnoffthiscomputer <colin.remi07@gmail.com>
Co-authored-by: pputman-clabs <99900942+pputman-clabs@users.noreply.github.com>
Co-authored-by: Self GitHub Actions <action@github.com>
Co-authored-by: turnoffthiscomputer <98749896+remicolin@users.noreply.github.com>
Co-authored-by: Vishalkulkarni45 <109329073+Vishalkulkarni45@users.noreply.github.com>
Co-authored-by: ayman <aymanshaik1015@gmail.com>
Co-authored-by: Aaron DeRuvo <aaron.deruvo@clabs.co>
Co-authored-by: Seshanth.S🐺 <35675963+seshanthS@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-09-07 11:19:59 -07:00

193 lines
7.1 KiB
Python

#!/usr/bin/env python3
"""
Upload Android AAB to Google Play Store using Workload Identity Federation
This script bypasses Fastlane and uses the Google Play Developer API directly
"""
import os
import sys
import json
import argparse
from pathlib import Path
try:
from google.oauth2 import service_account
from googleapiclient.discovery import build
from googleapiclient.http import MediaFileUpload
from google.auth import default
except ImportError:
print("❌ Error: Required packages not installed.")
print("Run: pip install google-auth google-auth-oauthlib google-auth-httplib2 google-api-python-client")
sys.exit(1)
def get_credentials():
"""Get credentials using ADC (Workload Identity Federation)"""
print("🔑 Authenticating using Application Default Credentials...")
try:
# Use the default() function which properly handles WIF
# This should work now that the audience is configured correctly
print("🔄 Using Google's default credential chain...")
credentials, project = default(scopes=['https://www.googleapis.com/auth/androidpublisher'])
print(f"✅ Authentication successful! Project: {project}")
print(f"🔍 Credential type: {type(credentials).__name__}")
# Ensure credentials are ready for use
if hasattr(credentials, 'refresh') and hasattr(credentials, 'valid') and not credentials.valid:
print("🔄 Refreshing credentials...")
import google.auth.transport.requests
request = google.auth.transport.requests.Request()
credentials.refresh(request)
print("✅ Credentials refreshed successfully")
return credentials
except Exception as e:
print(f"❌ Authentication failed: {e}")
print(f"❌ Error type: {type(e).__name__}")
# Debug information
creds_file = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
if creds_file:
print(f"🔍 Credentials file: {creds_file}")
if os.path.exists(creds_file):
try:
with open(creds_file, 'r') as f:
creds_info = json.load(f)
print(f"🔍 Credential type in file: {creds_info.get('type', 'unknown')}")
if 'audience' in creds_info:
print(f"🔍 Credential audience: {creds_info['audience']}")
except:
print("🔍 Could not read credentials file content")
else:
print("🔍 Credentials file does not exist")
else:
print("🔍 GOOGLE_APPLICATION_CREDENTIALS not set")
sys.exit(1)
def should_hold_for_manual_review(track):
"""
Determine if changes should be held for manual review based on track type.
Returns True only for production releases or when you need manual control.
For internal, alpha, beta tracks, changes are automatically sent for review.
"""
# Only hold for manual review on production track
# For other tracks (internal, alpha, beta), let changes go for automatic review
return track == 'production'
def upload_to_play_store(aab_path, package_name, track, credentials):
"""Upload AAB to Google Play Store"""
print(f"📤 Uploading {aab_path} to Play Store...")
try:
# Build the service
service = build('androidpublisher', 'v3', credentials=credentials)
# Create an edit
print("🚀 Creating edit transaction...")
edit_request = service.edits().insert(body={}, packageName=package_name)
edit = edit_request.execute()
edit_id = edit['id']
print(f"✅ Edit created: {edit_id}")
# Upload the AAB
print("📦 Uploading AAB file...")
media = MediaFileUpload(aab_path, mimetype='application/octet-stream')
upload_request = service.edits().bundles().upload(
packageName=package_name,
editId=edit_id,
media_body=media
)
bundle_response = upload_request.execute()
version_code = bundle_response['versionCode']
print(f"✅ AAB uploaded. Version code: {version_code}")
# Assign to track
print(f"🎯 Assigning to track: {track}")
track_request = service.edits().tracks().update(
packageName=package_name,
editId=edit_id,
track=track,
body={
'track': track,
'releases': [{
'versionCodes': [str(version_code)],
'status': 'completed'
}]
}
)
track_response = track_request.execute()
print(f"✅ Assigned to track: {track_response['track']}")
# Commit the edit
print("💾 Committing changes...")
# Determine if we should hold changes for manual review
hold_for_manual_review = should_hold_for_manual_review(track)
if hold_for_manual_review:
# For production or when manual review is needed
commit_request = service.edits().commit(
packageName=package_name,
editId=edit_id,
changesNotSentForReview=True
)
commit_response = commit_request.execute()
print(f"✅ Upload completed successfully! Edit ID: {commit_response['id']}")
print(f"📝 Note: Changes committed but held for manual review (production track)")
else:
# For internal, alpha, beta tracks - let changes go for automatic review
commit_request = service.edits().commit(
packageName=package_name,
editId=edit_id
)
commit_response = commit_request.execute()
print(f"✅ Upload completed successfully! Edit ID: {commit_response['id']}")
print(f"📝 Note: Changes committed and sent for automatic review ({track} track)")
return True
except Exception as e:
print(f"❌ Upload failed: {e}")
return False
def main():
parser = argparse.ArgumentParser(description='Upload Android AAB to Google Play Store using WIF')
parser.add_argument('--aab', required=True, help='Path to the AAB file')
parser.add_argument('--package-name', required=True, help='Android package name')
parser.add_argument('--track', default='internal', help='Release track (internal, alpha, beta, production)')
args = parser.parse_args()
# Validate AAB file exists
aab_path = Path(args.aab)
if not aab_path.exists():
print(f"❌ Error: AAB file not found: {aab_path}")
sys.exit(1)
print("🚀 Starting Google Play Store upload with Workload Identity Federation")
print(f"📦 AAB: {aab_path}")
print(f"📱 Package: {args.package_name}")
print(f"🎯 Track: {args.track}")
print()
# Get credentials and upload
credentials = get_credentials()
success = upload_to_play_store(str(aab_path), args.package_name, args.track, credentials)
if success:
print("\n🎉 Upload completed successfully!")
sys.exit(0)
else:
print("\n💥 Upload failed!")
sys.exit(1)
if __name__ == '__main__':
main()