diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 0000000..14fd6b0 --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,28 @@ +name: Android CI + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build: + name: Build Android Project + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up JDK + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: 17 + + - name: Make Gradle executable + run: chmod +x ./gradlew + + - name: Build with Gradle + run: ./gradlew build diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..a4fd868 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,43 @@ +name: Android CI + +on: + push: + branches: [ main, ci-cd-pipeline ] + pull_request: + branches: [ main ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '17' + + - name: Cache Gradle + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + ${{ runner.os }}-gradle- + + - name: Build with Gradle + run: ./gradlew build + + - name: Assemble Debug APK + run: ./gradlew assembleDebug + + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: app-debug-apk + path: app/build/outputs/apk/debug/app-debug.apk diff --git a/README.md b/README.md index dea4e4b..35fe7c4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The AI Secretary App is an AI-powered personal secretary application designed to assist users with various tasks through voice and text interactions. It utilizes a local LLM (LLaMA 3 via Ollama) to provide intelligent responses and has memory-based context and retrieval-augmented generation (RAG) capabilities. ## Features -- Voice and text input support +- Voice and text input support - Intelligent responses using LLaMA 3 - Memory management for context-aware interactions - User-friendly chat interface diff --git a/app/.github/workflows/ci.yml b/app/.github/workflows/ci.yml new file mode 100644 index 0000000..e69de29 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4641fe6..0d71f76 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,8 +2,9 @@ import java.util.Properties plugins { id("com.android.application") - kotlin("android") - id("com.google.devtools.ksp") version "1.9.0-1.0.13" + id("org.jetbrains.kotlin.android") + id("jacoco") + id("com.google.devtools.ksp") version "1.9.10-1.0.13" } // Load secrets from secrets.properties file @@ -18,7 +19,6 @@ if (secretsFile.exists()) { // Function to safely get properties with defaults fun getSecretProperty(key: String, defaultValue: String): String { val value = secretsProperties.getProperty(key, defaultValue) - // Ensure the value is not empty, use default if it is return if (value.isBlank()) defaultValue else value } @@ -32,11 +32,11 @@ android { targetSdk = 34 versionCode = 1 versionName = "1.0" - - // Add secrets as BuildConfig fields + + // Inject secrets as BuildConfig fields buildConfigField("String", "OLLAMA_BASE_URL", "\"${getSecretProperty("OLLAMA_BASE_URL", "http://localhost:11434")}\"") buildConfigField("String", "LLAMA_MODEL_NAME", "\"${getSecretProperty("LLAMA_MODEL_NAME", "llama3:8b")}\"") - + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } @@ -67,11 +67,11 @@ android { excludes += "/META-INF/notice.txt" } } - + buildFeatures { buildConfig = true } - + testOptions { unitTests { isIncludeAndroidResources = true @@ -90,19 +90,19 @@ dependencies { implementation("androidx.constraintlayout:constraintlayout:2.1.4") implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") - + // Room implementation("androidx.room:room-runtime:2.5.2") - implementation("androidx.room:room-ktx:2.5.2") // Add KTX for Coroutines support + implementation("androidx.room:room-ktx:2.5.2") ksp("androidx.room:room-compiler:2.5.2") - + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3") implementation("com.squareup.retrofit2:retrofit:2.9.0") implementation("com.squareup.retrofit2:converter-gson:2.9.0") implementation("com.github.bumptech.glide:glide:4.15.0") implementation("androidx.navigation:navigation-fragment-ktx:2.7.2") implementation("androidx.navigation:navigation-ui-ktx:2.7.2") - + // Testing testImplementation("junit:junit:4.13.2") testImplementation("org.mockito:mockito-core:5.3.1") @@ -110,8 +110,44 @@ dependencies { testImplementation("androidx.test.ext:junit:1.1.5") testImplementation("androidx.test.espresso:espresso-core:3.5.1") testImplementation("org.robolectric:robolectric:4.10.3") - - // Android Testing + + // Android Instrumentation Tests androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") -} \ No newline at end of file +} + +// JaCoCo configuration +jacoco { + toolVersion = "0.8.10" +} + +tasks.register("jacocoTestReport") { + dependsOn("testDebugUnitTest") + + reports { + xml.required.set(true) + html.required.set(true) + } + + val fileFilter = listOf( + "**/R.class", + "**/R$*.class", + "**/BuildConfig.*", + "**/Manifest*.*", + "**/*Test*.*" + ) + + val debugTree = fileTree("${buildDir}/intermediates/javac/debug/classes") { + exclude(fileFilter) + } + + val kotlinDebugTree = fileTree("${buildDir}/tmp/kotlin-classes/debug") { + exclude(fileFilter) + } + + classDirectories.setFrom(files(debugTree, kotlinDebugTree)) + sourceDirectories.setFrom(files("src/main/java", "src/main/kotlin")) + executionData.setFrom(fileTree(buildDir) { + include("**/*.exec", "**/*.ec") + }) +} diff --git a/build.gradle.kts b/build.gradle.kts index 7b969ee..e8b4e08 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,31 +1,56 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. -buildscript { - repositories { - google() - mavenCentral() - } - dependencies { - classpath("com.android.tools.build:gradle:8.1.0") - classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0") - } -} +import com.google.devtools.ksp.gradle.KspExtension plugins { - id("com.android.application") version "8.1.0" apply false - id("com.android.library") version "8.1.0" apply false - id("org.jetbrains.kotlin.android") version "1.9.0" apply false - id("org.jetbrains.kotlin.kapt") version "1.9.0" apply false - id("com.google.devtools.ksp") version "1.9.0-1.0.13" apply false + id("com.android.application") version "8.1.0" + id("org.jetbrains.kotlin.android") version "1.9.21" + id("com.google.devtools.ksp") version "1.9.21-1.0.15" } -tasks.register("clean", Delete::class) { - delete(rootProject.buildDir) -} -allprojects { - tasks.withType().configureEach { - kotlinOptions { - jvmTarget = "17" +android { + namespace = "com.example.astraai" + compileSdk = 34 + + defaultConfig { + applicationId = "com.example.astraai" + minSdk = 24 + targetSdk = 34 + versionCode = 1 + versionName = "1.0" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) } } -} \ No newline at end of file + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = "17" + } +} + +dependencies { + implementation("androidx.core:core-ktx:1.12.0") + implementation("androidx.appcompat:appcompat:1.6.1") + implementation("com.google.android.material:material:1.9.0") + implementation("androidx.constraintlayout:constraintlayout:2.1.4") + + implementation("androidx.room:room-runtime:2.5.2") + implementation("androidx.room:room-ktx:2.5.2") + ksp("androidx.room:room-compiler:2.5.2") + + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") +} diff --git a/gradle.properties b/gradle.properties index bb418d3..f4afbc3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -34,4 +34,4 @@ android.nonTransitiveRClass=true android.suppressUnsupportedCompileSdk=34 # Use JDK 17 for the build -org.gradle.java.home=/usr/lib/jvm/java-17-openjdk \ No newline at end of file + diff --git a/settings.gradle.kts b/settings.gradle.kts index ece142d..cdc6f0d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,8 +1,8 @@ pluginManagement { repositories { + gradlePluginPortal() google() mavenCentral() - gradlePluginPortal() } }