Skip to content
Draft
23 changes: 12 additions & 11 deletions example/androidlib/java/1-hello-world/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ object app extends AndroidAppModule {
def androidApplicationId = "com.helloworld.app"
def androidApplicationNamespace = "com.helloworld.app"

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

override def androidVirtualDeviceIdentifier: String = "java-test"

object test extends AndroidAppTests, TestModule.Junit4 {
Expand All @@ -57,6 +46,18 @@ object app extends AndroidAppModule {
)
}

object release extends AndroidReleaseModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
Copy link
Contributor

@vaslabs vaslabs Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with this change, we should remove the defaults and avoid the comment above

def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
}

//// SNIPPET:END
Expand Down
2 changes: 2 additions & 0 deletions example/androidlib/java/2-app-bundle/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ object bundle extends AndroidAppBundle {
def androidApplicationId = "com.helloworld.app"
def androidApplicationNamespace = "com.helloworld.app"

object release extends AndroidReleaseModule

def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
Expand Down
28 changes: 12 additions & 16 deletions example/androidlib/java/5-R8/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,7 @@ object app extends AndroidR8AppModule { // <2>
def androidApplicationId = "com.helloworld.app"
def androidApplicationNamespace = "com.helloworld.app"

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

override def androidVirtualDeviceIdentifier: String = "java-test"
override def androidIsDebug: T[Boolean] = Task { false }

def androidProjectProguardFiles = Task.Sources(
"proguard-rules.pro"
Expand All @@ -60,10 +48,6 @@ object app extends AndroidR8AppModule { // <2>
object it extends AndroidAppInstrumentedTests, AndroidR8AppModule {
def androidSdkModule = mill.api.ModuleRef(androidSdkModule0)

override def androidIsDebug: T[Boolean] = Task {
false
}

override def androidReleaseSettings: T[AndroidBuildTypeSettings] = Task {
AndroidBuildTypeSettings(isMinifyEnabled = false)
}
Expand All @@ -80,6 +64,18 @@ object app extends AndroidR8AppModule { // <2>
)
}

object release extends AndroidR8ReleaseModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
}

// <1> Create and configure an Android SDK module to manage Android SDK paths and tools.
Expand Down
23 changes: 13 additions & 10 deletions example/androidlib/java/6-native-libs/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ object app extends AndroidNativeAppModule { // <1>
def androidApplicationId = "com.helloworld.app"
def androidApplicationNamespace = "com.helloworld.app"

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

override def androidVirtualDeviceIdentifier: String = "java-test"

def androidExternalNativeLibs = Task { // <2>
Expand All @@ -58,6 +48,19 @@ object app extends AndroidNativeAppModule { // <1>
)
}

object release extends AndroidReleaseModule, AndroidNativeAppVariantModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

}

// <1> You need to extend AndroidNativeLibs trait to use native libraries in the app.
Expand Down
23 changes: 13 additions & 10 deletions example/androidlib/kotlin/1-hello-kotlin/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,6 @@ object app extends AndroidAppKotlinModule {
def androidApplicationId = "com.helloworld.app"
def androidApplicationNamespace = "com.helloworld.app"

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
override def androidVirtualDeviceIdentifier: String = "kotlin-test"
override def androidEmulatorPort: String = "5556"

Expand Down Expand Up @@ -65,6 +55,19 @@ object app extends AndroidAppKotlinModule {
mvn"junit:junit:4.13.2"
)
}

object release extends AndroidKotlinReleaseModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
}

//// SNIPPET:END
Expand Down
Binary file not shown.
7 changes: 7 additions & 0 deletions example/androidlib/kotlin/2-compose/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ object app extends AndroidAppKotlinModule {
mvn"androidx.tracing:tracing:1.2.0"
)

object release extends AndroidKotlinReleaseModule

def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

}

//// SNIPPET:END
Expand Down
24 changes: 13 additions & 11 deletions example/androidlib/kotlin/4-sum-lib-kotlin/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,6 @@ object lib extends AndroidLibKotlinModule, PublishModule {
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }

object test extends AndroidLibKotlinTests, TestModule.Junit4 {
def junit4Version = "4.13.2"
}
Expand Down Expand Up @@ -80,6 +69,19 @@ object app extends AndroidAppKotlinModule {
object test extends AndroidAppKotlinTests, TestModule.Junit4 {
def junit4Version = "4.13.2"
}

object release extends AndroidKotlinReleaseModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
}

//// SNIPPET:END
Expand Down
28 changes: 11 additions & 17 deletions example/thirdparty/android-endless-tunnel/build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,23 @@ object `endless-tunnel` extends mill.api.Module {

override def androidNativeLibName: T[String] = "libgame"

override def androidVirtualDeviceIdentifier: String = "cpp-test"

override def androidCMakeExtraArgs: T[Seq[String]] =
super.androidCMakeExtraArgs() ++ Seq("-DANDROID_STL=c++_static")

object release extends AndroidReleaseModule, AndroidNativeAppVariantModule

/**
* Configuration for ReleaseKey
* WARNING: Replace these default values with secure and private credentials before using in production.
* Never use these defaults in a production environment as they are not secure.
* This is just for testing purposes.
*/
def androidReleaseKeyAlias: T[Option[String]] = Task {
Some("releaseKey")
}

def androidReleaseKeyPass: T[Option[String]] = Task {
Some("MillBuildTool")
}

def androidReleaseKeyStorePass: T[Option[String]] = Task {
Some("MillBuildTool")
}

override def androidVirtualDeviceIdentifier: String = "cpp-test"

override def androidCMakeExtraArgs: T[Seq[String]] =
super.androidCMakeExtraArgs() ++ Seq("-DANDROID_STL=c++_static")

def androidReleaseKeyName: Option[String] = Some("releaseKey.jks")
def androidReleaseKeyAlias: T[Option[String]] = Task { Some("releaseKey") }
def androidReleaseKeyPass: T[Option[String]] = Task { Some("MillBuildTool") }
def androidReleaseKeyStorePass: T[Option[String]] = Task { Some("MillBuildTool") }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,4 +333,11 @@ trait AndroidAppKotlinModule extends AndroidKotlinModule, AndroidAppModule { out

}

trait AndroidAppKotlinVariantModule extends AndroidKotlinVariantModule, AndroidAppKotlinModule {
override def sources: T[Seq[PathRef]] = outer.sources
override def resolutionParams: Task[ResolutionParams] = Task.Anon(outer.resolutionParams())
}

trait AndroidKotlinReleaseModule extends AndroidReleaseModule, AndroidAppKotlinVariantModule

}
27 changes: 21 additions & 6 deletions libs/androidlib/src/mill/androidlib/AndroidAppModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,27 @@ trait AndroidAppModule extends AndroidModule { outer =>
)
}

