diff --git a/.aiexclude b/.aiexclude new file mode 100644 index 0000000..aa57bd0 --- /dev/null +++ b/.aiexclude @@ -0,0 +1,9 @@ +.gradle/ +build/ +!build/reports/ +*/build/ +!*/build/reports/ +!*/build/outputs/ +!*/build/test-results/ +local.properties +gradle.properties diff --git a/.gitignore b/.gitignore index 6498d2a..9a8ba20 100644 --- a/.gitignore +++ b/.gitignore @@ -31,12 +31,6 @@ proguard/ # Log Files *.log -# Intellij project files -*.iml -*.ipr -*.iws -.idea/ - # private config file gradle.properties !/benchmark/gradle.properties @@ -47,3 +41,13 @@ gradle.properties # OS X generated file .DS_Store +# Agent config local files (Claude, Codex, Gemini, Cursor, Windsurf, etc.) +# Keep main config files under version control, ignore user-local overrides +**/AGENTS.local.md +**/CLAUDE.local.md +**/.claude/**/*.local.* +**/.codex/**/*.local.* +**/.gemini/**/*.local.* +**/.cursor/**/*.local.* +**/.windsurf/**/*.local.* + diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..9107feb --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,70 @@ +# AGENTS.md + +This file provides guidance to coding agents when working with code in this repository. + +## Project Overview + +Android client library for tracking user events (Nosara/Tracks), A/B testing (ExPlat), and crash logging (Sentry). Published to Automattic's S3 Maven repository. Used internally by Automattic mobile apps. Includes a `sampletracksapp` app module that can be used for manual testing. + +## Build Commands + +```bash +./gradlew assembleDebug # Build all modules +./gradlew testDebugUnitTest # Run all unit tests +./gradlew lintDebug # Run lint checks +./gradlew ktlint # Check Kotlin code style (custom task from ktlint.gradle) +./gradlew ktlintFormat # Fix Kotlin code style deviations (custom task from ktlint.gradle) +./gradlew ciktlint # Same as ktlint but with checkstyle XML output for CI (custom task from ktlint.gradle) +./gradlew buildHealth # Dependency analysis +./gradlew :experimentation:apiCheck # Binary compatibility check (`experimentation` module only) +./gradlew :benchmark:assembleDebugAndroidTest # Build benchmark instrumented tests +./gradlew :benchmark:connectedDebugAndroidTest # Run benchmark instrumented tests on a connected device +``` + +To run a single test class: + +```bash +./gradlew :experimentation:testDebugUnitTest --tests "com.automattic.android.experimentation.ExPlatTest" +./gradlew :crashlogging:testDebugUnitTest --tests "com.automattic.android.tracks.crashlogging.SentryCrashLoggingTest" +``` + +**Note:** `gradle.properties` is gitignored. CI copies `gradle.properties-example` before building. Locally, copy it manually if needed: `cp gradle.properties-example gradle.properties`. + +## Architecture + +Three independently published library modules plus a sample app and benchmark module: + +| Module | Artifact | Language | Description | +|--------|----------|----------|-------------| +| `AutomatticTracks` | `com.automattic:Automattic-Tracks-Android` | Java + Kotlin | Core event tracking with SQLite storage and background network transmission | +| `experimentation` | `com.automattic.tracks:experimentation` | Kotlin | ExPlat A/B testing SDK with file-based caching and OkHttp REST client | +| `crashlogging` | `com.automattic.tracks:crashlogging` | Kotlin | Sentry-based crash logging, performance monitoring, and error tracking | +| `sampletracksapp` | — | Kotlin | Sample app demonstrating library usage | +| `benchmark` | — | Kotlin | Performance benchmarking via `androidTest` instrumented tests using `androidx.benchmark` | + +### Key architectural details + +- **AutomatticTracks** uses a queue-based architecture with background threads for event buffering, DB-to-network transfer, and network transmission. Events expire after 14 days. +- **experimentation** has `explicitApi()` enabled and uses binary compatibility validation (`apiCheck`). Public API surface is tracked in `experimentation/api/experimentation.api`. +- **crashlogging** wraps Sentry SDK via `SentryErrorTrackerWrapper` and exposes a `CrashLoggingDataProvider` interface for host apps to supply user/app context. +- Modules publish independently to S3. No product flavors or build variants. + +## Testing Conventions + +- **Frameworks:** JUnit 4, AssertJ, Mockito-Kotlin, kotlinx-coroutines-test, MockWebServer +- **Assertions:** Use AssertJ (`assertThat`), not kotlin.test assertions +- **Naming:** Backtick-quoted names: `` `given ..., when ..., then ...` `` +- **Coroutines:** Use `runTest` from `kotlinx.coroutines.test` + +## Important Gotchas + +- Build files use **Groovy** (`build.gradle`, `settings.gradle`), not Kotlin DSL — except `benchmark/build.gradle.kts` which uses Kotlin DSL +- Dependency versions are defined as `ext` properties in root `build.gradle`, not a version catalog +- Lint treats warnings as errors (`warningsAsErrors true`). `AutomatticTracks` uses a lint baseline file + +## Publishing + +CI publishes on every PR commit and trunk merge: +- PR: `{pr-number}-{commit-full-sha1}` +- Trunk merge: `trunk-{commit-full-sha1}` +- Tag: `{tag-name}` diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..43c994c --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md