androidkotlinmavengradle

Android kotlin Failed to upload the mavne configured for all submodules in the root directory configuration, name 'release' not found


child module build.gradle.kts


group = "net.xxxx.xxxx"
version = "1.0.0"
plugins {
    alias(libs.plugins.android.library) //  com.android.library 8.7.3
    alias(libs.plugins.kotlin.android) // org.jetbrains.kotlin.android 2.1.0
}

android {
    namespace = "net.xxxx.xxxx"
    compileSdk = 34
    defaultConfig {
        minSdk = 21

        testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
        consumerProguardFiles("consumer-rules.pro")
    }

    buildTypes {

        release {
            isMinifyEnabled = false
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
        debug {
            isMinifyEnabled = false
        }
    }
    compileOptions {
        sourceCompatibility = JavaVersion.VERSION_17
        targetCompatibility = JavaVersion.VERSION_17
    }
    kotlinOptions {
        jvmTarget = "17"
    }
}
//afterEvaluate {
//    publishing {
//        publications {
//            create<MavenPublication>("release") {
//                println(components.asMap.keys)
//                from(components["release"])
//            }
//        }
//    }
//}
dependencies {
    implementation(libs.appcompat.v7)
    implementation(libs.retrofit)
    implementation(libs.okhttp3.loging.interceptor)
    implementation(libs.okhttp3.converter.gson)
    implementation(libs.woaoo.model)
    testImplementation(libs.junit)
    androidTestImplementation(libs.runner)
    androidTestImplementation(libs.espresso.core)
}

in the submodule project create("release") components can get[debug,release]

root build.gradle.kts

import com.android.build.gradle.internal.dsl.BaseAppModuleExtension
import io.gitlab.arturbosch.detekt.Detekt

// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
    alias(libs.plugins.android.application) apply false
    alias(libs.plugins.kotlin.android) apply false
    alias(libs.plugins.jetbrains.kotlin.jvm) apply false
    alias(libs.plugins.arturbosch.detekt)
    alias(libs.plugins.android.library) apply false
    id("maven-publish")
}

subprojects {
    apply(plugin = "io.gitlab.arturbosch.detekt")
    apply(plugin = "maven-publish")

    detekt {
        source.from(files("src/main/java", "src/main/kotlin"))
        buildUponDefaultConfig = true
        allRules = false
        disableDefaultRuleSets = false
        debug = false
        parallel = false
    }

    tasks.withType<Detekt>().configureEach {
        reports {
            html.required.set(true)
            xml.required.set(true)
            txt.required.set(true)
            sarif.required.set(true)
        }
    }
    afterEvaluate {
        if (plugins.hasPlugin("com.android.library")) {
            publishing {
                publications {
                    println(components.asMap.keys)
                    create<MavenPublication>("${project.name}Release") {
                        artifactId = project.name 
                        if (artifactId == "app") return@create
                        val isJavaLib = components.asMap.keys.contains("kotlin")
                        if (isJavaLib) {
                            from(project.components.getByName("kotlin"))
                        } else {
                        from(components["release"]) 
                        }
                        groupId = project.group.toString() // 使用项目组作为 groupId
                        version = project.version.toString() // 使用项目版本作为 version
                    }
                }
//            repositories {
//                maven {
//                    isAllowInsecureProtocol = true
//                    name = "release"
//                    url = uri("http://xxxxxxx/repository/maven-releases")
//                    credentials {
//                        username = "xxxxx"
//                        password = "xxxxxxxx"
//                    }
//                }
            }
        }

    }
}
}

sync project will get a error and components is [] empty

* What went wrong:
A problem occurred configuring project ':xxxxx'.
> SoftwareComponent with name 'release' not found.

What I want to achieve is a unified configuration of maven packaging in the root directory, there are two sub-modules Java libray and Android library, and now the Java library is normal


Solution

  • I have solved in this way. method invoke sequence is subprojects.afterEvaluate -> child.afterEvaluate. the components is create at child.afterEvaluate,so we can not get 'release' in subprojects.afterEvaluate,use gradle.projectsEvaluated is invoke after child.afterEvaluate

    import io.gitlab.arturbosch.detekt.Detekt
    
    // Top-level build file where you can add configuration options common to all sub-projects/modules.
    plugins {
        alias(libs.plugins.android.application) apply false
        alias(libs.plugins.kotlin.android) apply false
        alias(libs.plugins.jetbrains.kotlin.jvm) apply false
        alias(libs.plugins.arturbosch.detekt)
        alias(libs.plugins.android.library) apply false
        id("maven-publish")
    }
    gradle.projectsEvaluated {
        subprojects {
            detekt {
                source.from(files("src/main/java", "src/main/kotlin"))
                buildUponDefaultConfig = true
                allRules = false
                disableDefaultRuleSets = false
                debug = false
                parallel = false
            }
    
            tasks.withType<Detekt>().configureEach {
                reports {
                    html.required.set(true)
                    xml.required.set(true)
                    txt.required.set(true)
                    sarif.required.set(true)
                }
            }
            publishing {
                publications {
                    create<MavenPublication>("${project.name}Release") {
                        if (artifactId == "app") return@create
                        val isJavaLib = components.asMap.keys.contains("kotlin")
                        if (isJavaLib) {
                            from(components.getByName("kotlin"))
                        } else {
                            from(components.getByName("release"))
                        }
                        groupId = project.group.toString() 
                        version = project.version.toString() 
                    }
                    create<MavenPublication>("${project.name}snapshot") {
                        artifactId = project.name 
                        if (artifactId == "app") return@create
                        val isJavaLib = components.asMap.keys.contains("kotlin")
                        if (isJavaLib) {
                            from(components.getByName("kotlin"))
                        } else {
                            from(components.getByName("release"))
                        }
                        groupId = project.group.toString() 
                        version = "${project.version}-SNAPSHOT"
                    }
                }
                repositories {
                    maven {
                        isAllowInsecureProtocol = true
                        name = "release"
                        url = uri("xxxxxxx")
                        credentials {
                            username = "xxxxx"
                            password = "xxxxxxxxxx"
                        }
                    }
                    maven {
                        isAllowInsecureProtocol = true=
                        name = "snapshot"
                        url = uri("http://xxxxxxxxx")
                        credentials {
                            username = "xxxxxx"
                            password = "xxxxxxxxx"
                        }
                    }
                }
            }
        }
    }
    
    subprojects {
        apply(plugin = "io.gitlab.arturbosch.detekt")
        apply(plugin = "maven-publish")
    }