MiMiTrends uses the JDK 26 jpackage tool to produce installers containing the application and a private Java runtime. A package must be built on the operating system on which it will run; jpackage does not cross-build native formats.
Requirements:
- macOS with Xcode command-line tools;
- JDK 26, resolved by the Gradle toolchain;
- a valid
Developer ID Applicationcertificate in Keychain for distribution outside the App Store; - Apple notary credentials for the final public DMG.
An unsigned application image for local testing:
./gradlew :app:packageMacAppThe project wrapper builds a signed and notarized DMG and automatically selects the first available
Developer ID Application identity:
./Scripts/build-macos-dmg.zshA Developer ID signed and notarized DMG is built through the same wrapper with an explicit identity:
security find-identity -v -p codesigning
./Scripts/build-macos-dmg.zsh --identity "Iakov Senatov (G2V9T9AD95)"Before jpackage runs, the Gradle pipeline extracts dependency JARs containing macOS native
libraries, signs every Mach-O binary with the Developer ID identity, hardened runtime, and a secure
timestamp, then rebuilds the JAR. After creating the DMG, verifySignedMacDmg mounts it and verifies
the separately signed DMG container, the application signature tree, and every embedded .dylib or .jnilib. Apple submission
is blocked if this preflight fails.
Run the preflight explicitly when diagnosing signing:
MAC_SIGNING_KEY_USER_NAME="Iakov Senatov (G2V9T9AD95)" \
./gradlew :app:verifySignedMacDmgStore the notarization credentials once in the login keychain. Use an app-specific password, not the Apple ID password:
xcrun notarytool store-credentials "MiMiNotary" \
--apple-id "YOUR_APPLE_ID" \
--team-id "YOUR_TEAM_ID" \
--password "YOUR_APP_SPECIFIC_PASSWORD"Then build, sign, submit to Apple, wait for acceptance, staple the ticket, and validate it:
./Scripts/build-macos-dmg.zsh \
--identity "Iakov Senatov (G2V9T9AD95)" \
--profile "MiMiNotary"The equivalent shorter command is:
./Scripts/build-macos-dmg.zshCI may use App Store Connect API credentials instead of a keychain profile by setting all of APPLE_NOTARY_KEY_FILE, APPLE_NOTARY_KEY_ID, and APPLE_NOTARY_ISSUER_ID.
Output:
app/build/distributions/native/macos/MiMiTrends-<version>.dmg
The wrapper increments appVersion in gradle.properties before every DMG attempt and passes that
exact version to Gradle. The patch component is always written with three digits and runs from 000
through 099; 2.65.099 therefore becomes 2.66.000. The application
label, About dialog, generated build information, JAR manifest, jpackage metadata, and DMG filename
therefore use one value. Calling the DMG Gradle task without the wrapper is rejected, preventing a
package from being created without its required version increment.
The package task also deliberately fails when MAC_SIGNING_KEY_USER_NAME is absent. This prevents an ad-hoc signed application from being mistaken for a distributable Developer ID build.
Requirements: Windows, JDK 26, and WiX Toolset 3.x available on PATH.
Scripts\build-windows-exe.batThe result is a self-contained per-user EXE installer with Start menu and desktop shortcuts under:
app\build\distributions\native\windows\
The task creates the installer but does not Authenticode-sign it. A Windows code-signing certificate can be applied afterward with signtool in the release environment.
Requirements: Linux and JDK 26. Building the Debian package also needs fakeroot.
./Scripts/build-linux-packages.shUse --portable-only or --deb-only when only one Linux format is needed.
This creates:
- a portable
MiMiTrends-<version>-linux-<arch>.tar.gzcontaining an executable and private runtime; - a Debian/Ubuntu
.debpackage with a desktop-menu entry.
Files are written below:
app/build/distributions/native/linux/
The repository stores one three-component appVersion in gradle.properties. DMG builds advance
the three-digit patch automatically and carry 099 into the next minor version. Build IDs remain
independently generated and appear alongside the application version in the title bar and About dialog.
Certificates, Apple passwords, API private keys, and notarization profiles are never stored in the repository. Pass only identity names or environment variables to Gradle.