Using Python as Tool to Build APKs From a Native Mobile Mendix Project
A Python Script to locally generate an unsigned APK (or AAB) that can be used to automate your build process
The Mendix Integrated Development Environment — Studio Pro — has an additional tool called Build Native App (a.k.a NBUI) that provides us a wizard through the several steps required to generate the application package APK/AAB (for Android) or IPA (for IOS). While NBUI works fine most of the times, sometimes the whole process takes a long time to complete. The alternative proposed in this article intends to reduce the required time to generate the application package substantially.
The Trick
How this time reduction can be possible? The trick is to follow all the required steps to generate the application package locally and using only the command line. I could use a simple *.bat script to accomplish this, but since I’m a huge fan of Python, I decided to use that language in this case!
The Requirements
- Mendix Studio Pro 9.24.0.2965
You must define theMENDIX_HOME
environment variable. E.g:MENDIX_HOME=D:\programs\Mendix
Note 01: this is the folder where all your Studio Pro installations are located.
Note 02: there’s an issue with the MxBuild tool that raises an error if your Mendix project is in a different drive than Studio Pro. As workaround, ensure that both Studio Pro and Mendix project are in the same drive. - Python 3.10.9
You may need to install therequests
package using the command line:python -m pip install requests
. - VSCode 1.77.3 — to edit the python code
You may need to install the Python VSCode Extensions. - Android Studio — with the platform tools installed.
- Node.JS
You must define the environmentNODE_HOME
variable. E.g:NODE_HOME=D:\programs\nodejs
.
The Methodology
Fortunately, Mendix provides us a command line called MxBuild tool that makes the scripting process possible. All you have to do is call this tool following the instructions described in the Mendix Documentation:
mxbuild.exe -java-home="JDKDirectory" -java-exe-path="javaExecutable" -target=deploy -native-packager-loose-version-check <path-to-your-app-mpr-file>
MxBuild is a Windows and Linux command-line tool that can be used to build a Mendix Deployment Package from a Mendix app.
After executing this command, MxBuild will generate a bundle (in app-directory\deployment\native\bundle
) containing all the business logic of your Mendix code, besides the layout and the static resources (folders assets
and res
). The bundle structure will be like:
- android
- res
- drawable-mdpi
- drawable-hdpi
- drawable-xhdpi
- drawable-xxhdpi
- drawable-xxxhdpi
- raw
- assets
- index.android.bundle
Then, you should copy this bundle to the correct location in a React Native project (your-native-template-root\android\app\src\main
) and proceed with the following steps:
- Run
npm install --legacy-peer-deps
- Run
npm run configure
A blank template React Native project is available from the Mendix GitHub repository. These commands should be executed in the root of the React Native project.
Finally you can go to the your-native-template-root/android
and:
- Run
.\gradlew.bat assembleAppstoreDebug
to generate the debug APK - Run
.\gradlew.bat bundleAppstoreDebug
to generate the debug AAB
The Caveat
Unfortunately, this process only is not enough. It will fail in the command npm run configure
, because an important file will be missing: config.json
.
This file is generated by the NBUI tool, and only for this reason, the methodology described in the article cannot be 100% executed via command line. You have to use the NBUI to generate the config.json
, at least one time. This file is important, since declares many of the configurations used in the React Native project.
So, you must follow the procedure described in the documentation in order have a valid and customized config.json
file. This procedure is beyond the scope of this article and well described in the Mendix documentation.
The Script
The Python script code that automates all this process is available in my personal GitHub repository: https://github.com/vstram/mx_buildscripts. A sample config.json
was provided as well, so that you can get start immediately (although it is recommended to run NBUI to generate a config.json
that suits your needs).
Such a script is far from being perfect, I think it could be improved a lot, but at least it is a start. You are welcome to contribute via a Pull Request or by submitting an Issue.
I will not explain every here line of the script, otherwise this article would be difficult to follow. Instead, all you need to know is how to invoke the command to run the script:
python <path-to-script>\build-unsigned-debug-apk-aab.py <path-to-MPR>\NativeApp02.mpr -c <path-to-config>\template_config.json -o <path-output> -m 9.24.0.2965 -t v7.0.0 -u http://192.168.0.51:8080
Basically, you have to:
- Download the Repository to a specific folder in your Mendix Project. E.g:
app-directory\scripts
. Use the link: https://github.com/vstram/mx_buildscripts/archive/refs/heads/main.zip - Extracts the contents of the zip file.
- Open a PowerShell terminal in
app-directory\scripts\mx_buildscripts-main\src\python
. - Run the command line as shown below, considering the correct path for your Mendix project (MPR), the path for the
template_config.file
, the output folder, the Studio Pro version number, the React Native template version number, and the Runtime URL in which your application server is running.
In my sample project, the complete command line was:
python H:\work\vstram\mx_buildscripts\src\python\build-unsigned-debug-apk-aab.py D:\temp\NativeApp02\NativeApp02.mpr -c H:\work\vstram\mx_buildscripts\src\mendix\template_config.json -o D:\temp\NativeApp02\output -m 9.24.0.2965 -t v7.0.0 -u http://192.168.0.51:8080
Python executable must be in your PATH environment variable list
A complete option list for this command is shown below:
PS H:\work\vstram\mx_buildscripts\src\python> python .\build-unsigned-debug-apk-aab.py -h
Usage:
Basic usage: python build-unsigned-debug-apk-aab.py [options] mpr_project_filename
Options:
-h, --help show this help message and exit
-r RELEASE_NUMBER, --release-number=RELEASE_NUMBER
Release Number
-m MX_VERSION, --mx-version=MX_VERSION
Mendix Version
-t RN_TEMPLATE_VERSION, --rn-template-version=RN_TEMPLATE_VERSION
React Native Template version
-c CONFIG_FILE, --config-file=CONFIG_FILE
The template Config Json file fullpath
-o OUTPUT_FOLDER, --output-folder=OUTPUT_FOLDER
The output folder in which the binaries APK and AAB
should be moved to
-i APP_IDENTIFIER, --app_identifier=APP_IDENTIFIER
The application id used to uniquely identify the
application
-n APP_NAME, --app_name=APP_NAME
The application name
-v APP_VERSION, --app_version=APP_VERSION
The application version
-b BUILD_NUMBER, --build_number=BUILD_NUMBER
The integer representing the application build number
-u RUNTIME_URL, --runtime_url=RUNTIME_URL
The application runtime url server
The script will verify some environment variables before proceeding with the execution. In addition, it uses the provided config.json
and replaces some key variables by the values defined in the command line. For example: the configuration "appIdentifier": "app_identifier"
is replaced by "appIdentifier": "myapp.nativeapp"
. You can use the provided template_config.json
as reference. Some of these command line options have default values, while others are mandatory. The figure below shows the start of the process:
If everything goes fine, you end up with a message like this, showing the path of your APK and AAB application packages:
As you can see above, the complete process took only 10.10 minutes (including the download of the React Native template project, recreation of the node_modules
folder)!
In my tests, it’s a half of the time required to generate the APK package using the recommend procedure (via Github + AppCenter).
The Rationale
I believe the reasons why the presented procedure is faster than the recommended procedure are:
- The AppCenter free tier is limited in terms of availability and responsiveness. Oftentimes, I got stuck in the middle of the process waiting for a slot in the AppCenter’s servers (because the resources are shared among many users).
- Besides that, every time AppCenter starts the building process, it starts a virtual machine from its very beginning: installs PowerShell, Gradle, among many other tools. And also downloads the project from GitHub. This process takes time…
- In addition, sometimes the build process fails due to connectivity issues between the AppCenter machines and the React Native or Maven package repositories. Since the virtual machine is always restarted, these packages are not cached.
The advantages & disadvantages
Compared to the recommended procedure, beyond the time saving, I can list the points below as advantages:
- You can quickly generate APK/AAB from your Mendix Mobile Native Project.
- You can quickly change the parameters to increase the app version or build number.
- You can easily adapt the code to use your template, instead of the Mendix default.
- You can use this python script in your CI/CD pipeline — such as Gitlab — to automate the delivery process of your project.
- You can extend the code to generate signed release APK/AAB —and this will be a subject for a future article.
As disadvantages, I can list:
- You have to run at least one time the NBUI to generate the
config.json
. Also, you must run NBUI every time you need change the app capabilities, since these configurations are stored in theconfig.json
. To save time, you can skip the Build Native Step.
- The NBUI tool is also required to pick up the correct React Native template from the Mendix GitHub repository, considering your Studio Pro release and the last fixes committed. In addition, it notifies you in case of a new release of the React Native template and offers the possibility of updating.
- This procedure is not officially supported neither recommended by Mendix.
- The script can break at any time due changes in MxBuild tool
- The script is not yet bullet proof (I could not test yet all the fail situations)
- The script was not tested in MacOS to generate IPAs. I’m not sure how XCode can be automated with Python.
The Suggestions (for Mendix)
Along the process you will notice that one of the steps that requires a long time to complete is the * Bundling native app for iOS
. What if I do not need to deliver an IPA to my customer, since it’s only required Android? This and other suggestions are listed below:
- An option to turn off the bundling for IOS.
- A Yeoman command line tool, like the one available for the Mendix Pluggable Widget Generator, for the creation of the
config.json
file. This would be useful to permit the build procedure completely via command line. - There is an Android Studio tool that can help with the build optimization. Worth noting is the Gradle Configuration Cache procedure.
The Conclusion
I believe this procedure can help those Mendix developers that need to quickly generate an APK to deliver to the QA Team and do not have patience to spend the time required by the AppCenter’s servers. I’m aware that the script has some flaws and surely can be improved.
That’s main reason I wrote this article: to get feedback from the fellow Mendix developers and to help me to improve the script. I’m curious and open to any opinion or criticism you may write in the comments.
Happy Low Coding!