-
Notifications
You must be signed in to change notification settings - Fork 440
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Up-to-date checks (AKA Incremental Build) in Gradle plugin #1133
Comments
Great idea @anatoliy-balakirev ! Care for a PR? :) |
Sorry, I seem too stupid to work with Gradle. What I thought that is working, is not. I will not re-attempt to implement this feature in the upcoming time. If anyone is a Gradle expert, please feel free to try to tackle this problem |
@marcingrzejszczak, what's the minimum Gradle version you all are supporting/building against with Hoxton? |
We're building against 5.5 |
Also maintaining a 5.0 compatibility like the Spring Boot Gradle plugin? |
I mean assuming that gradle 5.5 is compatible with gradle 5.0 everything should be fine. |
To a point, yes. Prime example of where this matters is in the 4.x line. As of 4.8, if memory serves, is where Gradle introduces task configuration avoidance. So in those terms, if we were base lining against a version before that point then the task configuration avoidance API would be off limits. I haven't had a chance to look in depth through the Gradle 5.x API yet, so I'm not sure if Gradle 5.x has any of these types of features that have been introduced during it's lifecycle, but wanted to make sure of the baseline version to ensure feature compatibility. |
Hi. Sorry, was quite busy on something else and then was on vacation. And it seems to be fine, except for one small thing, which is mentioned here:
So when I adjusted
and output to:
It all started to work as expected. I've also modified my sample project to make it easier to use snapshot builds there, so you can use it to check this on your own. So executing my original command with snapshot plugin now gives me this result:
Which is exactly what we needed! :) @marcingrzejszczak do you want to proceed with your commit, applying this small fix? |
Yeah please do! I've completely haven't noticed that info about the annotations |
Actually, playing with that further it looks like |
I mean please feel free to apply a pr, revert my commit that reverted the fix and apply your changes :) |
Update on this: I worked on it today and it turned out to be not so easy. There is this |
Yeah, that was exactly the problem :) |
@marcingrzejszczak I guess they will be downloaded / used the first time and then for all subsequent runs described problem will be the case, right? Do you have some sample config to reproduce this? I was trying to get that use case working, but looks like made a mistake there (never had that set up, so never tested). |
Here is the sample https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/2.2.x/producer_with_git Unfotunately there are the following issues
if (downloaded != null) {
logger.info("Downloaded contracts to [" + downloaded + "]")
config.includedContracts.set(downloaded.inclusionProperties.includedContracts)
config.includedRootFolderAntPattern.set(downloaded.inclusionProperties.includedRootFolderAntPattern)
config.initialisedContractsDirectory.set(downloaded.downloadedContracts)
}
logger.info("For project [{}] will use contracts provided in the folder [{}]", project.name, config.initialisedContractsDirectory.get()) running this ^^ results in
as you can see, even though we set a configuration element, the |
That's quite weird...
Just out of curiosity, how exactly did you fix that? Just wonder if that fix actually caused this:
Updating the property should be propagated everywhere, in theory... That output property is used as an input to other tasks. |
afair I've removed some Unfortunately, due to the amount of time I have to put into Gradle, and Gradle's lack of being developer friendly in any way, I will timebox it to a day or two and most likely will be forced to remove this feature or add some hacks to make the tests pass again. |
I can take a look into this. Maybe whole idea to try to make that |
Yeah looks like it |
By when do you need this fixed? |
The sooner, the better ;) |
Trying to run that project locally and getting:
Seems to be caused by this config:
Any suggestions on how to make it working? Can't understand how it can work with that config in place... |
It works on my machine ™️ just copy the
|
Ok, thx. There actually seems to be a gradle task to do that, but it has a wrong dependency on:
and must be this instead:
So after applying that and disabling incremental build for
I got another problem in the
And after I started propagating that properly - we have this log:
So as you can see, now we have |
Here is an old code, which I actually remember we even discussed:
So it was always setting it to |
we also check for backward compatibility in those samples, so most likely it will fail cause Finchley doesn't have the
Ah yeah, you're right, now I remember.
Yeah, restore it for now. We'll deal with that later. |
With current implementation of the `GradleContractsDownloader`, where we have custom caching, `InitContractsTask` doesn't really need to be incremental. Moreover, there is an issue in current implementation of the `InitContractsTask`: it doesn't mark itself as out of date when dynamic dependency is used (`+` or `SNAPSHOT` version). So for now just disabling incremental build for that task. Also restored old behaviour, where we used to always use `".*"` pattern to define included contracts for `GenerateServerTests` task. Also fixed minor logging issue. Fixes spring-cloudgh-1133
Created PR. Once that one is merged - I can also try to take a look into replacing custom caching in the |
I just checked that further and today caching of downloaded artifacts is done in a way that they are cached per
With Gradle's caching, steps #4 and #5 will trigger new download, as input was changed (i.e. it won't remember history of executions, only the previous one). So will be:
Is that ok? |
I guess so. However, with the history of working with Gradle I really feel scared to rely on anything that Gradle provides. We have no certainty that with Gradle 25.0 that with their current pace might be released in a month this feature will not be removed. OTOH it's not a gigantic change I guess so yeah, go ahead with using Gradle caching. |
:) hopefully won't be removed. That incremental build stuff is quite a fundamental thing in Gradle, making it so fast. |
With current implementation of the `GradleContractsDownloader`, where we have custom caching, `InitContractsTask` doesn't really need to be incremental. Moreover, there is an issue in current implementation of the `InitContractsTask`: it doesn't mark itself as out of date when dynamic dependency is used (`+` or `SNAPSHOT` version). So for now just disabling incremental build for that task. Also restored old behaviour, where we used to always use `".*"` pattern to define included contracts for `GenerateServerTests` task. Also fixed minor logging issue. Fixes spring-cloudgh-1133
With current implementation of the `GradleContractsDownloader`, where we have custom caching, `InitContractsTask` doesn't really need to be incremental. Moreover, there is an issue in current implementation of the `InitContractsTask`: it doesn't mark itself as out of date when dynamic dependency is used (`+` or `SNAPSHOT` version). So for now just disabling incremental build for that task. Also restored old behaviour, where we used to always use `".*"` pattern to define included contracts for `GenerateServerTests` task. Also fixed minor logging issue. Fixes gh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Fixes spring-cloudgh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Fixes spring-cloudgh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Also fixed `PublishStubsToScmTask` and removed incremental stuff from there for now. Fixes spring-cloudgh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Also fixed `PublishStubsToScmTask` and removed incremental stuff from there for now. Fixes spring-cloudgh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Also fixed `PublishStubsToScmTask` and removed incremental stuff from there for now. Fixes spring-cloudgh-1133
Replaced custom caching of the downloaded contracts with Gradle's incremental build. After that `InitContractsTask` is not needed any more, as its main purpose was to be a bridge between custom caching and Gradle's one. Simplified code to download contracts is now part of the `ContractsCopyTask`. Also fixed `PublishStubsToScmTask` and removed incremental stuff from there for now. Fixes gh-1133
Enhancement
Gradle plugin doesn't seem to support incremental build => executing
generateContractTests
task every time, which is slowing down execution of completely not relevant unit tests significantly.Here is some sample project, I created to simulate our setup, where we have a lot of contract tests (we are using Pact jsons as an input):
https://github.com/anatoliy-balakirev/cloud.contract.demo
Those contract tests in the sample project are not really useful, I just wanted to show the case, where there is a project with a lot of them (in real project we have much more, actually).
So if you get into that project and execute following command a couple of times (it's just a unit test):
./gradlew :test --tests "com.example.demo.service.UserServiceImplTest" --scan
You'll see that
generateContractTests
is executed every time and takes a couple of seconds even though it's not needed for this particular unit test and its input / output is not changed between runs.Here is an example of such scan:
https://scans.gradle.com/s/qy3gtncjmopdo/performance/execution
https://scans.gradle.com/s/l2em6bwohe54c/performance/execution
As you can see, there it took almost 2.5 seconds to do something, which is not needed anyway (in our real project it takes up to 10 seconds).
Would be great if plugin could utilise incremental build (check here: https://docs.gradle.org/current/userguide/more_about_tasks.html#sec:up_to_date_checks) and skip tasks if they are up to date.
The text was updated successfully, but these errors were encountered: