GodTools is a mobile discipleship app built by Cru. This repository contains the Android client.
- JDK 21 (Temurin) — version specified in
.tool-versions - Android SDK — compile/target SDK 36, minimum SDK 24
- Git LFS — required for Paparazzi snapshot files
# Clone the repo (Git LFS must be installed first)
git clone https://github.com/CruGlobal/godtools-android.gitPaparazzi snapshot images are stored in Git LFS. Install it before cloning or working with snapshot tests:
brew install git-lfs # macOS
git lfs install# Build the app bundle
./gradlew bundle
# Run unit tests (all variants)
./gradlew test
# Run tests for a specific module
./gradlew :library:model:test
./gradlew :app:test
# Verify Paparazzi snapshot tests (requires Git LFS)
./gradlew verifyPaparazzi
# Run ktlint (code style checks)
./gradlew :build-logic:ktlintCheck ktlintCheck
# Run Android lint
./gradlew lintPaparazzi Snapshots: Do not record snapshots locally. Trigger the manual GitHub Actions workflow on your feature branch to generate and commit updated screenshots.
app/ # Main application module
build-logic/ # Gradle convention plugins
feature/ # Google Play Dynamic Feature modules
library/ # Core non-UI modules
ui/ # UI and tool-renderer modules
Main application module — GodToolsApplication (Hilt entry point), DashboardActivity, Dagger modules in dagger/.
| Module | Purpose |
|---|---|
model |
Data models and JSON:API type definitions |
db |
Room database, DAOs, and repositories |
api |
Retrofit REST and Scarlet WebSocket clients |
sync |
WorkManager-based data synchronization |
base |
Core utilities, settings, file system abstraction |
account |
User authentication |
analytics |
Event tracking |
download-manager |
Tool download management |
initial-content |
Bundled initial content |
user-data |
User preferences and state |
| Module | Purpose |
|---|---|
base |
Shared Compose components and Material 3 theme |
base-tool |
Base tool rendering infrastructure |
tract-renderer |
Tract tool renderer |
lesson-renderer |
Lesson tool renderer |
article-renderer |
Article tool renderer |
article-aem-renderer |
AEM article tool renderer |
cyoa-renderer |
Choose Your Own Adventure renderer |
tips-renderer |
Tips renderer |
tutorial-renderer |
Tutorial renderer |
shortcuts |
App shortcuts UI |
qr-code |
QR code feature UI |
Google Play Dynamic Feature modules: bundledcontent (bundled initial content delivered via Play).
Gradle convention plugins: godtools.application-conventions, godtools.library-conventions, godtools.dynamic-feature-conventions.
| Concern | Technology |
|---|---|
| Dependency injection | Hilt (Dagger 2) |
| UI | Jetpack Compose + Material Design 3 |
| Navigation / UI state | Slack Circuit |
| Networking | Retrofit (REST), Scarlet (WebSocket), OkHttp |
| Database | Room |
| Background work | WorkManager |
| Image loading | Coil |
| Dependency versions | gradle/libs.versions.toml version catalog |
Circuit pattern: Presenter/UI pairs annotated with @CircuitInject. Presenters are @Composable functions that return state objects; actions flow through UiState.eventSink.
- Product flavors (
envdimension):stage(staging API),production(production API) - Build types:
debug,qa(inherits debug),release - The
stageflavor is only available fordebugandqabuilds
Style is enforced by ktlint with the android_studio code style.
- Max line length: 120
- Indent: 4 spaces
Always run ktlint before committing:
./gradlew :build-logic:ktlintCheck ktlintCheckStrings are managed via Crowdin. To push/pull translations, install the Crowdin CLI and set the CROWDIN_API_TOKEN environment variable.
- Branch from
developand open PRs againstdevelop(the default branch). - Add unit tests for any new functionality.
- Run ktlint and unit tests before opening a PR.
- For UI changes, trigger the Paparazzi snapshot workflow on your branch rather than recording locally.