Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Build app bundles (.aab files) #764

Merged
merged 16 commits into from
Aug 8, 2019
Merged

Conversation

breautek
Copy link
Contributor

@breautek breautek commented Jul 11, 2019

Platforms affected

  • Android

Motivation and Context

This PR adds support to build android bundle (aab) files.
Fixes: #729

Description

Adds an --bundle flag to the cordova build command. If present, cordova will do the necessary steps to run the gradlew bundleDebug command (or gradlew bundleRelease if --release flag is present)

Accepts packageType property from build.json, or optionally the --packageType=apk|bundle command line argument. The packageType property was chosen to keep consistency with the iOS platform.

This PR does not change the current build commands. Building APKs is still necessary for deploying apps to test devices, or of course to upload to the Google Play store using the traditional way. Bundle files are exclusively for deploying to Google Play Store.

You can however use the google provided bundletool program to build APKs from a bundle file so this PR still provides the ability to build bundles in both debug and release variants.

If build.json is present in the cordova project, just like building APKs, bundles will automatically be signed using the key and password as defined in build.json.

This PR does alter a previous constraint where if a signing property is present, but is missing the required properties for signing a warning would be displayed. This was altered to only show the warning if a property for signing is present is missing the required properties for signing. In other words, if packageType is the only property defined in the build.json file, then a warning about missing required properties for signing won't be emitted.

The cordova run android command has been modified to produce an error if packageType is set to bundle. This is because you cannot execute/deploy a bundle directly to the phone. I believe it is possible to replace all usages of the adb tool and instead use Google's bundletool, which provides tools to deploy bundle files to devices and thus support the cordova run command using bundles, but that would be another PR for another day.

Testing

I have done the following:

  • Added unit tests for using the --packageType flag
  • Ran npm test and ensure all tests passed (Running Node 10.x & cordova@9)
  • I installed cordova-android platform to a test app via cordova platform add https://github.com/breautek/cordova-android.git#app-bundle and manually ran build commands and all combinations of --debug, --release, and --bundle
  • I have created a test app on Google Play store to ensure that google will accept a signed aab file created by cordova build android --bundle --release.
  • I have tested app-bundle branch against one of my work projects which involves a more complicated project structure and includes the use of native libraries (crosswalk) and observed successful builds.

Checklist

  • I've run the tests to see all new and existing tests pass
  • I added automated test coverage as appropriate for this change
  • Commit is prefixed with (platform) if this change only applies to one platform (e.g. (android))
  • If this Pull Request resolves an issue, I linked to the issue in the text above (and used the correct keyword to close issues using keywords)
  • I've updated the documentation if necessary

