इस लेख में, मैं समझाने जा रहा हूं कि Android App Bundle (.aab फाइल) को Play Store के बीटा ट्रैक पर स्वचालित रूप से कैसे अपलोड किया जाए। हम Android Studio और AWS का उपयोग क्लाउड इंफ्रास्ट्रक्चर प्रदाता के रूप में करेंगे।
एक बार जब हम ऐप बंडल अपलोड कर देते हैं, तो हम एक Slack नोटिफिकेशन ट्रिगर करेंगे।
यह आपके समय का एक मूल्यवान उपयोग है कई कारणों से, जैसे ऑब्जर्वेबिलिटी बनाना और प्रक्रियाओं को प्राथमिकता देना।
हम जिस तकनीक का उपयोग करेंगे
यहां वे संसाधन हैं जिनका हम इस ट्यूटोरियल के लिए उपयोग करने जा रहे हैं:
- Android Studio
- AWS CodeBuild
- AWS Lambda
- S3
- Slack
परियोजना का उच्च-स्तरीय अवलोकन

उपरोक्त छवि आपको दिखाती है कि हम पूरी चीज को कैसे संरचित करेंगे इसका एक सामान्य अवलोकन।
अनिवार्य रूप से, आपके Android रिपॉजिटरी के लिए AWS पर एक Code Pipeline सेट अप होना आवश्यक है। इस Code Pipeline में Code Build इसके चरणों में से एक के रूप में होगा।
आपके Android ऐप रिपॉजिटरी के मास्टर ब्रांच पर पुश करने से Code Build ट्रिगर होगा। Code Build प्रोजेक्ट कमांड लाइन से Android ऐप पर हस्ताक्षर करेगा और आर्टिफैक्ट को S3 बकेट में अपलोड करेगा।
बंडल को S3 पर अपलोड करने से एक Lambda ट्रिगर होगा, जो बंडल को डाउनलोड करेगा और Google Publishing API का उपयोग करके इसे Play Store पर अपलोड करेगा। एक बार 200 प्रतिक्रिया मिलने पर, Lambda फिर एक Slack नोटिफिकेशन ट्रिगर करेगा।
अपना Google Play सर्विस अकाउंट कुंजी कैसे प्राप्त करें
Google Play Publisher API का उपयोग करने में सक्षम होने के लिए, आपको एक Google Play सर्विस अकाउंट कुंजी की आवश्यकता होगी।
एक सर्विस अकाउंट एक ऐसा अकाउंट है जो सर्वर एक-दूसरे के साथ संचार कर रहे हैं जब आपकी ओर से कार्य कर सकता है। आप यहां पढ़ सकते हैं कि Google सर्वर-टू-सर्वर संचार के लिए OAuth2.0 का उपयोग कैसे करता है।
सर्विस अकाउंट बनाने और इसे Google Play Publisher API तक पहुंच देने का तरीका देखने के लिए, यहां देखें।
एक बार जब आप अपना सर्विस अकाउंट बना लेते हैं और इसे उचित अनुमतियां दे देते हैं, तो सर्विस अकाउंट कुंजी डाउनलोड करना और इसे सुरक्षित रखना सुनिश्चित करें। आप इसे जल्द ही S3 बकेट में अपलोड करेंगे।
Android बंडल पर हस्ताक्षर कैसे करें
मुख्य बात यह पता लगाना है कि Android App Bundle पर हस्ताक्षर कैसे करें। Google के पास इस पर काफी अच्छी डॉक्यूमेंटेशन है जिसे आप यहां पा सकते हैं।
मैं नीचे दिए गए लिंक को संक्षेप में प्रस्तुत करूंगा।
keytool का उपयोग करके एक निजी कुंजी जनरेट करें जैसे:
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-alias आप अपनी कुंजी को जो चाहें नाम दे सकते हैं। यहां, मैंने इसे my-release-key.jks कहा। आप जो चाहें उपनाम भी चुन सकते हैं। इस ट्यूटोरियल के दौरान अपनी कुंजी के लिए सही नाम और उपनाम का उपयोग करना सुनिश्चित करें।
Android Studio में अपने app डायरेक्टरी के भीतर build.gradle खोलें और इसमें निम्न कोड ब्लॉक जोड़ें:
android { ... defaultConfig { ... } signingConfigs { release { // आपको या तो एक पूर्ण पथ निर्दिष्ट करना होगा या // keystore फाइल को build.gradle फाइल के समान डायरेक्टरी में शामिल करना होगा। storeFile file("my-release-key.jks") storePassword "password" keyAlias "my-alias" keyPassword "password" } } buildTypes { release { signingConfig signingConfigs.release ... } } } यदि आपने अपने रिलीज कुंजी का नाम डिफ़ॉल्ट के अलावा कुछ और बदल दिया है, तो नया नाम निर्दिष्ट करना सुनिश्चित करें। उपनाम के लिए भी यही बात लागू होती है।
आपका स्टोर पासवर्ड वह पासवर्ड होगा जो आपने पहली बार अपना ऐप Play Store पर अपलोड करते समय जनरेट किया था।
अब, जब आप Android Studio में कमांड लाइन से ./gradlew :app:bundleRelease कमांड चलाते हैं, तो आप देखेंगे कि यह एक साइन किया हुआ App Bundle जनरेट करता है।
हस्ताक्षर जानकारी को कैसे साफ़ करें
build.gradle फाइल में साइनिंग जानकारी को प्लेन टेक्स्ट के रूप में उपलब्ध कराकर कोड कमिट करना एक सुरक्षा जोखिम है और यह एक अटैक वेक्टर हो सकता है।
Google के पास इसके आसपास डॉक्यूमेंटेशन है जिसे आप यहां पा सकते हैं।
सबसे पहले, अपने प्रोजेक्ट डायरेक्टरी की जड़ में keystore.properties फाइल बनाएं।
फाइल की सामग्री नीचे दी गई होनी चाहिए:
storePassword=myStorePassword keyPassword=myKeyPassword keyAlias=myKeyAlias storeFile=myStoreFileLocation आपका स्टोर पासवर्ड और कुंजी पासवर्ड वह पासवर्ड होगा जिसका उपयोग आपने पहली बार अपना ऐप बंडल App Store पर अपलोड करते समय किया था।
आपका keyAlias और storeFile क्रमशः आपके द्वारा अपनी निजी कुंजी बनाते समय असाइन किया गया उपनाम और आपके द्वारा बनाई गई निजी कुंजी का स्थान होगा।
अब, हमें इस फाइल को build.gradle में लोड करने की आवश्यकता है। यह मेरे लिए शुरुआत में एक आश्चर्य के रूप में आया, लेकिन Gradle वास्तव में DSL के रूप में काम करता है। इसलिए, यह Gradle का उपयोग करके कॉन्फिगरेशन लिखना आसान बनाता है।
// keystore.properties से प्रॉपर्टी लोड करें def keystorePropertiesFile = rootProject.file("keystore.properties") // एक नया Properties() ऑब्जेक्ट बनाएं def keystoreProperties = new Properties() // यदि keystorePropertiesFile मौजूद है, तो उससे पढ़ें, अन्यथा बिल्ड एनवायरनमेंट से सेट करें if (keystorePropertiesFile.exists()) { // keystoreProperties फाइल लोड करें keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) } else { // बिल्ड एनवायरनमेंट से सभी एनवायरनमेंट वेरिएबल पढ़ें keystoreProperties.setProperty("storeFile", "${System.getenv('STORE_FILE')}") keystoreProperties.setProperty("keyAlias", "${System.getenv('KEY_ALIAS')}") keystoreProperties.setProperty("keyPassword", "${System.getenv('KEY_PASSWORD')}") keystoreProperties.setProperty("storePassword", "${System.getenv('STORE_PASSWORD')}") } आप वहां if कंडीशन देखेंगे – अभी इसके बारे में चिंता न करें। यह विशेष रूप से बाद में Code Build के लिए है।
एक बार जब आप ऐसा कर लेते हैं, तो build.gradle में अपने signingConfigs अनुभाग को इस तरह दिखने के लिए बदलें:
signingConfigs { release { storeFile file(keystoreProperties['storeFile']) keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storePassword keystoreProperties['storePassword'] } } AWS Code Pipeline कैसे सेट अप करें
मैं इसमें बहुत अधिक विस्तार से नहीं जाऊंगा क्योंकि यह अपेक्षाकृत सीधा है।
निम्नलिखित तीन चरणों के साथ एक AWS Code Pipeline सेट अप करें:
- स्रोत चरण जो आपके GitHub रिपॉजिटरी के
masterब्रांच से जुड़ा हुआ है - बिल्ड चरण जो AWS Code Build से जुड़ा हुआ है
- डेप्लॉय चरण जो S3 बकेट पर डेप्लॉय करेगा।
Code Pipeline सेट अप करने के बारे में अधिक डॉक्यूमेंटेशन आप यहां पा सकते हैं।
AWS S3 कैसे सेट अप करें
सबसे पहले, सुनिश्चित करें कि आपके पास Code Build को इसके चरणों में से एक के रूप में रखने वाला एक Code Pipeline सेट अप है। अगला, दो S3 बकेट सेट अप करें:
- अपनी रिलीज कुंजी स्टोर करने के लिए एक बकेट। मैं इस बकेट को
release-key.jksकह रहा हूं - एक बकेट जिसमें आप अपना Google Play सर्विस अकाउंट निजी कुंजी स्टोर करेंगे। (आपको यह कुंजी अपने सर्विस अकाउंट बनाते समय डाउनलोड करनी चाहिए थी।)
आपको अपने Code Build सर्विस रोल से इन बकेट तक पहुंच की अनुमति देनी होगी। आपका Code Build सर्विस रोल आपके Code Pipeline सेट अप करते समय बनाया गया होना चाहिए।
IAM कंसोल पर जाएं और अपना Code Build सर्विस रोल ढूंढें और ARN लें।
अगला, कंसोल का उपयोग करके बकेट release-key.jks के Permissions टैब पर जाएं और वहां निम्नलिखित नीति जोड़ें:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": [ "arn:aws:iam::123456789:role/service-role/codebuild-service-role-dummy", ] }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::release-key-bucket/*" } ] } यह नीति उस मशीन से S3 बकेट तक पहुंच की अनुमति देगी जहां आपका CodeBuild प्रोजेक्ट निष्पादित होगा।
आपको उपरोक्त उल्लिखित ARN को अपने खाते के ARN से बदलना होगा। Code Build सर्विस रोल के लिए सही ARN निर्दिष्ट करना सुनिश्चित करें जब आप नीति अपडेट कर रहे हों।
दूसरे बकेट के लिए अनुमति नीति बदलने की आवश्यकता नहीं है। हम AWS Lambda रोल में प्रासंगिक अनुमतियां जोड़कर इसे बकेट तक पहुंचने की अनुमति देंगे।
AWS CodeBuild कैसे सेट अप करें
अगला, अपने प्रोजेक्ट रूट फोल्डर में buildspec.yml फाइल बनाएं।
version: 0.2 phases: build: commands: - aws s3api get-object --bucket release-key.jks --key release-key.jks ./releaseKey.jks - cp ./releaseKey.jks ${CODEBUILD_SRC_DIR}/app/releaseKey.jks - export STORE_FILE=releaseKey.jks - export KEY_ALIAS=$keyAlias - export KEY_PASSWORD=$keyPassword - export STORE_PASSWORD=$storePassword - ./gradlew :app:bundleRelease artifacts: files: - app/build/outputs/bundle/release/app-release.aab यह फाइल काफी सरल है। यह निर्दिष्ट बकेट से रिलीज कुंजी लाता है और इसे Code Build सर्वर पर निर्दिष्ट स्थान पर एक स्थानीय फाइल में सहेजता है।
अगला, build.gradle कॉन्फिगरेशन को सही ढंग से काम करने के लिए आवश्यक सभी वेरिएबल एक्सपोर्ट करें। अंत में, कमांड लाइन से Gradle का रिलीज कमांड चलाएं।
इस स्क्रिप्ट को Code Build में चलाने से पहले, आपको वेरिएबल को Code Build एनवायरनमेंट में जोड़ना होगा। ऐसा करने के लिए, पहले AWS Code Build कंसोल पर जाएं और अपने Android ऐप के लिए अपना बिल्ड प्रोजेक्ट चुनें।
अगला, नीचे स्क्रीनशॉट की तरह Edit > Environment चुनें:

