avast / gradle-docker-compose-plugin

Simplifies usage of Docker Compose for integration testing in Gradle environment.
MIT License
412 stars 95 forks source link

Configuration cache incompatibility when using dockerCompose.exposeAsSystemProperties in doFirst block #452

Open wsutina opened 2 weeks ago

wsutina commented 2 weeks ago

I've encountered a configuration cache incompatible issue when using dockerCompose.exposeAsSystemProperties inside a doFirst block, following the guidance in the plugin's usage guide.

Code:

tasks.named<Test>("test") {
  doFirst {
    dockerCompose.exposeAsSystemProperties(this@named)
  }
}

Error:

Task `:service:test` of type `org.gradle.api.tasks.testing.Test`: cannot serialize object of type 'org.gradle.api.internal.project.DefaultProject', a subtype of 'org.gradle.api.Project', as these are not supported with the configuration cache.

See https://docs.gradle.org/8.10/userguide/configuration_cache.html#config_cache:requirements:disallowed_types

Given that the plugin should be configuration cache compatible (https://github.com/avast/gradle-docker-compose-plugin/issues/307), could you please advise how this line should be used or if there is an alternative approach to achieve the same outcome?

Thank you!

augi commented 2 weeks ago

Hello, thank you for the report!

The plugin should be still cache-compatible, the error message comes from the usage of [project.]dockerCompose IMHO, as it claims your test task cannot be serialized.

To be honest, I don't know how to overcome this issue, so any help is welcomed 🙏

staktrace commented 2 weeks ago

I'm not 100% sure how to resolve this issue either, but I took a bit of a look at it today. It seems that the exposeAsSystemProperties function needs to run during the task execution phase, as during configuration the set of properties that it has is not complete. (For example, properties like elasticsearch-local.host=localhost were not present at configuration time but were present at execution time).

However, the exposeAsSystemProperties function uses getServicesInfos() which delegates to tasksConfigurator.getServicesInfos() and the tasksConfigurator object holds a reference to the project instance. This essentially means that the project reference is needed at task execution time, which is fundamentally incompatible with the configuration cache (at least in my understanding - I could be wrong).

So I think something will need to change on the plugin side in order to make this API (or some equivalent API) compatible with the configuration cache.

augi commented 2 weeks ago

I also spent some time in the Gradle documentation and thinking about the design, and maybe the solution would be to have servicesInfos as output from the ComposeUp task. Then, you could use it to configure your test task. But it is just an idea, and maybe the implementation wouldn't be so easy.

Yes, it is not so easy - the task output can only be files and directories. But ComposeUp task already has a property named ServicesInfos, so maybe it could be somehow used for your task configuration. But the exposeAsSystemProperties method would have to be static probably.