Vinicius Strugata Ambrosio
8 min readApr 15, 2023

Mendix

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

Photo by Glenn Carstens-Peters on Unsplash

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 the MENDIX_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 the requests 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 environment NODE_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:

  1. Run npm install --legacy-peer-deps
  2. 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:

  1. Run .\gradlew.bat assembleAppstoreDebug to generate the debug APK
  2. 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.

Error message after running the command npm run configure without config.json file
Error message after running the command npm run configure without config.json file

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.

A config.json sample
A config.json sample

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:

  1. 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
  2. Extracts the contents of the zip file.
  3. Open a PowerShell terminal in app-directory\scripts\mx_buildscripts-main\src\python.
  4. 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:

Running the python script— starting

If everything goes fine, you end up with a message like this, showing the path of your APK and AAB application packages:

Running the python script — end with a successful message!

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…
AppCenter starts a virtual machine at every APK build…
  • 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 the config.json. To save time, you can skip the Build Native Step.
Option to Skip MX Build
  • 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!

Vinicius Strugata Ambrosio
Vinicius Strugata Ambrosio

Written by Vinicius Strugata Ambrosio

Mendix Developer, Python Enthusiast and Flutter/Dart Learner — https://www.linkedin.com/in/vstram/

No responses yet