Configuring Maven Publish based on another plugin data

I am creating a sort of orchestration plugin: a plugin that we use for some internal projects and that should simplify the configuration of our builds, by checking other plugins are present and configure them.

As part of this plugin I have an extension. In this extension I set some values and these values should then be used to define publications.

For example:

configure<StarLasuPluginExtension> {
    githubName.set("/plsql-to-java-transpiler")
    packageName.set("extendedsqlparser")
    moduleName.set("extendedsqlparser") // this is used as the name of an artifact to be published
}

In my plugin I have this code:

publishingExtension.publications {
                create<MavenPublication>(extension.moduleName.get()) {
                    from(this@setupPublication.components["java"])
                    groupId = "com.strumenta"
                    artifactId = extension.moduleName.get()
     }
}

Now, the project is that when I configure the plugin the data has not yet been loaded by the extension, so this does not work.

I then tried to add this in the doFirst of publishToMavenLocal:

    tasks.named("publishToMavenLocal") {
        tasks.find { it.name == "sourcesJar" }?.let { sourcesJar ->
            dependsOn(sourcesJar)
        }
        doFirst {
            publishingExtension.publications {
                create<MavenPublication>(extension.moduleName.get()) {
                ...

This does not work because adding a publication also create a corresponding task that it is added as a dependency of publishToMavenLocal and that cause an error.

I also tried creating a task called preparePublishToMavenLocal and set the configuration there and then decleare publishToMavenLocal to depend on preparePublishToMavenLocal but also that does not work, as it is too late for publishToMavenLocal to take into account the new dependency added.

Is there a pattern to solve this kind of problems?

As you found, you should not try to create (or do something that creates) tasks at execution time.

You should also not change the configuration of a task during its own execution phase.

You can indeed configure one task from the execution phase of another task, but only as long as you do not use the shiny new configuration cache, as this pattern is illegal with the configuration cache, so should generally also be avoided to be more future proof.

From your description I guess you add that extension and then try to use its values right away, before the consumer had a chance to configure the extension.
Generally, you should have lazy stuff in your extensions and then wire properties together to avoid such problems.

In your concrete case this does of course not work.
Instead I’d recommend you make a function in your extension.
This function is then called by the consumer.
And in that function you can do the necessary configuration with the consumer-supplied value.