Main script that is aimed to be run with scriptworker (but runs perfectly fine as a standalone script). This project is a fork of signingscript. Most of the documentation from signing script applies to this project.
First, you need python>=3.11.0.
# create the virtualenv in ./venv3
virtualenv3 venv3
# activate it
. venv3/bin/activate
git clone https://github.com/mozilla-releng/pushapkscript
cd pushapkscript
pip install pushapkscriptThen you need to install jarsigner (usually included with JDK).
If pushing AAB files, you need to install bundletool; then set environment variable BUNDLETOOL_PATH=/path/to/bundletool.jar.
Add the nightly certificate to the java keystore:
keytool -import -keystore ~/.keystores/mozilla-android -file pushapkscript/data/android-nightly.cer -alias nightlyNote: The keystore location and the certificate alias will be used in the config.json section
cp examples/config.example.json config.json
# edit it with your favorite text editorThere are many values to edit. Example values should give you a hint about what to provide. If not, please see signingscript's README for more details about allowing URLs, or contact the author for other unclear areas.
If you aren't running through scriptworker, you need to manually create the directories that work_dir and artifact_dir point to. It's better to use new directories for these rather than cluttering and potentially overwriting an existing directory. Once you set up scriptworker, the work_dir and artifact_dir will be regularly wiped and recreated.
cp examples/task.example.json /path/to/work_dir
# edit it with your favorite text editorOrdinarily, scriptworker would get the task definition from TaskCluster, and write it to a task.json in the work_dir. Since you're initially not going to run through scriptworker, you need to put this file on disk yourself.
The important entries to edit are the:
upstreamArtifacts/path: point to the APK and/or AAB file(s) to publish to Google Playdependencies: need to match thetaskIds of the URLs unless you modify thevalid_artifact_*config items as specified abovescopes: the first and only scope,project:releng:googleplay:*, tells which product in Google Play store should be updated (either aurora, beta, or release)google_play_track: refers to which Google Play track (either production, beta, or alpha) the APK/AAB will be uploaded
Google Play allows a product to have 3 different tracks (alpha, beta, production). Tracks are used by end-users when they want to enroll in a beta-testing program.
However, this feature wasn't out when we started publishing Fennec. This is why Fennec is registered as 3 different product: one for each regular Firefox channel (aurora, beta, release). As a consequence, here's how products/tracks should be used.
| Product | Brand name | Track | Notes |
|---|---|---|---|
| release | Firefox | production |
|
| beta | Firefox Beta | production |
|
| aurora | Firefox Aurora for Developers | beta |
production is not used to show the product is not aimed at regular users |
Note: For development purpose, aurora on the alpha track can also be used.
You're ready to run pushapkscript!
pushapkscript CONFIG_FILEwhere CONFIG_FILE is the config json you created above.
This should download the file(s) specified in the payload, check their signatures with jarsigner and publish them to Google Play Store.
Follow the scriptworker readme to set up scriptworker, and use ["path/to/pushapkscript", "path/to/script_config.json"] as your task_script.
work_dir and artifact_dir point to the same directories between the scriptworker config and the pushapkscript config!
No. Chain of trust is used to securely download artifacts. You can bypass that step by having artifacts already on-disk. Just put the APKs in: $work_dir/cot/$task_id/public/build/target.apk (each APK has a different task_id). Then, you can run pushapkscript.
There used to be one, but it's now decommissioned. You can spawn a new instance via puppet. To do so:
- Create a new VM instance. You can ask for a loaner.
- On the puppet master node, set up a user environment.
- Add a new node to moco-nodes.pp. The config example is present in this repo at
examples/puppet-node.example.pp. - Activate chain of trust by creating the gpg keys and whitelisting them. Otherwise, artifacts won't be downloaded.
- Edit your tasks to point to a different worker-type. Define it at your will. Please do not use the
deppool because it's used outside of releng, intryfor example. - On your VM, make the slave take the config of your user environment.
"commit": false is in your task definitions (or don't define it).
Sadly, no. The Google Play documentation doesn't mention any server we can plug to. This means, you will interact with production data. There are ways to mitigate the risk, though.
There are 3 incremental ways to avoid targeting real users (or the entire user base):
This will execute every step implemented in pushapkscript, but the last one, which commits the transaction to the Play store.
This allows to publish the same APK several times.
However, there are a few final checks that Google Play does only when the transaction is committed. We have already experienced one: the integrity of l10n stores (descriptions and "what's new" sections) is verified only at this time. We may extrapolate the behavior to: everything that can be done in several calls to Google Play will be checked at commit time.
If not defined in the task payload, commit defaults to false.
At some point, you may want to publish your APK anyway.
Google Play provides the ability to have a beta and alpha program within a product. Aurora already uses the beta program.
You can ask release management to set up a closed alpha testing on the Google Play console (Go to Release management -> App releases -> Manage Alpha) and target users by email address. Then, edit your task definition to contain "google_play_track": "alpha".
HttpError 403 when requesting https://www.googleapis.com/androidpublisher/v2/applications/org.mozilla.fennec_aurora/edits/17791185193608549142:commit?alt=json returned "Version 2015491409 of this app can not be downloaded by any devices as they will all receive APKs with higher version codes.
In the case where Release Management isn't connect, there's a temporary workaround:
- Publish the APKs on the alpha track.
- On the Google Play dashboard, promote the APKs to the beta (then the rollout channel). Reuploading the same APKs to the beta track won't be accepted by Google Play, because APKs can only be pushed once.
If you are confident enough to publish to percentage of our user base, you can use "rollout" functionality. Just edit your task definition to contain:
"channel": "production",
"rollout_percentage": 10,if you want to target 10% of the production user base.