TODO

  • Additionally fallback to build.json packageType to decide whether to build an APK or bundle. Overridable by --packageType (Removing the --bundle flag)
  • Update build.json documentation
  • Fix the added unit test so that they are consistent (one uses withContext, the other doesn't)
  • Revert devDependencies nyc and jasmine

Crosswalk Users

See #764 (comment)

@breautek

This comment has been minimized.

@breautek breautek marked this pull request as ready for review July 11, 2019 03:52
corrected tests

bundle flag

added bundle specific output

reverted jasmine-spec-reporter change

revert jasmine config change
@dpogue
Copy link
Member

dpogue commented Jul 11, 2019

Thanks for the pull request!!

I haven't looked at this in any detail yet, but in my recent musing about how we might add support for this feature I had imagined we might reuse the packageType field from build.json (with Android-specific values) to determine whether to make a bundle or an APK.

@janpio

This comment has been minimized.

@janpio

This comment has been minimized.

@janpio janpio closed this Jul 11, 2019
@janpio janpio reopened this Jul 11, 2019
@janpio

This comment has been minimized.

@codecov-io
Copy link

codecov-io commented Jul 11, 2019

Codecov Report

Merging #764 into master will decrease coverage by 0.55%.
The diff coverage is 51.72%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #764      +/-   ##
==========================================
- Coverage   66.57%   66.02%   -0.56%     
==========================================
  Files          18       19       +1     
  Lines        1822     1860      +38     
==========================================
+ Hits         1213     1228      +15     
- Misses        609      632      +23
Impacted Files Coverage Δ
bin/templates/cordova/Api.js 53.48% <0%> (ø) ⬆️
bin/templates/cordova/lib/PackageType.js 100% <100%> (ø)
bin/templates/cordova/lib/build.js 27.77% <36.36%> (+1%) ⬆️
...n/templates/cordova/lib/builders/ProjectBuilder.js 66.3% <60%> (-3.34%) ⬇️
bin/templates/cordova/lib/run.js 98.43% <66.66%> (-1.57%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 38c6627...b0a113b. Read the comment docs.

@breautek
Copy link
Contributor Author

Thanks for the pull request!!

I haven't looked at this in any detail yet, but in my recent musing about how we might add support for this feature I had imagined we might reuse the packageType field from build.json (with Android-specific values) to determine whether to make a bundle or an APK.

I'm open to suggestions and will gladly modify this PR. I opened this PR with exactly that in mind actually.

I do have one question about using a setting from build.json. For some context, I'll describe a bit of android bundles that I understand to make sure we are on the same page.

Bundles won't be replacing APKs. Developers actively developing their app will still build APKs and deploy to their devices/emulators for testing. But one might opt to build a bundle instead of an APK to release to the app store.

So I think the general use case is most of the time, developers will be building APKs, just like they have always done traditionally. Then they'll build a bundle when they are ready to make a release. If the setting to decide whether to build an APK is in a json file, I think most people will end up requiring to edit the file constantly based on what they want to build. This is why I opted to add a --bundle flag instead, something that is easy to tack on when required, and easy to configure CI as well.

Interested to hear your thoughts on this.

@janpio
Copy link
Member

janpio commented Jul 11, 2019

This is probably not about either/or, but about "additionally". I generate the build.json for builds on CI for example, and being able to switch to a bundle there would match my use case pretty well I think.

@breautek
Copy link
Contributor Author

breautek commented Jul 11, 2019

This is probably not about either/or, but about "additionally". I generate the build.json for builds on CI for example, and being able to switch to a bundle there would match my use case pretty well I think.

Ok that makes sense to me. Later tonight I can make an edit where I can grab the setting from build.json packageType. Overriding it if --bundle --packageType=value is present on the command line.

@dpogue
Copy link
Member

dpogue commented Jul 11, 2019

I think what we do on iOS with packageType is that we try to read it from build.json, but it can also be specified on the command-line as --packageType=value. The values we want to support are probably just going to be apk and bundle, with apk being the default if it's not specified.

@erisu
Copy link
Member

erisu commented Jul 11, 2019

Is the bumping of the devDependencies jasmine and nyc required for this PR to pass?
Could they be in a separate PR or made in a separate commit (for regular merge instead of squash merge)?

@breautek
Copy link
Contributor Author

breautek commented Jul 11, 2019

Is the bumping of the devDependencies jasmine and nyc required for this PR to pass?
Could they be in a separate PR or made in a separate commit (for merge vs squash merge)?

nyc had a high vulnerability, but no I don't believe it was required to change these versions for the tests to pass. I can revert these changes if it is more proper for them to be made in a separate PR.

@janpio janpio changed the title App bundle feat: App bundles (aab) Jul 11, 2019
@janpio janpio changed the title feat: App bundles (aab) feat: build app bundles (.aab files) Jul 11, 2019
@janpio janpio changed the title feat: build app bundles (.aab files) feat: Build app bundles (.aab files) Jul 11, 2019
@brodybits
Copy link
Contributor

I would really favor keeping the jasmine & nyc updates to devDependencies in a separate PR, as I think they have nothing to do with this feature. I would also really favor getting these devDependencies merged before we merge this one, for the sake of cleaning up the warning asap.

@breautek
Copy link
Contributor Author

I would really favor keeping the jasmine & nyc updates to devDependencies in a separate PR, as I think they have nothing to do with this feature. I would also really favor getting these devDependencies merged before we merge this one, for the sake of cleaning up the warning asap.

Thanks for your explanation, I'm a little new to this. :) Didn't think of potential conflicts that could occur later. The changeset was more or less and artefact of me messing around with jasmine when I having troubles with Node12, that I forgot to revert before I made the PR. I've added a TODO item for myself to revert these devDependency changes later tonight.

@janpio
Copy link
Member

janpio commented Aug 18, 2019

Ugh, that's true - you should create an issue that cordova-android currently doesn't build nightlies :/

Then your best bet is to install from master (which Cordova CLI supports) or fork the repo and publish under your own npm package if you really don't want to use via Git.

@steebchen
Copy link

Thanks for the info. Created #810

@breautek breautek mentioned this pull request Aug 21, 2019
5 tasks
@ath0mas
Copy link
Contributor

ath0mas commented Sep 23, 2019

@tomriddle1234 it should work using -- before your param

cordova build android --release -- --packageType=bundle

like explained in doc about flags :

Note: You should use double -- to indicate that these are platform-specific arguments

@breautek
Copy link
Contributor Author

Just leaving a note here for Crosswalk users (like myself, since I haven't migrated away from it yet...)

If you are using the crosswalk webview plugin, building bundles will not give you a bundle that contains the 64bit crosswalk library. This is because the crosswalk plugin downloads a single prebuilt library and it will only download 32bit architecture; unless the --xwalk64bit flag is passed in which case, crosswalk will download a 64bit architecture library. The problem is crosswalk plugin in its current state will only ever include 1 architecture.

As a result, using bundles will not work properly with the crosswalk webview. Even if you use the --xwalk64bit flag you may pass the Google Play 64bit requirement, but you'll not include the 32bit architecture for older 32bit devices.

This is a problem with the crosswalk webview plugin itself, it will need to be updated so it packages all prebuilt libraries for each architecture when you build a bundle. Note that Intel has stopped maintaining the crosswalk project a couple years ago so you won't see a fix on the official crosswalk repository.

@sriharsha0023
Copy link

Does this work with cordova platform add android@8.0.0 ?
and this commands looks Correct?
cordova build android --debug -- --packageType=bundle
and
cordova build android --release -- --packageType=bundle

@breautek
Copy link
Contributor Author

breautek commented Oct 8, 2019

Does this work with cordova platform add android@8.0.0 ?

No, this feature was only merged in and released under 8.1.0

and this commands looks Correct?
cordova build android --debug -- --packageType=bundle
and
cordova build android --release -- --packageType=bundle

Those two commands looks right.

@dfiggtns
Copy link

I'm trying to convert to use app bundles, but when I use:

ionic cordova build android --release -- --packageType=bundle

cordova still creates an apk in build/outputs/apk.

I'm using cordova@9.0.0 and cordova-android@8.1.0

How can I get cordova to create an aab in build/outputs/bundle?

@breautek
Copy link
Contributor Author

@dfiggtns

See ionic-team/ionic-cli#4187 (comment) for how to pass packageType to cordova when using ionic.

@dfiggtns
Copy link

@breautek, yes I saw that post in my trawl through the forums. In fact, that's the one I got the format of the command from that I used above.

Unfortunately, it doesn't appear to work, as it keeps creating an apk, instead of a bundle. Hence my question of how I can get it to create a bundle.

Is there something more I have to do than just adding the extra parameter to the command?

@breautek
Copy link
Contributor Author

@dfiggtns

For ionic it's:
ionic cordova build android -- -- --packageType="bundle"

You have:
ionic cordova build android --release -- --packageType=bundle

Note the double -- -- between android and --packageType.

@dfiggtns
Copy link

I couldn't get cordova 8.1.0 to build anything other than an apk, so I resorted to using the following step between the ionic build and jarsigner steps:

cd ./platforms/android ; ./gradlew app:bundleRelease ; cd ../.. ;

which worked first time and the resulting signed bundle was accepted by the Play Store.

I hope that helps anyone with the same problem.

@mosabab
Copy link
Contributor

mosabab commented Nov 17, 2019

Hello @breautek
How can i build my android app for .aab files in phonegap build ?
I am using phonegap build for building iOS and Android apps.

Regards

@breautek
Copy link
Contributor Author

If phonegap supports the build.json file, then you can use it to signal that you want a bundle. See https://cordova.apache.org/docs/en/dev/guide/platforms/android/index.html#using-buildjson

If it doesn't work... You'll have to ask the phonegap team. Cordova supports it as of cordova-android 8.1.0.

@dfiggtns
Copy link

I've now tried using build.json to create an aab and it works!

My build.json is (located in the project root folder):

{
    "android": {
        "debug": {
            "keystore": "my.keystore",
            "storePassword": "mypw",
            "alias": "myalias",
            "password" : "mypw",
            "keystoreType": "",
            "packageType": "apk"
        },
        "release": {
            "keystore": "my.keystore",
            "storePassword": "mypw",
            "alias": "myalias",
            "password" : "mypw",
            "keystoreType": "",
            "packageType": "bundle"
        }
    }
}

and the build command is:

ionic cordova build android --release -- --buildConfig=build.json

I hope that helps.

@mosabab
Copy link
Contributor

mosabab commented Nov 18, 2019

I've now tried using build.json to create an aab and it works!

My build.json is (located in the project root folder):

{
    "android": {
        "debug": {
            "keystore": "my.keystore",
            "storePassword": "mypw",
            "alias": "myalias",
            "password" : "mypw",
            "keystoreType": "",
            "packageType": "apk"
        },
        "release": {
            "keystore": "my.keystore",
            "storePassword": "mypw",
            "alias": "myalias",
            "password" : "mypw",
            "keystoreType": "",
            "packageType": "bundle"
        }
    }
}

and the build command is:

ionic cordova build android --release -- --buildConfig=build.json

I hope that helps.

the problem is that i use phonegap build to build the apps, so i don't know which solution or method can i used to make this codes in phonegap build

@breautek
Copy link
Contributor Author

the problem is that i use phonegap build to build the apps, so i don't know which solution or method can i used to make this codes in phonegap build

May be best to ask the phonegap team. It's possible that they require some updates on their end to support the latest cordova-android version, which adds bundle support.

@mosabab
Copy link
Contributor

mosabab commented Nov 18, 2019

the problem is that i use phonegap build to build the apps, so i don't know which solution or method can i used to make this codes in phonegap build

May be best to ask the phonegap team. It's possible that they require some updates on their end to support the latest cordova-android version, which adds bundle support.

You are right, but unfortunately i put an issue in phoengap build github page about .aab file that not support in current phonegap cli (android 8.0.0), I think they should update the version of android to the latest one, but until now no anyone investigate about the issue

@Guy-Sela
Copy link

I couldn't get cordova 8.1.0 to build anything other than an apk, so I resorted to using the following step between the ionic build and jarsigner steps:

cd ./platforms/android ; ./gradlew app:bundleRelease ; cd ../.. ;

which worked first time and the resulting signed bundle was accepted by the Play Store.

I hope that helps anyone with the same problem.

Had a similar problem: I was getting .apk instead of .aab with all the above mentioned commands. What worked for me eventually was running: c:\Cordova\app_name\platforms\android>gradlew.bat bundle

Might also worth mentioning here is that gradle is still looking for ANDROID_HOME environment variable, although it's officially deprecated.

@paknecht
Copy link

paknecht commented Feb 3, 2020

Thanks very much for this feature. But I have a question. Is it somehow possible to build an apk and an abb file at the same time? Or do I have to choose between these two? I would like to have both types built.

@breautek
Copy link
Contributor Author

breautek commented Feb 3, 2020

Thanks very much for this feature. But I have a question. Is it somehow possible to build an apk and an abb file at the same time? Or do I have to choose between these two? I would like to have both types built.

You can't do it at the same time, but you can run the build twice, one with the --packageType=bundle and the other without the --packageType (or --packageType=apk). There is two folders will appear in platforms/android/app/build/outputs/, apk for built APKs, and bundle for built bundles.

https://cordova.apache.org/docs/en/dev/guide/platforms/android/index.html#using-flags

@paknecht
Copy link

paknecht commented Feb 4, 2020

Thanks very much for this feature. But I have a question. Is it somehow possible to build an apk and an abb file at the same time? Or do I have to choose between these two? I would like to have both types built.

You can't do it at the same time, but you can run the build twice, one with the --packageType=bundle and the other without the --packageType (or --packageType=apk). There is two folders will appear in platforms/android/app/build/outputs/, apk for built APKs, and bundle for built bundles.

https://cordova.apache.org/docs/en/dev/guide/platforms/android/index.html#using-flags

Thanks for the fast answer. Works Great.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support new Android App Bundle package format