Skip to content

Build System

This document covers the Gradle build system, convention plugins, JKube integration, and key configuration properties for quant-app.

For how these artifacts are deployed, see infrastructure.md and ci-cd.md.

Build Types

Controlled by the -PbuildType=<type> Gradle parameter. Three types are defined in build-logic/src/main/kotlin/buildconfig/BuildType.kt:

  • DEV (default) — local development
  • STG — staging, produces -SNAPSHOT image tags
  • PROD — production

Each build type loads its corresponding properties file from the root: gradle.dev.properties, gradle.stg.properties, gradle.prod.properties.

Build Logic (build-logic/)

Convention plugins compiled as a separate included build. All plugins are precompiled script plugins (.gradle.kts) under src/main/kotlin/.

Key plugins:

  • buildconfig.buildtype — loads build-type properties, creates the buildConfig {} DSL, generates typed config classes
  • conventions.kubernetes.image — computes kubernetesConvention.imageName, wires CONTAINER_REGISTRY into JKube tasks at execution time
  • conventions.kubernetes.testing — renders per-build-type JKube manifest fixtures for unit tests
  • jkube.extension — adds fluent JKube DSL helpers and custom enricher bridges for controller env.valueFrom refs plus lifecycle hooks

Environment Variables

  • CONTAINER_REGISTRY — required at execution time for k8sResource and k8sPush. Not required for k8sBuild or at configuration time (Gradle sync succeeds without it). Set in ~/.gradle/gradle.properties for local development.
  • USERNAME / TOKEN — GitHub Packages credentials used by settings.gradle.kts to resolve com.geldata:driver from https://maven.pkg.github.com/timemanx/gel-java. Commands may need these exported explicitly or sourced from the local .env.
  • NODE_AUTH_TOKEN — GitHub Packages npm token used by JS/npm steps that can hit npm.pkg.github.com (for example test and assemble when the frontend web distribution is built).

Container Image Convention (conventions.kubernetes.image)

Located at build-logic/src/main/kotlin/conventions/kubernetes/.

KubernetesConvention exposes imageName: Property<String> — the image name without registry ($namespace/$name:$tag).

image.gradle.kts applies to modules that build and push container images:

  • Computes imageName lazily from build type and k8s-namespace extra property
  • Image tags: $version-SNAPSHOT for DEV and STG, $version for PROD
  • Declares CONTAINER_REGISTRY as an inputs.property on k8sResource and k8sPush; sets it on each non-skipped JKube image in doFirst

Modules that use this plugin: backend-app, backend-server, backend-sync, backend-web-app.

JKube Extension (jkube.extension)

Located at build-logic/src/main/kotlin/jkube/.

  • Requires org.eclipse.jkube.kubernetes; it fails the build after evaluation if JKube is not applied.
  • Enables kubernetes.useProjectClassPath and adds the project classpath entries needed for custom JKube enrichers.
  • Exposes a fluent DSL around ControllerResourceConfig via Project.controllerResourceConfig { ... }.
  • envValuesFrom(...) accepts ControllerEnvValueFromSpec entries built with helpers such as envValueFromSecretKey, envValueFromConfigMapKey, and envValueFromField.
  • postStartExec(...), preStopExec(...), and lifecycleHooks(...) record container lifecycle hooks in Gradle and apply them through a custom enricher, with optional containerName targeting for multi-container pods.
  • This is the mechanism used when JKube's stock DSL cannot directly express controller env.valueFrom entries. backend-database uses it for GEL_SERVER_USER and GEL_SERVER_PASSWORD; backend-recorder uses it for all six qdb-env-vars secret refs; backend-sync uses it for DB_USER, DB_PASSWORD, KUBERNETES_NAMESPACE, and HOSTNAME.
  • Shared helpers such as httpGetProbe(...), podAnnotations(...), and VolumeDsl.configMapItems(...) live in the same package and are intended to keep module build.gradle.kts files fluent.
  • Modules using this plugin: backend-database, backend-recorder, backend-sync.

Kubernetes Deployment

JKube (org.eclipse.jkube.kubernetes) generates Kubernetes resource YAMLs via k8sResource and applies them via k8sApply. Resources are generated per build type using -PbuildType=<type>.

k8s-namespace must be set in the build-type properties file for the target environment.

Manifest Fixture Rendering For Tests

conventions.kubernetes.testing lives in build-logic/src/main/kotlin/conventions/kubernetes/testing.gradle.kts.

  • It registers prepareManifestFixtures, which renders JKube manifests for every BuildType into build/test-manifests/<buildType>.
  • The standard test task for modules applying this plugin depends on prepareManifestFixtures.
  • The plugin also accepts -PkubernetesTesting.fixtureBuildDir=... to redirect the generated fixture build directory when needed.

Key Properties

Property Source Used by
k8s-namespace gradle.{buildtype}.properties JKube namespace, image name
CONTAINER_REGISTRY Env var or ~/.gradle/gradle.properties Image registry at execution time
buildType Gradle param -PbuildType= Build config, image tag suffix
db.credentials.secret.name gradle.properties backend-database secret name in DSL and manifest test
db.readiness.path / db.liveness.path gradle.properties backend-database probe paths in DSL and manifest test
db.probe.initial.delay.seconds / db.probe.period.seconds gradle.properties backend-database probe timing in DSL and manifest test
recorder.image gradle.properties backend-recorder QuestDB image
recorder.credentials.secret.name gradle.properties backend-recorder secret name in DSL and manifest test
recorder.readiness.path / recorder.liveness.path gradle.properties backend-recorder probe paths in DSL and manifest test
recorder.probe.initial.delay.seconds / recorder.probe.period.seconds gradle.properties backend-recorder probe timing in DSL and manifest test
recorder.log.timezone / recorder.metrics.enabled / recorder.http.* / recorder.pg.security.readonly gradle.properties backend-recorder direct env vars in DSL and manifest test