Skip to content

Add android_generate_apk_from_aab action #467

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

Closed
wants to merge 14 commits into from

Conversation

rynaardb
Copy link
Contributor

@rynaardb rynaardb commented Apr 24, 2023

What does it do?

Adds a new android_generate_apk_from_aab action to generate an APK from a given AAB.

This action can be useful in cases where you already have an AAB and just need the APK from it without having to build the APK from the source.

Checklist before requesting a review

  • Run bundle exec rubocop to test for code style violations and recommendations
  • Add Unit Tests (aka specs/*_spec.rb) if applicable
  • Run bundle exec rspec to run the whole test suite and ensure all your tests pass
  • Make sure you added an entry in the CHANGELOG.md file to describe your changes under the approprioate existing ### subsection of the existing ## Trunk section.

@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch from ebbaa84 to a3f5960 Compare April 24, 2023 14:49
@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch from a3f5960 to 5a54afc Compare April 24, 2023 14:57
@rynaardb rynaardb requested a review from a team April 24, 2023 15:47
@rynaardb rynaardb marked this pull request as ready for review April 24, 2023 15:47
@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch from a57a910 to 7762101 Compare April 25, 2023 21:18
@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch 2 times, most recently from 686edc0 to 19930ed Compare April 25, 2023 23:19
@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch from 19930ed to 515832d Compare May 3, 2023 19:08
@rynaardb rynaardb changed the title Add bundletool_generate_universal_signed_apk action Add android_generate_apk_from_aab action May 3, 2023
@rynaardb rynaardb force-pushed the action/bundletool-create-apk branch from 515832d to f99c55e Compare May 3, 2023 19:34
@rynaardb rynaardb requested a review from AliSoftware May 3, 2023 19:47
Copy link
Contributor

@AliSoftware AliSoftware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your implementation is not resilient to paths with spaces and special characters, and spawns a shell interpreter for little benefit, instead of using sh('bundletool', 'arg1', 'arg2') pre-parsed syntax.

Besides, your logic with mv can lead to unwanted destructive action if the caller passes a path to a destination folder instead of a path to the APK.

I've suggested an alternate implementation below. If you adopt it, you'll have to adjust your unit tests accordingly too; I'd suggest you to add some more unit tests as well, to validate various combinations of parameters (like if the user is passing the keystore_path but not the other keystore parameters, or if we provide paths with spaces or $ characters in them, test error handling, etc)

Left some other suggestions to improve the code here and there, feel free to review them.

type: String,
optional: false,
default_value: nil
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we decided to not create intermediate folders if they don't exist, we should add a check to ensure the parent dir exists. Otherwise we'd still have the action run bundletool but only fail afterwards while trying to move the file to the destination, instead of failing early.

Suggested change
),
verify_block: proc { |p| UI.user_error!('The parent folder for the destination does not exist. Please create it first.') unless p.nil? || File.directory?(File.dirname(p)) }
),

This new implementation fixes the following issues that we had in the old implementation:

 - Issues and security risk with paths containing spaces or special parameters
    - This would not only have made the command fail
    - But it also created a security issue for parameter injection (e.g. `apk_output_file_path: 'foo --inject this && echo print the rest'`)
 - Risk of deleting any arbitrary folder on disk (due to use of unchecked `rm -rf`)
    - Calling the action with `apk_output_file_path: '.'` for example (or a path to any directory) would have the side effect of… deleting the whole content of the current directory before failing
    - This was even more problematic that this could be an easy genuine accidental error to make—especially if the caller misread the documentation and thought that the command accepted a folder for the output path instead of the path to the apk file.

In addition, this commit adds the following features to the action's behavior:

 - The action will detect if the parent directory of the `apk_output_file_path` does not exist, and exit early with a nice error if so
 - We now allow `apk_output_file_path` to be a directory, and if so the output file will be put in that directory and use the same basename as the input aab_file_path (but with `.apk` extension instead of `.aab`)
 - The action now returns the path to the generated file (which is especially useful if you didn't provide an explicit value for `apk_output_file_path` and let the action infer it, or if you provided a directory for this output path)
Group the code related to parsing the `apk_output_file_path` parameter together
@AliSoftware
Copy link
Contributor

@rynaardb GitHub doesn't let me add you as reviewer for the PR (likely because you're the PR author and GitHub doesn't allow authors to review and approve their own PRs, I guess), but feel free to review my latest changes addressing what we discussed.

@AliSoftware AliSoftware dismissed their stale review May 5, 2023 18:25

As discussed in Slack, I've ended up taking over Rynaard and fixing the issues raised above myself, so the changes I requested are now all addressed (but just dismissing my review instead of approving the PR, because it doesn't seem fair to self-approve my own changes)

@AliSoftware AliSoftware force-pushed the action/bundletool-create-apk branch from e177697 to 2d499f9 Compare May 5, 2023 18:30
@rynaardb
Copy link
Contributor Author

rynaardb commented May 8, 2023

@AliSoftware looks good. Once you approve the PR, I'll get it merged, or feel free also to do it.

@rynaardb rynaardb added the Do Not Merge e.g. if it depends on another PR to be merged first, or if that PR is only to trigger CI on forks, … label May 12, 2023
@rynaardb
Copy link
Contributor Author

@AliSoftware I've marked the PR as Do Not Merge since there seems to be an issue with the logic that checks whether bundletool is installed. See this build for an example. It only happens on our Android CI build agents, with bundletool obviously installed. The behavior seems to be different when testing locally, as it works as expected. So I'll need a bit more time to investigate why that is and to ensure we haven't missed anything.

@AliSoftware
Copy link
Contributor

Good catch.

Idea (not checked): could the reason for the failure be that bundletool is installed… but not in the $PATH of those agents, and thus not found by command -v bundletool? 🤔

@rynaardb
Copy link
Contributor Author

rynaardb commented May 12, 2023

Good catch.

Idea (not checked): could the reason for the failure be that bundletool is installed… but not in the $PATH of those agents, and thus not found by command -v bundletool? 🤔

So here's the thing, it does actually finds the path when you run command -v bundletool:

root@buildkite-android-builder-66998c988b-4hnfl:/# command -v bundletool
/usr/local/bin/bundletool

But for some reason, the check reports something else. I've already spent a good amount of time looking at the build agents to ensure we haven't misconfigured something. And so far as I can tell, everything looks fine to me.

@AliSoftware
Copy link
Contributor

AliSoftware commented May 12, 2023

Mmmmh… confusing 🤔

Trying to think of something but the only think I could think of would be if the shell context could be different when running command -v bundletool directly in your Terminal vs via fastlane and its sh method?

  • Like the Terminal uses one shell (say, bash) and fastlane uses another (say, sh)?
  • Or like the code that adds adds bundletool to the PATH is in the wrong RC file (e.g. .bashrc vs .bash_profile) which would explain why it's loaded when in an interactive terminal session but not when invoked directly?

One way of checking that this is due to different context could be to create a dummy lane that runs sh('command -v bundletool') and see if the result differs from when you invoke it in the Terminal. Especially maybe the error you get (and that our code rescue here) is something other than "executable not found" in practice, and not rescuing it in your lane test to let it crash and print will give you more insights as to what might be wrong?


Note: the fact that when I used a similar logic to test the presence of bundletool in #365, and that this sh('command', '-v', 'bundletool') call from my fastlane action worked when I tested it in wordpress-mobile/WordPress-Android#16580 (although that was back when we were still using CircleCI, not Buildkite, but still)… makes me think that the reason it doesn't work here is most likely related to something we missed in the agent's setup/config (rather than something wrong in the ruby code logic, since the same logic worked on another runner back then)? 🤔
The big question is what that missing agent configuration is of course… but at least that might help narrowing down the ideas to test? 🤞

@rynaardb rynaardb closed this Jul 14, 2023
@AliSoftware AliSoftware deleted the action/bundletool-create-apk branch July 20, 2023 09:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Do Not Merge e.g. if it depends on another PR to be merged first, or if that PR is only to trigger CI on forks, …
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants