Android Library Publishing
If you have an Android library that you want to publish to a repository like Maven Central, you can follow the steps outlined in this page to build and publish your library using Mill.
Example Android Library Publishing Workflow
This section demonstrates how to set up an Android library module written in Kotlin for publishing.
In addition to AndroidKotlinModule, we utilize AndroidLibModule, which extends PublishModule to enable seamless
library building (AAR artifact) and local publishing with minimal configuration.
package build
import mill.*, androidlib.*, kotlinlib.*
import coursier.maven.MavenRepository
import publish.*
Create and configure an Android SDK module to manage Android SDK paths and tools.
object androidSdkModule0 extends AndroidSdkModule {
def buildToolsVersion = "35.0.0"
}
object lib extends AndroidKotlinModule, AndroidLibModule {
def artifactName = "sumlib-kotlin"
def androidSdkModule = mill.api.ModuleRef(androidSdkModule0)
def androidMinSdk = 19
def androidCompileSdk = 35
def kotlinVersion = "2.0.20"
def androidLibPackage = "com.example"
def publishVersion = "0.0.1"
def pomSettings = PomSettings(
description = "sumlib-kotlin",
organization = "com.example.sumlib",
url = "https://github.com/lihaoyi/example",
licenses = Seq(License.MIT),
versionControl = VersionControl.github("lihaoyi", "example"),
developers = Seq(Developer("lihaoyi", "Li Haoyi", "https://github.com/lihaoyi"))
)
object test extends AndroidKotlinTestModule, TestModule.Junit4 {
def junit4Version = "4.13.2"
}
}
object app extends AndroidAppKotlinModule {
def kotlinVersion = "2.0.20"
def androidSdkModule = mill.api.ModuleRef(androidSdkModule0)
def androidMinSdk = 19
def androidCompileSdk = 35
def androidApplicationId = "com.example.app"
def androidApplicationNamespace = "com.example.app"
override def repositoriesTask = Task.Anon {
super.repositoriesTask() ++ Seq(
MavenRepository("file://" + sys.props("user.home") + "/.m2/repository")
)
}
def mvnDeps = Seq(mvn"com.example.sumlib:sumlib-kotlin:0.0.1")
object test extends AndroidAppKotlinTests, TestModule.Junit4 {
def junit4Version = "4.13.2"
}
}
This command triggers the build process, which create the library AAR and publish it locally at ~/.m2/repository
Project Structure:
The project follows the standard Android app layout. Below is a typical project folder structure:
. ├── app │ └── src │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java/com/example/SampleLogic.kt | | └── kotlin/com/example/SampleLogicKotlinDir.kt │ │ └── res │ │ └── values │ │ ├── colors.xml │ │ └── strings.xml │ └── test/java/com/example/ExampleUnitTest.kt │ └── test/kotlin/com/example/ExampleUnitTestInKotlinDir.kt ├── lib │ └── src │ └── main │ ├── AndroidManifest.xml │ | └── kotlin/com/example/Sum.kt | | └── res | | └── values | | ├── colors.xml | | └── strings.xml | └── test/java/com/example/SumUnitTest.kt └── build.mill
> ./mill show lib.test
{
"msg": "",
"results": [
{
"fullyQualifiedName": "com.example.SumLibUnitTest.kotlin_dir_text_size_is_correct",
"selector": "com.example.SumLibUnitTest.kotlin_dir_text_size_is_correct",
"duration": ...,
"status": "Success"
}
]
}
> ./mill lib.publishM2Local
Publish sumlib-kotlin-0.0.1 to /home/.../.m2/repository/...
> ./mill show lib.publishArtifacts
{
"meta": {
"group": "com.example.sumlib",
"id": "sumlib-kotlin",
"version": "0.0.1"
},
"payload": [
[
".../out/lib/androidAar.dest/library.aar",
"sumlib-kotlin-0.0.1.aar"
],
...
This command runs unit tests on your local environment.
> ./mill show app.test
...
{
"msg": " ",
"results": [
{
"fullyQualifiedName": "com.example.ExampleUnitTest.text_size_is_correct",
"selector": "com.example.ExampleUnitTest.text_size_is_correct",
"duration": ...,
"status": "Success"
},
{
"fullyQualifiedName": "com.example.ExampleUnitTestInKotlinDir.kotlin_dir_sum_is_correct",
"selector": "com.example.ExampleUnitTestInKotlinDir.kotlin_dir_sum_is_correct",
"duration": ...,
"status": "Success"
},
{
"fullyQualifiedName": "com.example.ExampleUnitTestInKotlinDir.kotlin_dir_text_size_is_correct",
"selector": "com.example.ExampleUnitTestInKotlinDir.kotlin_dir_text_size_is_correct",
"duration": ...,
"status": "Success"
}
]
}
...