trait AndroidAppVariantModule extends AndroidVariantModule, AndroidAppModule {
override def androidApplicationId: String = outer.androidApplicationId
override def androidApplicationNamespace: String = outer.androidApplicationNamespace

override def androidVirtualDeviceIdentifier: String = outer.androidVirtualDeviceIdentifier
}

trait AndroidReleaseModule extends AndroidAppVariantModule, AndroidAppModule {
override def androidReleaseKeyAlias: T[Option[String]] = outer.androidReleaseKeyAlias()

override def androidReleaseKeyName: Option[String] = outer.androidReleaseKeyName

override def androidReleaseKeyPass: T[Option[String]] = outer.androidReleaseKeyPass()

override def androidReleaseKeyStorePass: T[Option[String]] = outer.androidReleaseKeyStorePass()

override def androidReleaseKeyPath: T[Seq[PathRef]] = outer.androidReleaseKeyPath()

override def androidIsDebug: T[Boolean] = Task { false }
}

trait AndroidAppTests extends AndroidTestModule, AndroidAppModule {
override def androidApplicationId: String = s"${outer.androidApplicationId}.test"
override def androidApplicationNamespace: String = s"${outer.androidApplicationNamespace}.test"
Expand All @@ -900,12 +921,6 @@ trait AndroidAppModule extends AndroidModule { outer =>
override def androidApplicationId: String = s"${outer.androidApplicationId}.test"
override def androidApplicationNamespace: String = s"${outer.androidApplicationNamespace}.test"

override def androidReleaseKeyAlias: T[Option[String]] = outer.androidReleaseKeyAlias()
override def androidReleaseKeyName: Option[String] = outer.androidReleaseKeyName
override def androidReleaseKeyPass: T[Option[String]] = outer.androidReleaseKeyPass()
override def androidReleaseKeyStorePass: T[Option[String]] = outer.androidReleaseKeyStorePass()
override def androidReleaseKeyPath: T[Seq[PathRef]] = outer.androidReleaseKeyPath()

override def androidEmulatorPort: String = outer.androidEmulatorPort

override def sources: T[Seq[PathRef]] = Task.Sources("src/androidTest/java")
Expand Down
8 changes: 8 additions & 0 deletions libs/androidlib/src/mill/androidlib/AndroidKotlinModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,14 @@ trait AndroidKotlinModule extends KotlinModule with AndroidModule { outer =>
jars
}

trait AndroidKotlinVariantModule extends AndroidVariantModule, AndroidKotlinModule {
override def kotlinVersion: T[String] = outer.kotlinVersion()
override def androidEnableCompose: T[Boolean] = outer.androidEnableCompose()
override def generatedSources: T[Seq[PathRef]] = outer.generatedSources()
override def androidCompiledModuleResources: T[Seq[PathRef]] =
outer.androidCompiledModuleResources()
}

trait AndroidKotlinTestModule extends KotlinTests, AndroidTestModule {
override def kotlinVersion: T[String] = outer.kotlinVersion

Expand Down
30 changes: 30 additions & 0 deletions libs/androidlib/src/mill/androidlib/AndroidModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,36 @@ trait AndroidModule extends JavaModule { outer =>
None
}

trait AndroidVariantModule extends AndroidModule {
override def androidCompileSdk: T[Int] = outer.androidCompileSdk()

override def androidMinSdk: T[Int] = outer.androidMinSdk()

override def androidTargetSdk: T[Int] = outer.androidTargetSdk()

override def androidSdkModule: ModuleRef[AndroidSdkModule] = outer.androidSdkModule

override def androidManifest: T[PathRef] = outer.androidManifest()

override def moduleDir: os.Path = outer.moduleDir

override def androidNamespace: String = outer.androidNamespace

override def sources: T[Seq[PathRef]] = outer.sources()

override def androidResources: T[Seq[PathRef]] = outer.androidResources()

override def mvnDeps: T[Seq[Dep]] = outer.mvnDeps()

override def runMvnDeps: T[Seq[Dep]] = outer.runMvnDeps()

override def compileMvnDeps: T[Seq[Dep]] = outer.compileMvnDeps()

override def moduleDeps: Seq[JavaModule] = outer.moduleDeps

override def bomMvnDeps: T[Seq[Dep]] = outer.bomMvnDeps()
}

trait AndroidTestModule extends JavaTests, AndroidModule {

override def androidCompileSdk: T[Int] = outer.androidCompileSdk()
Expand Down
14 changes: 13 additions & 1 deletion libs/androidlib/src/mill/androidlib/AndroidNativeAppModule.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import mill.T
import mill.api.{PathRef, Task}

@mill.api.experimental
trait AndroidNativeAppModule extends AndroidAppModule {
trait AndroidNativeAppModule extends AndroidAppModule { outer =>

def androidNativeSource: T[PathRef] = Task.Source {
moduleDir / "src/main/cpp"
Expand Down Expand Up @@ -123,7 +123,19 @@ trait AndroidNativeAppModule extends AndroidAppModule {
*/
override def androidPackageableExtraFiles: T[Seq[AndroidPackageableExtraFile]] = Task {
super.androidPackageableExtraFiles() ++ androidPackageableNativeLibs()
}

trait AndroidNativeAppVariantModule extends AndroidAppVariantModule, AndroidNativeAppModule {

override def androidNativeSource: T[PathRef] = outer.androidNativeSource()

override def androidExternalNativeLibs: T[Seq[PathRef]] = outer.androidExternalNativeLibs()

override def androidNativeLibName: T[String] = outer.androidNativeLibName()

override def androidCMakeExtraArgs: T[Seq[String]] = outer.androidCMakeExtraArgs()

override def androidCompileNative: T[PathRef] = outer.androidCompileNative()
}

}
Loading