External plugin (nebula.release) cannot be applied in precompiled script plugin

Hi,

I am having trouble, adding an external plugin (nebula.release) to my precompiled script plugin. As stated in the documentation, I added the nebula-release-plugin dependency in the root build.gradle.kts file as an implementation dependency but when I try to build the project with ./gradlew clean check it fails with the following errors:

> Task :generatePrecompiledScriptPluginAccessors
Git repository not found at /Users/somebody/Projects/git.acme.com/gradle-plugins/build/tmp/generatePrecompiledScriptPluginAccessors/accessors3038685752906344908 -- nebula-release tasks will not be available. Use the git.root Gradle property to specify a different directory.

> Task :compileKotlin FAILED
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (6, 1): Unresolved reference: nebulaRelease
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (7, 5): Unresolved reference: addReleaseBranchPattern
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (40, 1): Expression 'release' cannot be invoked as a function. The function 'invoke()' is not found
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (40, 1): Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
internal val ComNetflixNebulaPluginGroup.release: PluginDependencySpec defined in gradle.kotlin.dsl.plugins._a06f7d6c83541c827fbf1cfda5baf9c1 in file PluginSpecBuilders.kt
internal val NebulaPluginGroup.release: PluginDependencySpec defined in gradle.kotlin.dsl.plugins._a06f7d6c83541c827fbf1cfda5baf9c1 in file PluginSpecBuilders.kt
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (40, 11): Unresolved reference: finalizedBy
e: /Users/somebody/Projects/git.acme.com/gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts: (40, 24): Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
internal val TaskContainer.publish: TaskProvider<DefaultTask> defined in gradle.kotlin.dsl.accessors._b7719bb009bf77985775c5b9fa4e40d9 in file Accessorsb13nju9doius8kxwhlptqirtr.kt

My gradle scripts look liek the following:

gradle-plugins/build.gradle.kts

plugins {
    `kotlin-dsl`
    `kotlin-dsl-precompiled-script-plugins`
    `maven-publish`
    id("pl.allegro.tech.build.axion-release") version "1.14.0"
}

repositories {
    mavenCentral()
}

group = "com.acme"
version = scmVersion.version

dependencies {
    implementation("com.netflix.nebula:nebula-release-plugin:17.1.0")
}

publishing {
    repositories {
        maven {
            url = uri("https://git.acme.com/api/v4/projects/1388/packages/maven")
            name = "Acme.com-GitLab"
            credentials(HttpHeaderCredentials::class) {
                name = "Job-Token"
                value = System.getenv("CI_JOB_TOKEN")
            }
            authentication {
                create<HttpHeaderAuthentication>("header")
            }
        }
    }
}

gradle-plugins/src/main/kotlin/com.acme.publish.gradle.kts

plugins {
    `maven-publish`
    id("nebula.release")
}

nebulaRelease {
    addReleaseBranchPattern("develop")
}

publishing {
    publications {
        create<MavenPublication>("maven") {
            groupId = "com.acme"
            artifactId = project.name
            from(components["java"])
        }
    }
    repositories {
        maven {
            val repoName = "Acme.com-GitLab"
            val projectId = System.getenv("CI_PROJECT_ID")
            val repoUrl = "https://git.acme.com/api/v4/projects/${projectId}/packages/maven"
            val runsOnCi = System.getenv().containsKey("CI")
            val tokenType = if (runsOnCi) { "Job-Token" } else { "Private-Token" }
            val accessToken = if (runsOnCi) { System.getenv("CI_JOB_TOKEN") } else { System.getenv("GITLAB_API_TOKEN") }

            url = uri(repoUrl)
            name = repoName
            credentials(HttpHeaderCredentials::class) {
                name = tokenType
                value = accessToken
            }
            authentication {
                create<HttpHeaderAuthentication>("header")
            }
        }
    }
}

release { finalizedBy (publish) }

Any help is appreciated :slight_smile:

Well, that plugin is obviously not compatible with being applied in the plugins { ... } block of a precompiled script plugin.
You should open a feature request with them.

The plugins { ... } block of a precompiled script plugin is transplanted to a dummy project that is then evaluated and investigated to find out which typesafe accessors for Kotlin DSL should be generated.

But as that plugin does an early-out at nebula-release-plugin/ReleasePlugin.groovy at main · nebula-plugins/nebula-release-plugin · GitHub before any tasks or extensions are added, no typesafe accessors are generated and you only get that warning during the accessor determination step.

To get rid of that warning you would need to apply the plugin the legacy way using apply instead of the plugins { ... } block.
To make your plugin compile and work, you need to use the uglier longer raw version instead of the accessors, so replace nebulaRelease { by configure<ReleaseExtension> {.

Thanks for the clarification! In the meantime I played around with the axion-release-plugin and the same mechanics worked out of the box. Maybe we’ll consider a switch to axion.

I also added an issue in the nebula github repository. So far it did not receive much attention though. Is there any migration available that shows how to migrate old plugins to the new style?

No, because most plugins will simply work with the new system.
What the problem is with that plugin, I described above.