एक बार ऐसा करने पर दिखाई देने वाली स्क्रीन पर, Additional Configuration ड्रॉपडाउन चुनें। वहां आपको की-वैल्यू जोड़े के माध्यम से एनवायरनमेंट वेरिएबल जोड़ने का विकल्प दिखाई देगा।
जैसा कि अभी चीजें खड़ी हैं, जब आपकी पाइपलाइन चलती है, Code Build आपके Android ऐप को साइन और बिल्ड करने के लिए निजी कुंजी डाउनलोड कर सकेगा और साइन किए गए बंडल को S3 बकेट पर अपलोड करेगा।
Slack ऐप कैसे सेट अप करें
ऑब्जर्वेबिलिटी ऑटोमेशन की पहचान है। आप जानना चाहते हैं कि आपका ऑटोमेशन कब चलता है, चाहे वह सफल हो या विफल, और यदि यह विफल होता है, तो विफलता का कारण।
AWS आमतौर पर CloudWatch के माध्यम से ऑब्जर्वेबिलिटी को संभालता है। लेकिन मुझे लगता है कि Slack एकीकरण उद्देश्य की पूर्ति करता है।
अपने ऑटोमेशन वर्कफ़्लो में Slack को एकीकृत करने का सबसे आसान तरीका एक Slack ऐप सेट अप करना है और उस ऐप को अपने ऑटोमेशन वर्कफ़्लो से नोटिफिकेशन भेजना है।
Slack ऐप सेट अप करने का तरीका जानने के लिए, यहां डॉक्यूमेंटेशन देखें। प्रक्रिया सुपर आसान है और आपके पास कुछ मिनटों में एक ऐप चालू और चल रहा होना चाहिए।
एक बार जब आप ऐप बना लेते हैं, तो आपको एक WebHook URL मिलेगा जिसका उपयोग आप ऐप को संबंधित चैनल में पोस्ट करने के लिए कॉल करने के लिए कर सकते हैं। इस WebHook URL को ट्रैक करके रखें क्योंकि हम इसे AWS Lambda फंक्शन के साथ उपयोग करेंगे।
AWS Lambda कैसे सेट अप करें
अब तक, हमारे पास एक Android App Bundle है जिसे साइन, बिल्ड और S3 बकेट पर अपलोड किया गया है। अगला, हमें यह पता लगाना होगा कि बंडल को Play Store पर बीटा ट्रैक पर कैसे अपलोड किया जाए।
ऐसा करने का तरीका एक AWS Lambda सेट अप करना है जो बकेट पर बंडल अपलोड होने पर ट्रिगर होगा। जब यह ट्रिगर होता है, तो Lambda चलेगा, बंडल डाउनलोड करेगा, सर्विस अकाउंट कुंजी लेगा, और बंडल को Play Store बीटा ट्रैक पर अपलोड करेगा।
एक बार जब आप एक Lambda बना लेते हैं और बकेट पर फाइल अपलोड होने पर इसे चलाने के लिए ट्रिगर जोड़ते हैं, तो नीचे दिए गए कोड को देखें:
"""यह Python3 स्क्रिप्ट प्ले स्टोर पर एक नया .aab बंडल अपलोड करने के लिए उपयोग की जाती है। इस Python स्क्रिप्ट का निष्पादन AWS Lambda के माध्यम से होता है जिसे तब आमंत्रित किया जाता है जब एक नई फाइल प्रासंगिक S3 बकेट पर अपलोड की जाती है""" import json import boto3 import os from urllib import request, parse from google.oauth2 import service_account import googleapiclient.discovery # प्राधिकरण अनुरोध का दायरा परिभाषित करें SCOPES = ['https://www.googleapis.com/auth/androidpublisher'] # ऐप के लिए पैकेज नाम package_name = 'com.app.name' # Slack webhook URL परिभाषित करें slack_webhook_url = os.environ['SLACK_WEBHOOK_URL'] def send_slack_message(message): data = json.dumps({ 'text': message }) post_data = data.encode('utf-8') req = request.Request(slack_webhook_url, data=post_data, headers={ 'Content-Type': 'application/json' }) request.urlopen(req) # यह मुख्य हैंडलर फंक्शन है def lambda_handler(event, context): # एक नया S3 क्लाइंट बनाएं और बकेट से सही फाइल डाउनलोड करें s3 = boto3.client('s3') s3.download_file('service-account-bucket-key', 'service-account-bucket-key.json', '/tmp/service-account-key.json') SERVICE_ACCOUNT_FILE = '/tmp/service-account-key.json' # ऐप-रिलीज.aab फाइल डाउनलोड करें जिसने Lambda को ट्रिगर किया bucket_name = event['Records'][0]['s3']['bucket']['name'] file_key = event['Records'][0]['s3']['object']['key'] s3.download_file(bucket_name, file_key, '/tmp/app-release.aab') APP_BUNDLE = '/tmp/app-release.aab' print(f"A bundle uploaded to {bucket_name} has triggered the Lambda") # एक क्रेडेंशियल ऑब्जेक्ट बनाएं और क्रेडेंशियल ऑब्जेक्ट का उपयोग करके एक सर्विस ऑब्जेक्ट बनाएं credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=SCOPES ) service = googleapiclient.discovery.build('androidpublisher', 'v3', credentials=credentials, cache_discovery=False) # सर्विस ऑब्जेक्ट का उपयोग करके एक एडिट अनुरोध बनाएं और editId प्राप्त करें edit_request = service.edits().insert(body={}, packageName=package_name) result = edit_request.execute() edit_id = result['id'] # ऐप बंडल अपलोड करने के लिए एक अनुरोध बनाएं try: bundle_response = service.edits().bundles().upload( editId=edit_id, packageName=package_name, media_body=APP_BUNDLE, media_mime_type="application/octet-stream" ).execute() except Exception as err: message = f"There was an error while uploading a new version of {package_name}" send_slack_message(message) raise err print(f"Version code {bundle_response['versionCode']} has been uploaded") # बंडल को बीटा ट्रैक पर अपलोड करने के लिए एक ट्रैक अनुरोध बनाएं track_response = service.edits().tracks().update( editId=edit_id, track='beta', packageName=package_name, body={u'releases': [{ u'versionCodes': [str(bundle_response['versionCode'])], u'status': u'completed', }]} ).execute() print("The bundle has been committed to the beta track") # BETA ट्रैक पर एडिट को कमिट करने के लिए एक कमिट अनुरोध बनाएं commit_request = service.edits().commit( editId=edit_id, packageName=package_name ).execute() print(f"Edit {commit_request['id']} has been committed") message = f"Version code {bundle_response['versionCode']} has been uploaded from the bucket {bucket_name}.\nEdit {commit_request['id']} has been committed" send_slack_message(message) return { 'statusCode': 200, 'body': json.dumps('Successfully executed the app bundle release to beta') } उपरोक्त Lambda googleapiclient लाइब्रेरी और इसके डिस्कवरी मॉड्यूल का उपयोग Google Play के Publishing API के लिए URL बनाने के लिए करेगा।
अगला, Lambda पहले सेट अप किए गए बकेट से सर्विस अकाउंट कुंजी डाउनलोड करेगा। आपको सही बकेट नाम निर्दिष्ट करने होंगे।
चाहे अपलोड सफल हो या विफल, हम एक Slack संदेश भेजना चाहते हैं। पिछले अनुभाग से Slack WebHook URL को Lambda के एनवायरनमेंट वेरिएबल में जोड़ें। उपरोक्त फंक्शन एनवायरनमेंट वेरिएबल तक पहुंचने और Slack पर संदेश पोस्ट करने के लिए Python के os मॉड्यूल का उपयोग करता है।
यदि आपका Lambda विफल होता है, तो ऐसा इसलिए हो सकता है क्योंकि आपके Lambda के पास S3 बकेट तक पहुंचने की अनुमति नहीं है जहां आपके Google Play सर्विस अकाउंट की कुंजी संग्रहीत है। उस स्थिति में, आपको इसका संकेत देने वाला एक त्रुटि संदेश दिखाई देगा।
इसे ठीक करने के लिए, आपको बस अपने Lambda रोल में प्रासंगिक अनुमतियां जोड़नी होंगी।
यहां वह नीति है जिसे आपको जोड़ना होगा:
{ "Version": "2012-10-07", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObjectVersion", "s3:GetBucketVersioning", "s3:GetBucketAcl", "s3:GetObject", "s3:GetBucketTagging", "s3:GetBucketLocation", "s3:GetObjectVersionAcl" ], "Resource": [ "arn:aws:s3:::arn:aws:s3:::your-bucket-name-with-service-account-key" ] } ] } अपने खाते के लिए प्रासंगिक बकेट के ARN से ARN को बदलें और आप जाने के लिए तैयार होंगे।
निष्कर्ष
तो, वहां आपके पास है। यह निश्चित रूप से आसान नहीं था और इसमें कई चलते हुए हिस्से हैं, लेकिन यह एक ऑटोमेशन है जो आपका बहुत समय और प्रयास बचाएगा।
यदि आप एक टीम का हिस्सा हैं जो अक्सर नए ऐप अपडेट जारी करती है, तो आप नहीं चाहते कि एक व्यक्ति की अनुपस्थिति से बाधित हों जिसका काम अपडेट जारी करना है।
इस तरह का ऑटोमेशन बनाने से आपका CI/CD वर्कफ़्लो बहुत आसान और मजबूत हो जाता है।
यदि आप इस तरह के ब्लॉग में रुचि रखते हैं, तो आप https://redixhumayun.github.io पर अधिक पढ़ सकते हैं या मुझे Twitter पर फॉलो कर सकते हैं।