From GitHub to Google Play: The Android Release Gauntlet
The technical and bureaucratic journey to ship an Android app on Google Play — including the gotchas that trip up most first-time developers.
There’s a significant gap between having a working Android app and having one that can generate revenue on Google Play. The technical part — building and signing an app — is straightforward. The process of actually getting it into production, however, is a minefield of quirks, restrictions, and requirements that aren’t immediately obvious from the documentation.
I’m going to walk through the full workflow from GitHub initialization to your first sale, with an emphasis on the things that commonly derail developers the first time.
1. Repository & Environment Setup: The .gitignore Gotcha
You’ll want to initialize a new repository on GitHub. But Android projects have a critical security consideration that trips up many developers: your signing keystore (the .jks file) and release signing credentials must never, ever be committed to the repository.
Create a .gitignore specifically tailored for Android:
# Build outputs
build/
.gradle/
*.apk
*.aab
# Signing credentials
*.jks
*.keystore
local.properties
gradle.properties
# IDE
.idea/
*.iml
.vscode/
The most dangerous mistake here is committing your .jks file. If someone gets access to your release keystore, they can sign and publish malicious updates to your app — and users will install them because they appear to come from you.
Version Control Strategy
Establish two main branches: main for production-ready code and a working branch (typically develop or feature branches) for active development. This enforces a gate — your production releases don’t go out without explicit review.
Automate Early With CI/CD
Set up a GitHub Actions workflow (.github/workflows/main.yml) that runs on every commit:
- Lint checks and static analysis
- Unit tests
- Build the App Bundle (AAB) — more on this below
Having automated builds catch errors before they reach your signing process saves tremendous time.
2. Signing & Secrets: The Modern AAB Standard
Google Play has officially moved from .apk (Android Package) to .aab (Android App Bundle). This is important: if you’re only building APKs, you can still submit, but AAB is now the default and necessary for reaching optimal app sizes on user devices. Most tooling and examples have migrated accordingly.
Generate the Upload Key
You’ll create a signing key using keytool:
keytool -genkey -v -keystore my-release-key.jks \
-keyalg RSA -keysize 2048 -validity 10000 -alias my-alias
This prompts you for your name, organization, and a password. Choose a strong password — this is the key to your app’s future.
Gotcha #1: The -validity 10000 sets the certificate to expire in ~27 years. If your key expires before your app updates expire, Google Play will reject your upload. So pick a huge number here.
Gotcha #2: Don’t lose this file or the password. There is no way to recover a lost upload key. If you lose it, you cannot update your app — you’ll have to unpublish, create a new app entry, and rebuild your user base from zero. Store it somewhere with backups.
Secure the Credentials in GitHub Actions
In your GitHub repository, navigate to Settings → Secrets and Variables → Actions and add:
KEYSTORE_FILE(base64-encoded.jksfile)KEYSTORE_PASSWORDKEY_ALIASKEY_PASSWORD
To base64-encode your keystore:
base64 -w 0 my-release-key.jks > keystore.b64
Then paste the contents into KEYSTORE_FILE.
Configure Gradle for Signing
In your build.gradle.kts (or build.gradle for Groovy), add a signingConfigs block that reads these environment variables:
android {
signingConfigs {
create("release") {
storeFile = file(System.getenv("KEYSTORE_PATH") ?: "keystore.jks")
storePassword = System.getenv("KEYSTORE_PASSWORD")
keyAlias = System.getenv("KEY_ALIAS")
keyPassword = System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
}
}
}
Your GitHub Actions workflow then decodes the keystore and sets the path before running the build:
- name: Decode Keystore
run: |
echo "${{ secrets.KEYSTORE_FILE }}" | base64 -d > keystore.jks
echo "KEYSTORE_PATH=$PWD/keystore.jks" >> $GITHUB_ENV
3. Google Play Console: The Developer Account & Store Listing
Create a Google Play Developer account, which requires a one-time $25 fee and a Google account. There’s no recurring cost beyond this.
Create Your App Entry
In the Play Console:
- Click “Create App”
- Name your app
- Select your app type (App vs. Game) and category
- Declare if it contains ads, supports family policy, etc.
Simple so far. The friction comes next.
The Store Listing Assets
You need to provide several images and descriptions:
- App Icon (512×512 px, PNG): This is your app’s avatar everywhere
- Feature Graphic (1024×500 px): The banner at the top of your store listing
- Screenshots (at least 2, ideally 4-5): Phone (1080×1920) or tablet (2560×1600). These are critical — they’re often the deciding factor for whether someone installs
- App Description (4000 characters max): Sell your app
- Short Description (80 characters): The headline people see first
Gotcha #3: Your store listing isn’t published immediately. Google Play requires you to go through testing tracks first. You cannot see what your production release will look like to users until you’ve at least submitted to internal testing.
4. Testing Tracks: The 14-Day Closed Testing Wall
This is where most first-time developers get stuck, and it’s poorly documented.
Internal Testing
Upload your first AAB to the “Internal Testing” track. This lets you (and up to 100 people you invite) install the app immediately from Play Console.
This is fast — it takes minutes. Use this to verify your app actually runs on real hardware.
Closed Testing: The “20 Tester” Rule
To move from internal testing to closed testing, you need a minimum of 20 testers who remain opted-in for 14 consecutive days. This is the single biggest gotcha for individual developers.
Why this rule exists: Google Play uses this to collect stability data and crash reports. They won’t let you move forward without evidence that real people have run your app for two weeks without catastrophic failures.
How to meet it:
- Recruit 25+ people (assume some will drop out)
- Send them an email with the internal testing link
- Ask them to install it and use it for at least 2 weeks
- Don’t submit to closed testing until the 14 days are up
You cannot rush this. Many developers try to submit to closed testing with fewer testers or in less than 14 days and get rejected by automated checks.
Gotcha #4: “Opted-in” means they’ve clicked the link and installed from Play Console at least once. Inactive testers who never engaged don’t count. The timer extends if they uninstall and reinstall.
During this phase, monitor the Play Console’s Vitals dashboard, which shows crashes, ANRs (Application Not Responding), and other errors. Fix any critical issues before moving to production — a high crash rate here will severely damage your app’s ranking once it’s public.
5. Production Submission: Data Safety and The Manual Review
Once your closed testing window has elapsed and your crash-free user percentage is acceptable (Google doesn’t publish the exact threshold, but assume they want < 1% crashes), you create a new release in the Production track.
The Data Safety Form
Before you can submit, you must complete the “Data Safety” section. This is mandatory and is the most common reason for rejection on first submission.
You declare:
- What personal data your app collects (location, contacts, financial info, health data, etc.)
- How you use it (analytics, advertising, account management)
- Whether data is encrypted
- Whether third parties can access it
- Your privacy policy link
Gotcha #5: Omissions here are the most common rejection reason. If your app uses Google Analytics and you don’t declare it, submission will be rejected. If you use AdMob but say you don’t collect advertising ID data, same thing. Be exhaustive and honest.
Advertising & Targeting Disclosures
If your app shows ads or uses an ad network SDK, you must declare it. You also need to target specific countries — you can’t leave this blank.
Upload and Submit
Upload the signed AAB and submit for review. A Google reviewer will manually examine your app and perform automated security checks. The process typically takes 3–7 days for first-time apps (subsequent reviews often move faster).
Gotcha #6: During review, your app status shows “In Review.” If Google finds issues, they’ll email you with specific rejection reasons. This is not a one-shot process — you fix the issues and resubmit. The review window starts over each time.
Gotcha #7: Your app goes live the moment the status changes from “In Review” to “Available on Google Play.” You don’t need to do anything else. An email will notify you, but some developers think they need to take an additional action and end up missing this.
6. Monetization: The Merchant Account Setup
To accept payments and earn revenue, you must link a Google Payments merchant account.
Connect Your Merchant Account
In Play Console, go to Setup → Payments Profile and add your merchant account. You’ll need:
- Your name and address
- A tax identification number (EIN in the US, or equivalent)
- Banking details for payouts
Set Pricing
If you’re charging for your app or offering in-app purchases, set the base price in your home currency. Google Play automatically converts this to local currencies and handles tax collection for most regions (VAT in Europe, GST in India, etc.).
Gotcha #8: Don’t assume your listed price is what the user pays. In regions with VAT, Google adds tax on top. A $5 app might cost €5.99 or £5.49 after local tax is factored in. Users see the final price, but your revenue reports will show the pre-tax amount.
Monitor Financial Reports
Once your app is live, track the Financial Reports section to see transaction counts, revenue, payouts, and refund rates.
Gotcha #9: Payouts don’t happen immediately. Merchants in the US can typically withdraw starting 21 days after their first sale. Other regions may have longer delays.
The Complete Workflow: Start to First Sale
To recap the non-obvious sequencing:
- Set up GitHub with proper
.gitignoreand CI/CD - Create and store your signing key securely in GitHub Actions Secrets
- Create your Google Play Developer account (fee required)
- Build and sign your AAB
- Upload to internal testing — verify functionality
- Recruit 25+ testers and upload to closed testing
- Wait 14 days for the testing window to elapse
- Complete the Data Safety form thoroughly
- Submit to production for review (3–7 day wait)
- App goes live — review status changes to “Available”
- Set up merchant account and enable monetization
- Track first sale in Financial Reports
The technical portions are straightforward. The procedural portions — especially the 14-day testing gate and the data safety form — require patience and attention to detail. Most first-time developers underestimate how many rejections they’ll face at the Data Safety stage and how long the testing window actually takes.
Plan for the full workflow to take 4–5 weeks from GitHub initialization to first sale. The first release is the longest; subsequent updates move faster because you skip the closed testing phase.