Upload Android release to the Play Store

May 1, 2026 · View on GitHub

This action will help you upload an Android .apk or .aab (Android App Bundle) file to the Google Play Console using the Google Play Developer API v3.

Inputs

InputDescriptionValueRequired
releaseFilesThe Android release file(s) to upload (.apk or .aab)Comma-separated paths. Supports glob via fast-globtrue
serviceAccountJsonPlainTextThe service account json in plain text, provided via a secret, etcThe contents of your service-account.jsontrue (or serviceAccountJson)
packageNameThe package name, or Application Id, of the app you are uploadingA valid package name, e.g. com.example.myapp. The packageName must already exist in the play console account, so make sure you upload a manual apk or aab first through the consoletrue
tracksThe tracks in which you want to assign the uploaded app. Defaults to productionComma-separated names. See APKs and Tracks documentation for calculating your target track namestrue
releaseNameThe release name. Not required to be unique. Default is configured by Google Play ConsoleA user-friendly update name, e.g. v1.0.0false
inAppUpdatePriorityIn-app update priority of the release. All newly added APKs in the release will be considered at this priority. Defaults to 0[0-5], where 5 is the highest priorityfalse
userFractionPercentage of users who should get the staged version of the app.(0.0-1.0)false
statusRelease status. Defaults to completed.One of completed, inProgress, halted, draft. Cannot be null.false
whatsNewDirectoryThe directory of localized "whats new" files to upload as the release notes. The files contained in the whatsNewDirectory MUST use the pattern whatsnew-<LOCALE> where LOCALE is using the BCP 47 formatA path to a valid whatsNewDirectoryfalse
mappingFileThe mapping.txt file used to de-obfuscate your stack traces from crash reportsA path to a valid mapping.txt filefalse
debugSymbolsThe native-debug-symbols.zip file or folder that contains your debug symbolsA path to a valid native-debug-symbols.zip file file or a folderfalse
changesNotSentForReviewIndicates that the changes in this edit will not be reviewed until they are explicitly sent for review from the Google Play Console. Defaults to falsetrue or falsefalse
serviceAccountJsonThe service account json private key file to authorize the upload request. Can be used instead of serviceAccountJsonPlainText to specify a file rather than provide a secretA path to a valid service-account.json filetrue (or serviceAccountJsonPlainText)
existingEditIdThe ID of an existing edit that has not been completed. If this is supplied, the action will append information to that rather than creating an editA valid, unpublished Edit IDfalse
versionCodesToRetainVersion codes to retain from previous releases.Comma-separated version codes.false
releaseFilePlease switch to using releaseFiles as this will be removed in the futurefalse
trackPlease switch to using tracks as this will be removed in the futurefalse

Using tracks

The track input is deprecated. Use tracks instead.

  • Single track:
with:
  tracks: production
  • Multiple tracks (comma-separated):
with:
  tracks: internal,qa

Outputs

OutputEnvironment VariableDescription
internalSharingDownloadUrlsINTERNAL_SHARING_DOWNLOAD_URLSA JSON list containing the download urls for every release file uploaded using the internalsharing track
internalSharingDownloadUrlINTERNAL_SHARING_DOWNLOAD_URLThe download url for the last release file uploaded using the internalsharing track
committedEditIdCOMMITTED_EDIT_IDThe unique identifier of the committed edit.
committedEditIdExpiryTimeSecondsCOMMITTED_EDIT_ID_EXPIRY_TIME_SECONDSTime in seconds until the committed edit expires.

Example usage

The below example publishes MyApp to Google Play, targetting 33% (0.33) of users with a priority of 2.

uses: r0adkll/upload-google-play@v1
with:
  serviceAccountJsonPlainText: ${{ SERVICE_ACCOUNT_JSON }}
  packageName: com.example.MyApp
  releaseFiles: app/build/outputs/bundle/release/app-release.aab
  tracks: production
  status: inProgress
  inAppUpdatePriority: 2
  userFraction: 0.33
  whatsNewDirectory: distribution/whatsnew
  mappingFile: app/build/outputs/mapping/release/mapping.txt
  debugSymbols: app/intermediates/merged_native_libs/release/out/lib

Configure access via service account

  1. Enable the Google Play Android Developer API.
    1. Go to https://console.cloud.google.com/apis/library/androidpublisher.googleapis.com.
    2. Click on Enable.
  2. Create a new service account in Google Cloud Platform (docs).
    1. Navigate to https://cloud.google.com/gcp.
    2. Open IAM & Admin > Service accounts > Create service account.
    3. Pick a name for the new account. Do not grant the account any permissions.
    4. To use it from the GitHub Action use either:
      • Account key in GitHub secrets (simpler):
        1. Open the newly created service account, click on keys tab and add a new key, JSON type.
        2. When successful, a JSON file will be automatically downloaded on your machine.
        3. Store the content of this file to your GitHub secrets, e.g. SERVICE_ACCOUNT_JSON.
        4. Set serviceAccountJsonPlainText: ${{ SERVICE_ACCOUNT_JSON }} when using this action.
      • Workload identity authentication (more secure, recommended by GCP):
        1. Configure workload identity provider in the same project as the new service account (docs).
        2. Run a step to obtain short-lived access credentials:
          - id: auth
            uses: google-github-actions/auth@v2
            with:
              workload_identity_provider: <project>/.../workloadIdentityPools/<provider>
              service_account: <service-account>@<project>.iam.gserviceaccount.com
          
        3. Set serviceAccountJson: ${{ steps.auth.outputs.credentials_file_path }} when using this action.
  3. Add the service account to Google Play Console.
    1. Open https://play.google.com/console and pick your developer account.
    2. Open Users and permissions.
    3. Click invite new user and add the email of the service account created in the previous step.
    4. Grant permissions to the app that you want the service account to deploy in app permissions.

FAQ

I get the error "Package not found"

Make sure you upload an apk or aab manually first by creating a release through the play console.

The whatsNewDirectory in this example supplies changelogs for English, German and Japanese

distribution/
└─ whatsnew/
  ├─ whatsnew-en-US
  ├─ whatsnew-de-DE
  └─ whatsnew-ja-JP

I get the error "Precondition check failed"

This means some required state or store listing requirement hasn’t been met. Verify your track progression and edit state against the Android Publisher API reference. Common causes include:

First‑time production push

You may have not yet promoted any AAB/APK through internal‑testing, alpha or beta before targeting production.

Before you can target production, push at least one release through an earlier track. For example:

uses: r0adkll/upload-google-play@v1
with:
  # ... other configurations ...
  tracks: internal

Edit conflict

If you start an edit draft, then make changes to the console (or another draft), committing the original draft will sometimes fail — always create a fresh edit after external changes.

Concurrent edits

Multiple clients may open edits in parallel, but once one is committed all others become stale and may trigger this error.