Vlastimil Brecka
07/11/2026, 2:49 PM./gradlew check :appA:assemble
but as a explicit buildAppA task?
I really hate pushing complexity/impl details into cli / ci configs. It does not scale. Its what tasks are forVampire
07/11/2026, 3:00 PMVlastimil Brecka
07/11/2026, 3:01 PMVampire
07/11/2026, 3:04 PMlifecycle-base task, you can just depend on all check tasks in all projects.Vlastimil Brecka
07/11/2026, 3:05 PMVlastimil Brecka
07/11/2026, 3:06 PM./gradlew :appA:buildWhatever would be the syntaxVlastimil Brecka
07/11/2026, 3:08 PMbuildAppA in root, its the same thing, isnt it? check is refering to this project's (root) checkVlastimil Brecka
07/11/2026, 3:10 PMVampire
07/11/2026, 3:21 PMtasks.register("buildWhatever") {
rootProject.allProjects.forEach { dependsOn("${it.path}:check") }
}
(Written from head, so might need some fix)Vlastimil Brecka
07/11/2026, 3:27 PMVampire
07/11/2026, 3:34 PMVlastimil Brecka
07/11/2026, 3:36 PMVlastimil Brecka
07/11/2026, 3:36 PMVlastimil Brecka
07/11/2026, 3:36 PMVampire
07/11/2026, 3:40 PMokay but that requires the task to exist on those projects for sure, right?
Yes. That's why I said "Given all projects apply at least the
lifecycle-base plugin"
or can I make it optional?
Not in that construct, no.
Vlastimil Brecka
07/11/2026, 3:40 PMVampire
07/11/2026, 3:45 PMVlastimil Brecka
07/11/2026, 3:45 PMVampire
07/11/2026, 3:45 PMVampire
07/11/2026, 3:46 PMVlastimil Brecka
07/11/2026, 3:46 PMVampire
07/11/2026, 3:49 PMLuke Bemish
07/14/2026, 5:00 PMcheck task of each subproject in an outgoing variant of that project with certain attributes. Then, your bulk task can depend on a lenient artifact view of a configuration with project deps on every project, and it will then depend on check in all subprojects where it exists without IP violations. This is an approach I've used elsewhere (say, in my central portal publishing plugin) to effectively allow "open" task dependencies that are then set up from the provider side, without IP violations.Vampire
07/14/2026, 9:56 PMLuke Bemish
07/17/2026, 6:28 PMLuke Bemish
07/17/2026, 6:35 PMVampire
07/17/2026, 8:11 PMLuke Bemish
07/17/2026, 8:14 PMLuke Bemish
07/17/2026, 8:15 PMVampire
07/18/2026, 10:12 AMYou cannot ensure that the existing variant is there if you are depending on every project, and not every project may expose the thing in question.
Sure you can. If you have a convention plugin that is applied to all of the projects, that plugin can add such a variant. I know that it works, because I recently did exactly that.
And as for the second point -- yes that's exactly the issue. I would assume there is an API to request artifact selection specifically on resolved variants that is not "lenient" in any sense, but it appears there isn't.
Sure there is, as I said, just directly request that variant directly instead of using an artifact view.
Luke Bemish
07/20/2026, 1:58 AMIf you have a convention plugin...
This is fine for a single project. Less fine for publishing a plugin, which you now require to be a settings plugin for no good reason.
Just directly request the variant directly...
That only works if the artifact in question is the primary artifact set of a variant. If you want artifact(s) that are available only through a view or a secondary artifact set, your only option is to request them via a view, then go through afterwards and validate that you have all the same capabilities as the resolved variants, or some approach of that sort. I think my complaint is that there's some mixing up of artifact and variant resolution happening in this API. Ideally, the axes of what degree you allow variant selection and artifact selection to fail should be controllable and controllable independently; currently, your only options (assuming you're requesting different attributes for both selection steps) are fail-fast variant selection and never-fail artifact selection, or never failing for both. Allowing variant selection to fail but requiring artifact selection from selected variants to succeed, for instance, would be quite useful; similarly for requiring both to succeed.
Vampire
07/20/2026, 4:45 PMThis is fine for a single project. Less fine for publishing a plugin, which you now require to be a settings plugin for no good reason.... no 1. it is good reason 2. you quoted me and I did not say create a settings plugin, but I said "If you have a convention plugin that is applied to all of the projects" For our corporate convention plugins I for example anyway have a mandatory settings plugin, and a mandatory base plugin to be applied to all projects directly or indirectly. The base plugin verifies that the settings plugin is applied, the settings plugin verifies that all projects have at least the base plugin applied. This way all the corporate convention plugins can be sure that at least the base plugin is applied everywhere and can depend on that like requesting the given variant that is guaranteed to be available on each and every project in the build as it is added by the base plugin.
That only works if the artifact in question is the primary artifact set of a variant. If you want artifact(s) that are available only through a view or a secondary artifact set, your only option is to request them via a view, then go through afterwards and validate that you have all the same capabilities as the resolved variants, or some approach of that sort.Can you elaborate on that with an MCVE? Which variants are only available through an artifact view? I'm not aware of such a restriction, besides - as I said - if only an artifact transform can produce the variant. Other than that I think you should be able to request all directly also.
I think my complaint is that there's some mixing up of artifact and variant resolution happening in this API.Yes, that is indeed a bit strange at times. For example some attributes are on configurations / variants, some are on artifacts. And artifact transforms can for example not influence the variant selection even if they could then later provide the requested attributes. There are open FR for such things.
Luke Bemish
07/20/2026, 4:47 PMLuke Bemish
07/20/2026, 4:47 PMVampire
07/20/2026, 4:53 PMFor instance. Any artifact transform who's resulting attributes are incompatible with the attributes requested for variant selectionYes, as I said multiple times, if only an artifact transform can produce a variant, then an artifact view is necessary. Well, also not fully true iirc. If the transformed attributes are artifact attributes, not variant attributes, then it should even work without artifact view. But - as I said - if no artifact transform is involved at all, no artifact view should be necessary.
And your convention plugin example is once again, likely fine for a corporate setup but less fine for a published plugin which now needs to be applied in projects it does nothing inOur corporate convention plugins are published to a maven repo internally and applied to builds just like any other published plugin, so I don't see how there would be any difference to a publically published plugin, or why you would need to apply it to somewhere it does nothing in.
Luke Bemish
07/20/2026, 4:59 PMIf no artifact transform is involved at all, no artifact transform is necessary
My point is also true of plain old secondary artifact sets (previously secondary variants). Besides which... Yes, that's the point. You need separate control over the attributes used for artifact and variant selection in some cases. That requires artifact views. Which don't let you enforce successful artifact selection.
Luke Bemish
07/20/2026, 5:01 PMVampire
07/20/2026, 6:13 PMMy point is also true of plain old secondary artifact sets (previously secondary variants).No, it's not if they are built sanely:
val foo = configurations.dependencyScope("foo")
val fooClasspath = configurations.resolvable("fooClasspath") {
extendsFrom(foo)
attributes {
attribute(CATEGORY_ATTRIBUTE, project.objects.named(LIBRARY))
attribute(USAGE_ATTRIBUTE, project.objects.named(JAVA_RUNTIME))
attribute(LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(JAR))
attribute(BUNDLING_ATTRIBUTE, project.objects.named(EXTERNAL))
}
}
val bar = configurations.dependencyScope("bar")
val barClasspath = configurations.resolvable("barClasspath") {
extendsFrom(bar)
attributes {
attribute(CATEGORY_ATTRIBUTE, project.objects.named(LIBRARY))
attribute(USAGE_ATTRIBUTE, project.objects.named(JAVA_RUNTIME))
attribute(LIBRARY_ELEMENTS_ATTRIBUTE, project.objects.named(CLASSES))
attribute(BUNDLING_ATTRIBUTE, project.objects.named(EXTERNAL))
}
}
dependencies {
foo(projects.foo)
bar(projects.foo)
}
tasks.register("baz") {
doLast {
println("FOO")
fooClasspath.get().forEach { println(it) }
println("BAR")
barClasspath.get().forEach { println(it) }
}
}
=>
FOO
.../showcase/foo/build/libs/foo.jar
BAR
.../showcase/foo/build/classes/java/main
You need separate control over the attributes used for artifact and variant selection in some cases. That requires artifact viewsUsually not, because artifact attributes are on the artifact, not on the variant, so if you request them on the resolvable configuration already, they are ignored for the variant selection, as the variant does not provide the attribute you requested which is considered compatible and then on the artifact resolution they are taken into account.
Which don't let you enforce successful artifact selection.Which is sad sometimes, yes.
it does nothing but make an empty variantWhich is not nothing, so yes it does something that your plugin needs to operate properly on the build and thus is imho ok to be enforced, especially if your settings plugin can simply enforce it, so the consumer only needs to apply the settings plugin.
It's silly, having an API flexible enough to resolve those two axes separately would avoid the issue entirelyWell, open a feature request ticket if there is none yet. 🙂
Vampire
07/20/2026, 6:14 PMVampire
07/20/2026, 6:14 PMVampire
07/20/2026, 6:14 PMVampire
07/20/2026, 6:14 PMVampire
07/20/2026, 6:16 PMLuke Bemish
07/20/2026, 6:17 PMVampire
07/20/2026, 6:24 PM