Jacoco-report-aggregation with custom maven repository

I’m unsure if my problem is specific to the jacoco-report-aggregation plugin or just a misunderstanding of how multi-project Gradle works with private repositories. I have followed the instructions on how to setup the jacoco-report-aggregation plugin and I am using Gradle 7.4, and I get the following error in my Gradle project when trying to run the testCodeCoverageReport:

Execution failed for task ':code-coverage:testCodeCoverageReport'.
> Could not resolve all files for configuration ':code-coverage:allCodeCoverageReportClassDirectories'.
   > Could not find com.mycompany.common:util:1.1.
     Required by:
         project :code-coverage > project :app:projectA
         project :code-coverage > project :app:projectB
   > Could not find com.mycompany.common:logging:3.5.
     Required by:
         project :code-coverage > project :app:projectA
         project :code-coverage > project :app:projectB

my project structure is like this:

app/projectA
|----> build.gradle.kts
app/projectB
|----> build.gradle.kts
code-coverage
|--> build.gradle.kts
build.gradle.kts
settings.gradle.kts

my settings.gradle.kts sets a custom, private maven repository like below, the intent is to allow this private repository to be used across multiple projects.

pluginManagement {
    repositories {
        gradlePluginPortal()
        mavenCentral()
        maven {
            url = uri("https://pkgs.dev.azure.com/MYORG/_packaging/MYCOMPANYFEED/maven/v1")
            name = "mycompany"
            credentials {
                username ="TheUsername"
                password = fun(): String? {
                    val vstsMavenAccessToken: String? by settings
                    if (!vstsMavenAccessToken.isNullOrEmpty()) {
                        return vstsMavenAccessToken
                    }

                    var token : String? = System.getenv("SYSTEM_ACCESSTOKEN")
                    if (token != null && token != "") {
                        return token
                    }

                    token = System.getenv("AZDO_PERSONAL_ACCESS_TOKEN")
                    if (token != null && token != "") {
                        return token
                    }

                    throw GradleException ("Failed to find Azure Artifacts Personal Access Token.")
                }()
            }
        }
    }
}

rootProject.name = "my-broken-project"
// Subprojects
include(":app:projectB")
include(":app:projectA")

// For aggregate code coverage reporting
include(":code-coverage")

So what I see happening is that my projectA and projectB include the com.mycompany.common:logging and com.mycompany.common:util maven packages as dependencies, and this works just fine as long as I don’t enable the code-coverage project. But as soon as the code-coverage project gets added for some reason it wants to inspect those packages and for some reason it isn’t able to get them. I’m not understanding why.

My workaround is to update the code-coverage/build.gradle.kts with the snippet below, which is ALMOST an exact duplicate of what is in the settings.gradle.kts…and it works… but I just hate to have duplicate code hanging around my Gradle setup.

    repositories {
        gradlePluginPortal()
        mavenCentral()
        maven {
            url = uri("https://pkgs.dev.azure.com/MYORG/_packaging/MYCOMPANYFEED/maven/v1")
            name = "mycompany"
            credentials {
                username ="TheUsername"
                password = fun(): String? {
                    val vstsMavenAccessToken: String? by project
                    if (!vstsMavenAccessToken.isNullOrEmpty()) {
                        return vstsMavenAccessToken
                    }

                    var token : String? = System.getenv("SYSTEM_ACCESSTOKEN")
                    if (token != null && token != "") {
                        return token
                    }

                    token = System.getenv("AZDO_PERSONAL_ACCESS_TOKEN")
                    if (token != null && token != "") {
                        return token
                    }

                    throw GradleException ("Failed to find Azure Artifacts Personal Access Token.")
                }()
            }
        }
    }

Maybe there is a way I can de-duplicate so I only need to define the private repository in one place? I’m kind of confused because defining the private repository in the settings.gradle.kts allows me to have it defined in one place for my two sub projects, but for some reason it doesn’t work for the code-coverage project.

1 Like

You didn’t show your other build scripts, but you must have this repository already defined somewhere else. Because what show you have in the settings script is only in pluginManagement, it will only work for resolving plugins and plugin dependencies from, not normal project dependencies.

You can also define normal project dependency repositories in the settings script and then it is for all projects, but currently you most porobably have that repository defined in projectA and projectB build scripts, either directly or via some plugin you apply.

What I do in such cases in the settings script to not have it duplicated even therein if the repositories for plugins and project dependencies should be the same is like

// the plugin management block is evaluated first separately, do not change this to
// listOf(pluginManagement.repositories, dependencyResolutionManagement.repositories)
// instead that would change the semantics
pluginManagement {
    listOf(repositories, dependencyResolutionManagement.repositories).forEach { repositories ->
        repositories.apply {
            maven("https://nexus.company.com/repository/maven") {
                name = "Company Nexus"
            }
        }
    }
}