feat: add product flavors (termux/embedded) with loader-noop module and FlavorModule DI

Introduce Gradle product flavors to separate termux and embedded build variants.
Each flavor provides its own FlavorModule for DI wiring. CI workflows updated
to build termuxRelease specifically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kohei 2026-02-28 20:04:15 +09:00
parent b790a63e7d
commit 69cdd2e60a
9 changed files with 61 additions and 7 deletions

View file

@ -51,10 +51,10 @@ jobs:
EOF EOF
- name: Build release APK - name: Build release APK
run: ./gradlew assembleRelease run: ./gradlew assembleTermuxRelease
- name: Upload APK - name: Upload APK
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: clawdroid-release-apk name: clawdroid-release-apk
path: android/app/build/outputs/apk/release/*.apk path: android/app/build/outputs/apk/termuxRelease/*.apk

View file

@ -120,16 +120,16 @@ jobs:
EOF EOF
- name: Build release APK - name: Build release APK
run: ./gradlew assembleRelease run: ./gradlew assembleTermuxRelease
- name: Rename APK with version - name: Rename APK with version
run: | run: |
mv app/build/outputs/apk/release/app-release.apk \ mv app/build/outputs/apk/termuxRelease/app-termux-release.apk \
app/build/outputs/apk/release/clawdroid-${{ inputs.tag }}.apk app/build/outputs/apk/termuxRelease/clawdroid-${{ inputs.tag }}.apk
- name: Upload APK to release - name: Upload APK to release
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: | run: |
gh release upload "${{ inputs.tag }}" \ gh release upload "${{ inputs.tag }}" \
app/build/outputs/apk/release/clawdroid-${{ inputs.tag }}.apk app/build/outputs/apk/termuxRelease/clawdroid-${{ inputs.tag }}.apk

View file

@ -49,8 +49,20 @@ android {
} }
} }
flavorDimensions += "variant"
productFlavors {
create("termux") { dimension = "variant" }
create("embedded") { dimension = "variant" }
}
buildFeatures { buildFeatures {
compose = true compose = true
buildConfig = true
}
sourceSets {
getByName("termux") { java.srcDirs("src/termux/java") }
getByName("embedded") { java.srcDirs("src/embedded/java") }
} }
compileOptions { compileOptions {
@ -67,6 +79,8 @@ dependencies {
implementation(project(":backend:api")) implementation(project(":backend:api"))
implementation(project(":backend:config")) implementation(project(":backend:config"))
"termuxImplementation"(project(":backend:loader-noop"))
implementation(platform(libs.compose.bom)) implementation(platform(libs.compose.bom))
implementation(libs.compose.ui) implementation(libs.compose.ui)
implementation(libs.compose.material3) implementation(libs.compose.material3)

View file

@ -0,0 +1,10 @@
package io.clawdroid.di
import io.clawdroid.backend.api.BackendLifecycle
import io.clawdroid.backend.api.NoopBackendLifecycle
import org.koin.dsl.module
val flavorModule = module {
// Step 13 で EmbeddedBackendLifecycle に差し替え予定
single<BackendLifecycle> { NoopBackendLifecycle() }
}

View file

@ -7,6 +7,7 @@ import io.clawdroid.backend.config.ConfigApiClient
import io.clawdroid.backend.config.configModule import io.clawdroid.backend.config.configModule
import io.clawdroid.core.data.remote.WebSocketClient import io.clawdroid.core.data.remote.WebSocketClient
import io.clawdroid.di.appModule import io.clawdroid.di.appModule
import io.clawdroid.di.flavorModule
import io.clawdroid.receiver.NotificationHelper import io.clawdroid.receiver.NotificationHelper
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@ -23,7 +24,7 @@ class ClawDroidApp : Application() {
super.onCreate() super.onCreate()
val koinApp = startKoin { val koinApp = startKoin {
androidContext(this@ClawDroidApp) androidContext(this@ClawDroidApp)
modules(appModule, configModule) modules(appModule, flavorModule, configModule)
} }
NotificationHelper.createNotificationChannel(this) NotificationHelper.createNotificationChannel(this)

View file

@ -0,0 +1,9 @@
package io.clawdroid.di
import io.clawdroid.backend.api.BackendLifecycle
import io.clawdroid.backend.api.NoopBackendLifecycle
import org.koin.dsl.module
val flavorModule = module {
single<BackendLifecycle> { NoopBackendLifecycle() }
}

View file

@ -0,0 +1,17 @@
plugins {
alias(libs.plugins.android.library)
}
android {
namespace = "io.clawdroid.backend.loader.noop"
compileSdk = libs.versions.android.compileSdk.get().toInt()
defaultConfig { minSdk = libs.versions.android.minSdk.get().toInt() }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
dependencies {
implementation(project(":backend:api"))
}

View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View file

@ -20,3 +20,4 @@ include(":core:data")
include(":core:ui") include(":core:ui")
include(":backend:api") include(":backend:api")
include(":backend:config") include(":backend:config")
include(":backend:loader-noop")