pluginManagement dynamic version

I have a gradle plugin I’d like to use in more than one project. I’ve uploaded it to artifactory. In the past I was able to use dynamic dependencies with the classpath configuration of the buildscript block, but I’m trying to adopt the new plugins {} functionality, and gradle is complaining saying that “dynamic plugin versions are not supported.”

I tried searching around the forum and couldn’t find if anyone had found a workaround for this limitation. I guess I could use the old way of doing things, but I’m feeling motivated to try to adopt the newer API.

The plugins blocks that actually apply plugins are very restricted.
But to overcome this, you could use the pluginManagement { plugins { ... } } block in the settings script.
There you can define default versions for plugins and then in the actual build scripts you can apply the plugins without version.
In that block in the settings script, you can do dynamic calculations.

Be aware that adding plugins in the settings file in gradle 6 may have some undesired behavior. I had actually opened an issue with them some time ago Classpath leak from settings.gradle into projects buildscript classpath · Issue #13803 · gradle/gradle · GitHub . In a nutshell, plugins and their transitives versions as they come out from settings.gradle seem to now be enforced. Worse, you may not realize it, as if you try to print out the buildscript’s classpath from a project you are faced with the normal dependency resolution tree - except that if you try to debug gradle itself, you’ll find out it’s loading some other libraries. This I believe is in addition to gradle now seemingly “preferring” its own internal libraries when conflicts arise, too.

And your issue is related to the topic here how?
I did not recommend applying a plugin in the settings script or adding a plugin to the class path of the settings script which your problem is about.
Only defining the default plugin version does not trigger the behavior you warn about.

Replacing your buildscript block in the settings script of your reproducer by

pluginManagement {
    plugins {
        id "net.vivin.gradle-semantic-build-versioning" version "4.0.0"
    }
}
plugins {
    id "net.vivin.gradle-semantic-build-versioning"
}

also triggers the behavior you describe.
But removing the last three lines does not.
And even adding

plugins {
    id "net.vivin.gradle-semantic-build-versioning" apply false
}

to the actual build script does not cause the described behavior as then conflict resolution is done probably. (the apply false is there because it is a settings plugin, not a project plugin so cannot be applied, but those lines still add it to the class path)

Ideally, I’d be able to do something like this

    resolutionStrategy {
        eachPlugin {
            if (requested.id.namespace == 'org.samples') {
                if(requested.version == null) {
                      useModule("org.gradle:custom-plugin:+")
                }
            }
        }
    }

but as far as I can tell, this isn’t supported for things coming out of a private repo, which is really confusing that it wouldn’t be supported.

If it’s about the version, I would use the appropriate pluginManagement { plugins { ... . } } block. The resolution strategy I would only use to compensate missing marker artifacts.
But actually it should work fine, why shouldn’t it with with a private repo?

It sounds like I must be doing something wrong then. I have this in my settings.gradle:

pluginManagement {
  repositories {
    gradlePluginPortal()
    maven {
      url "my-artifactory-url"
    }
  }
  plugins {
    id "com.example.my.plugin" version "+"
  }
}

And then I’m using the plugin like this:

plugins {
  id "com.example.my.plugin"
}

and when I run ./gradlew tasks I get:

Starting a Gradle Daemon, 2 incompatible Daemons could not be reused, use --status for details

> Configure project :
Using JRE version 11.0.9 (Azul Systems, Inc. 11.0.9+11-LTS) from ***

FAILURE: Build failed with an exception.

* Where:
Build file '***build.gradle' line: 2

* What went wrong:
Plugin [id: 'com.example.my.plugin', version: '+'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (dynamic plugin versions are not supported)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 5s

Ah, ok.
According to the error message it seems dynamic versions are not possible.
I was not aware of that, as I would never use dynamic versions, sorry.
Then you are probably right with using the resolutionStrategy if you want a dynamic version.

That’s actually pretty interesting, I didn’t indeed try not to apply the plugin from the settings file. Strange behaviour, or maybe not. I think this may have been done to protect the classpath for the gradle enterprise plugin.

Not applying the plugin in your settings script is not really an option, as that plugin is a settings plugin, so can only applied there. The point just is, that your problem and thus your warning does not apply to this thread, as here we did not talk about applying a plugin in settings which is where you have problems with.

Actually if you upgrade to Gradle 7, the dynamic version for the plugin should work.
Gradle 7.0 release notes say:

Using dynamic versions in the plugins block

Until now, the plugins { } block only supported fixed versions for community plugins. All version string notations Gradle supports are now accepted, including + or latest.release .