Skip to content

Building and Running

Se.Cherkasov edited this page Aug 23, 2026 · 1 revision

Building and running

English · Русский

Prerequisites

  • JDK 21 — every module sets jvmToolchain(21); the foojay-resolver plugin fetches a toolchain if none is installed.
  • Android SDK — needed by every client build, not just Android ones: :androidApp is always in the settings graph and AGP resolves the SDK at configuration time. Set ANDROID_HOME, or sdk.dir in local.properties (compileSdk 37, targetSdk 36, minSdk 26).
  • A server-only build needs neither: ./gradlew :server:run -PserverOnly.

Versions live in gradle/libs.versions.toml; dependencies are added there, never as raw coordinates.

Run

./gradlew :composeApp:run                                   # desktop app
./gradlew :composeApp:hotRunDesktop                         # desktop with Compose Hot Reload
ANDROID_HOME=$HOME/Android/Sdk ./gradlew :androidApp:installDebug
SKERRY_JWT_SECRET=dev ./gradlew :server:run -PserverOnly     # sync server
docker compose up -d --build                                 # sync server in Docker

Test and analyse

./gradlew test allTests        # JUnit 5 — `test` alone skips the multiplatform modules
./gradlew build                # full gate, Android lint included
./gradlew detektAll            # static analysis
./gradlew koverHtmlReport      # coverage
./gradlew :androidApp:compileDebugKotlin   # the Android side of a UI change

The test stack is kotlin("test") on the JUnit 5 backend. There is no Kotest, no MockK and no ktlint in this repository — fakes are hand-written, and the lint gate is Android lint inside ./gradlew build. UI tests need a display; CI runs them under xvfb-run --auto-servernum.

Package

./gradlew :composeApp:packageDistributionForCurrentOS   # .deb / .rpm / .msi / .dmg
./gradlew :composeApp:packageAppImage                   # portable Linux .AppImage
./gradlew :composeApp:packagePortableZip                # portable .zip

A package is built for the OS and CPU architecture of the build machine — an arm64 .dmg only comes out of an arm64 macOS runner.

ProGuard/minification is disabled on purpose for the desktop release: it broke the crypto stack (JNA/libsodium, okio, BouncyCastle's signed jar). Read the comment in composeApp/build.gradle.kts before re-enabling it.

Two local instances

Point XDG_CONFIG_HOME at a different directory and run a createDistributable build to have a second, isolated install (useful for testing sync between two "devices" on one machine).

Build daemons

After a long series of Gradle runs, ./gradlew --stop and killing a leftover KotlinCompileDaemon frees a substantial amount of memory.

The gate

Anything beyond a documentation change goes through the project's own harness rather than ad-hoc Gradle runs — see Testing and the gate.

Clone this wiki locally