Skip to content

Commit

Permalink
Add dry_run option to validate without committing (#172)
Browse files Browse the repository at this point in the history
* Add dry_run option to validate without committing

* Add E2E test

* Fix indent

* Fix parallel testing issues?

* Fix conflicting versionName across tests

* Increment version code to not conflict with another test

* Define track

---------

Co-authored-by: Olivér Falvai <ofalvai@gmail.com>
  • Loading branch information
smuldr and ofalvai authored Sep 26, 2024
1 parent c341208 commit fe37a30
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 27 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ Upload your Android app to Google Play.

The Step uploads your Android app to Google Play. It works with both APK and AAB files.

Please note that in order to successfully use this Step, you must [upload your first APK or AAB file manually](https://support.google.com/googleplay/android-developer/answer/9859152?hl=en&visit_id=637407764704794872-3953166533&rd=1), using Google's own web interface!
Once you uploaded one APK or AAB of your app to Google Play manually, you can use our Step for all subsequent versions.
Please note that in order to successfully use this Step, you must [upload your first APK or AAB file manually](https://support.google.com/googleplay/android-developer/answer/9859152?hl=en&visit_id=637407764704794872-3953166533&rd=1), using Google's own web interface!
Once you uploaded one APK or AAB of your app to Google Play manually, you can use our Step for all subsequent versions.

### Configuring the Step

The Step uses Google's API so before attempting to use the Step, you need to [Set up Google API access](https://devcenter.bitrise.io/deploy/android-deploy/deploying-android-apps/#setting-up-google-play-api-access). This includes:
- [Linking your Google Developer Console to an API project](https://developers.google.com/android-publisher/getting_started#linking_your_api_project).
- [Setting up API access using a service account](https://developers.google.com/android-publisher/getting_started#using_a_service_account).
- Granting the necessary access rights to the service account.
- Upload the service account JSON key to Bitrise and store it in a [Secret Env Var](https://devcenter.bitrise.io/builds/env-vars-secret-env-vars/).
- Granting the necessary access rights to the service account.
- Upload the service account JSON key to Bitrise and store it in a [Secret Env Var](https://devcenter.bitrise.io/builds/env-vars-secret-env-vars/).

Due to the way the Google Play Publisher API works, you have to grant at least the following permissions to that service account:
- Edit store listing, pricing & distribution
Expand All @@ -30,25 +30,25 @@ Read the full process in our [Deploying Android apps guide](https://devcenter.bi

To deploy your app with the Step:

1. In the **Service Account JSON key file path**, add the Secret that stores your service account JSON key.
1. In the **App file path** input, set the path to your APK and/or AAB files. You can add multiple paths here, separated with a newline.
1. In the **Service Account JSON key file path**, add the Secret that stores your service account JSON key.
1. In the **App file path** input, set the path to your APK and/or AAB files. You can add multiple paths here, separated with a newline.
In most cases, the default values work well unless you changed the output variable of the Step that build your APK or AAB.
1. In the **Package name** input, set the package name of your app.
1. In the **Package name** input, set the package name of your app.
1. In the **Track** input, add the track to which you want to assign the app. This can be any of the built-in tracks or a custom track of your own.

### Troubleshooting
### Troubleshooting

If the Step fails, check the following:
- If it's an authentication error, check that your Secret points to the correct file (and that a file is uploaded at all).
- If it's an authentication error, check that your Secret points to the correct file (and that a file is uploaded at all).
- Make sure your service account has the necessary access rights.
- Check that there's no typo in the package name and that you selected an existing track for the app.
- Check that there's no typo in the package name and that you selected an existing track for the app.

### Useful links
### Useful links

- [Google Play Developer API - Getting Started](https://developers.google.com/android-publisher/getting_started)
- [Deploying Android apps](https://devcenter.bitrise.io/deploy/android-deploy/deploying-android-apps/)

### Related Steps
### Related Steps

- [TestFairy Deploy Android](https://www.bitrise.io/integrations/steps/testfairy-deploy-android)
- [AppCenter Android Deploy](https://www.bitrise.io/integrations/steps/appcenter-deploy-android)
Expand Down Expand Up @@ -104,12 +104,13 @@ steps:
| `mapping_file` | The `mapping.txt` file provides a translation between the original and obfuscated class, method, and field names. Uploading a mapping file is not required when deploying an AAB as the app bundle contains the mapping file itself. In case of deploying [multiple artifacts](https://developer.android.com/google/play/publishing/multiple-apks.html), you can specify multiple mapping.txt files as a newline (`\n`) or pipe (`\|`) separated list. The order of mapping files should match the list of APK or AAB files in the `app_path` input. | | `$BITRISE_MAPPING_PATH` |
| `retry_without_sending_to_review` | If set to `true` and the initial change request fails, the changes will not be reviewed until they are manually sent for review from the Google Play Console UI. If set to `false`, the step fails if the changes can't be automatically sent to review. | required | `false` |
| `ack_bundle_installation_warning` | Must be set to `true` if the App Bundle installation may trigger a warning on user devices (for example, if installation size may be over a threshold, typically 100 MB). | required | `false` |
| `dry_run` | If set to `true` then the changes will not be committed to create a real release in the Play Console. Use this flag to validate your configuration without triggering a new review. See the [API reference](https://developers.google.com/android-publisher/api-ref/rest/v3/edits/validate). | | `false` |
</details>

<details>
<summary>Outputs</summary>

| Key | Description |
| Key | Description |
|------------------|----------------------------------------------------|
| `FAILURE_REASON` | Reason the upload to Google Play failed, if it did |

Expand Down
1 change: 1 addition & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type Configs struct {
Status string `env:"status"`
RetryWithoutSendingToReview bool `env:"retry_without_sending_to_review,opt[true,false]"`
AckBundleInstallationWarning bool `env:"ack_bundle_installation_warning,opt[true,false]"`
DryRun bool `env:"dry_run,opt[true,false]"`
IsDebugLog bool `env:"verbose_log,opt[true,false]"`
}

Expand Down
56 changes: 56 additions & 0 deletions e2e/bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,62 @@ workflows:
- user_fraction: ""
- retry_without_sending_to_review: true
- verbose_log: true
test_dry_run:
envs:
- TEST_APP_URL: https://github.com/bitrise-io/sample-apps-android-sdk22.git
- BRANCH: master

- BITRISEIO_ANDROID_KEYSTORE_URL: $SIMPLESAMPLE_ANDROID_KEYSTORE_URL
- BITRISEIO_ANDROID_KEYSTORE_PASSWORD: $SIMPLESAMPLE_ANDROID_KEYSTORE_PASSWORD
- BITRISEIO_ANDROID_KEYSTORE_ALIAS: $SIMPLESAMPLE_ANDROID_KEY_ALIAS
- BITRISEIO_ANDROID_KEYSTORE_PRIVATE_KEY_PASSWORD: $SIMPLESAMPLE_ANDROID_KEY_PASSWORD

- PACKAGE_NAME: com.bitrise_io.sample_apps_android_simple_google_play_deploy
- SERVICE_ACCOUNT_KEY_URL: $GOOGLE_PLAY_SERVICE_ACCOUNT_KEY_URL
- TRACK: internal
before_run:
- _setup
steps:
- set-java-version:
inputs:
- set_java_version: "17"
- script:
title: Set $VERSION_CODE higher than previously submitted
inputs:
- content: |-
set -ex
envman add --key VERSION_CODE --value $(( $BITRISE_BUILD_NUMBER + 1 ))
- change-android-versioncode-and-versionname:
inputs:
- build_gradle_path: ./app/build.gradle
- new_version_code: $VERSION_CODE
- new_version_name: 0.2.5-dryrun
- gradle-runner:
inputs:
- gradle_task: assembleRelease
- gradlew_path: ./gradlew
- sign-apk:
inputs:
- android_app: $BITRISE_APK_PATH_LIST
- use_apk_signer: true
- path::./:
title: Execute step
# Limit running this test to only one stack to avoid parallel testing issues
# Running E2E tests on all stacks in parallel would cause conflicting deployments in Google Play to the same app
run_if: |-
{{ or (enveq "IS_LATEST_STACK_UBUNTU" "true") (not .IsCI) }}
inputs:
- service_account_json_key_path: $SERVICE_ACCOUNT_KEY_URL
- package_name: $PACKAGE_NAME
- app_path: $BITRISE_SIGNED_APK_PATH
- dry_run: true
- track: $TRACK
- mapping_file: ""
- user_fraction: ""
- retry_without_sending_to_review: true
- verbose_log: true

_setup:
steps:
- script:
Expand Down
36 changes: 24 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,15 +177,15 @@ func main() {
}
log.Donef("Authenticated client created")

errorString := executeEdit(service, configs, false)
errorString := executeEdit(service, configs, false, configs.DryRun)
if errorString == "" {
return
}
if strings.Contains(errorString, changesNotSentForReviewMessage) {
if configs.RetryWithoutSendingToReview {
log.Warnf(errorString)
log.Warnf("Trying to commit edit with setting changesNotSentForReview to true. Please make sure to send the changes to review from Google Play Console UI.")
errorString = executeEdit(service, configs, true)
errorString = executeEdit(service, configs, true, false)
if errorString == "" {
return
}
Expand All @@ -200,7 +200,7 @@ func main() {
failf(errorString)
}

func executeEdit(service *androidpublisher.Service, configs Configs, changesNotSentForReview bool) (errorString string) {
func executeEdit(service *androidpublisher.Service, configs Configs, changesNotSentForReview bool, dryRun bool) (errorString string) {
editsService := androidpublisher.NewEditsService(service)
//
// Create insert edit
Expand Down Expand Up @@ -245,15 +245,27 @@ func executeEdit(service *androidpublisher.Service, configs Configs, changesNotS
}
log.Donef("Track updated")

//
// Commit edit
fmt.Println()
log.Infof("Committing edit")
editsCommitCall := editsService.Commit(configs.PackageName, appEdit.Id)
editsCommitCall.ChangesNotSentForReview(changesNotSentForReview)
if _, err := editsCommitCall.Do(); err != nil {
return fmt.Sprintf("Failed to commit edit, error: %s", err)
if dryRun {
//
// Validate edit
fmt.Println()
log.Infof("Dry run: validating edit without committing")
validateEditCall := editsService.Validate(configs.PackageName, appEdit.Id)
if _, err := validateEditCall.Do(); err != nil {
return fmt.Sprintf("Failed to validate edit, error: %s", err)
}
log.Donef("Edit validated")
} else {
//
// Commit edit
fmt.Println()
log.Infof("Committing edit")
editsCommitCall := editsService.Commit(configs.PackageName, appEdit.Id)
editsCommitCall.ChangesNotSentForReview(changesNotSentForReview)
if _, err := editsCommitCall.Do(); err != nil {
return fmt.Sprintf("Failed to commit edit, error: %s", err)
}
log.Donef("Edit committed")
}
log.Donef("Edit committed")
return ""
}
12 changes: 10 additions & 2 deletions step.yml
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ inputs:
value_options:
- "true"
- "false"

- ack_bundle_installation_warning: "false"
opts:
title: Acknowledge Bundle Installation Warning
Expand All @@ -187,7 +186,16 @@ inputs:
value_options:
- "true"
- "false"

- dry_run: "false"
opts:
title: Dry Run
description: |-
If set to `true` then the changes will not be committed to create a real release in the Play
Console. Use this flag to validate your configuration without triggering a new review.
is_required: false
value_options:
- "true"
- "false"
- verbose_log: "false"
opts:
title: Enable verbose logging
Expand Down

0 comments on commit fe37a30

Please sign in to comment.