Slackbot
04/24/2023, 2:40 AMVampire
04/24/2023, 6:46 AMonlyIf
is checked at execution time.Mikhail Lopatkin
04/24/2023, 7:15 AMEli Graber
04/24/2023, 5:56 PMonlyIf
is the culprit here:
project.gradle.taskGraph.allTasks.any { it.state.failure != null }
Is there an easy way to make that work with the CC? I'm not really familiar with this project and it is no longer maintained, so I'm looking for a quick and easy fix if possible š
Vampire
04/24/2023, 7:18 PMOperationCompletionListener
and check that instead of the taskgraph?gmazzo
05/02/2023, 4:21 PMonlyIf
closures are now evaluated at configuration time and not at execution time, I am right?
Maybe not configuration time, but definitely before the dependent tasks are run š¤gmazzo
05/02/2023, 4:32 PMOperationCompletionListener
would work?
Basically what we need to archive is to run a finalizedBy
task but only if the dependent where successful.
The original logic was accessing the taskgraph to gather their result, but now this is a violation of CC.
I've tried moving the logic to a Provider<Boolean>
but tests are not passing (only with CC enabled) because the behavior is different, the provider gets evaluated before the tasks are run
cc: @Zac SweersVampire
05/02/2023, 4:35 PMa.finalizedBy(b)
but b
should only run if a
was successful?Vampire
05/02/2023, 4:35 PMa.finalizedBy(b)
b.dependsOn(a)
Vampire
05/02/2023, 4:35 PMgmazzo
05/02/2023, 4:38 PMCommitEdit
is a bit hacky. It should commit the Play Store transaction if the dependents tasks where successful. But it should rollback (by calling apiService.get().cleanup()
if they weren't).gmazzo
05/02/2023, 4:39 PMcleanup
was done before as part of the onlyIf
spec (not ideal) but now the onlyIf
is evaluated at configuration phase, I'm wondering if that's an issue š¤ as the docs says it's evaluated just before the task is rungmazzo
05/02/2023, 4:39 PMVampire
05/02/2023, 4:40 PMgmazzo
05/02/2023, 4:40 PMYou meanBoth, we need to change the behavior based on the outcome of previous tasksbuta.finalizedBy(b)
should only run ifb
was successful?a
Vampire
05/02/2023, 4:42 PMVampire
05/02/2023, 4:43 PMgmazzo
05/02/2023, 4:53 PMI don't believe that without proof.I put a breakpoint in the provider, look at the terminal, it's evaluated at
100% CONFIGURING
(when it's stored to cache) and without CC, it's evaluated just before the task is about to run, but after the other had run š¤Vampire
05/02/2023, 5:01 PMtasks.configureEach {
onlyIf {
println("onlyIf for $name")
true
}
doFirst {
println("execution of $name")
}
}
$ gw --configuration-cache build
Encryption of the configuration cache is enabled.
Reusing configuration cache.
> Task :processResources UP-TO-DATE
onlyIf for processResources
> Task :processTestResources UP-TO-DATE
onlyIf for processTestResources
> Task :compileJava UP-TO-DATE
onlyIf for compileJava
> Task :classes
onlyIf for classes
execution of classes
> Task :jar UP-TO-DATE
onlyIf for jar
> Task :assemble
onlyIf for assemble
execution of assemble
> Task :compileTestJava UP-TO-DATE
onlyIf for compileTestJava
> Task :testClasses
onlyIf for testClasses
execution of testClasses
> Task :test UP-TO-DATE
onlyIf for test
> Task :check
onlyIf for check
execution of check
> Task :build
onlyIf for build
execution of build
BUILD SUCCESSFUL in 17s
11 actionable tasks: 5 executed, 6 up-to-date
Configuration cache entry reused.
gmazzo
05/02/2023, 5:06 PM.get
is called as part of the onlyIf
closure, added in a init
method of the same task.
The task is registered in the graph with finalizeBy
by other tasks.gmazzo
05/02/2023, 5:17 PMval finalTask by tasks.registering {
val prov = provider { project.gradle.taskGraph.allTasks.any { println("*** provider called: ${it.path}"); true } }
onlyIf { prov.get() }
doFirst { println("*** finalTask run") }
}
val someTask by tasks.registering {
finalizedBy(finalTask)
doFirst { println("*** someTask run") }
}
./gradlew aaa
shows:
⯠./gradlew someTask
> Task :app:someTask
*** someTask run
> Task :app:finalTask
*** provider called: :app:someTask
*** finalTask run
and ./gradlew aaa --configuration-cache
shows:
⯠./gradlew someTask --configuration-cache
Encryption of the configuration cache is enabled.
Calculating task graph as no configuration cache is available for tasks: someTask
*** provider called: :app:someTask
> Task :app:someTask
*** someTask run
> Task :app:finalTask
*** finalTask run
Gradle version is 8.1.1
.
Should I fill a bug? or this is expected?Vampire
05/02/2023, 6:08 PMprov
is probably state on the task and thus on serialization queried and persistedVampire
05/02/2023, 6:09 PMgmazzo
05/03/2023, 8:49 AMAutoCloseable
(to rollback) and OperationCompletionListener
(to know if any previous task has failed) in the PlayApiService
. Thanks a lot @Vampire for the hints!gmazzo
05/03/2023, 8:51 AMI think the behavior is "any provider created while a task is configuring" is resolved at configuration time and stored into the cache. It would be nice to have some official word/doc regarding this to confirm it. But definitely, it behaves in a different way when CC is on.is evaluated at configuration phase,onlyIf
Vampire
05/03/2023, 9:53 AMI think the behavior is "any provider created while a task is configuring" is resolved at configuration timeNo, the tasks state is serialized to CC. Providers are resolved at serialization time and their result serialized to CC. The
onlyIf
closure is part of the task and things it references are thus automatically also such state.
In your case you reference the prov
within onlyIf
, so prov
gets serialized, so that the onlyIf
can access its value at execution time.
And as prov
is a provider, it is resolved at CC store time.
If you add to your MCVE a println("*** onlyIf called")
within the onlyIf
you see that the onlyIf
is indeed run at execution time. Just the provider is realized at CC store time.Vampire
05/03/2023, 9:55 AMFYI, I finally make it work by introducingIf you do the rollback in the build service, you could also do the commit in the build service. Or if you want to keep the split, you could actually leave out the(to rollback) andAutoCloseable
(to know if any previous task has failed) in theOperationCompletionListener
.PlayApiService
onlyIf
check then and do what I initialliy suggested, adding an additional dependsOn
, so that the finalizer task is only run on success.gmazzo
05/03/2023, 10:11 AMThat won't work as we have may "potential" tasks getting registerer/created. Adding, so that the finalizer task is only run on success.dependsOn
dependsOn
(to archive "only on success") will force all of them to run, just because one of team has run.
I'm wondering if we need an API to complement finalizedBy
to know about the outcome of its previous tasks š¤
Clarifing, the plugin adds:
⢠publishApk
⢠publishBundle
⢠publishStoreDetails (or similar, don't remember exactly)
⢠etc, etc
All of them are followed by commitEdit
with finalizedBy
but only if didn't fail. Adding the oposite dependsOn
will force all of them to run. I couldn't find a way to archive the behavior with the current API, so I'm taking tracking their outcome in the BuildService
and the commitEdit
check if any has file as a onlyIf
condition.Vampire
05/03/2023, 10:28 AM