Skip to content

Make gradle-revapi configuration cache friendly #13

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

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from

Conversation

FinlayRJW
Copy link

@FinlayRJW FinlayRJW commented Jul 23, 2025

Before this PR

gradle-revapi had a range of issues making it not configuration cache friendly:

  1. The use of project.exec to run Git commands
  2. The use of Task.project within ConjureProjectFilters, RevapiAcceptBreakTask, RevapiAnalyzeTask, RevapiReportTask and RevapiVersionOverrideTask

After this PR

Converted GitVersionUtils to a manage type so it can be injected via @Nested and switched to the configuration cache friendly ProviderFactory.exec

Converted ConjureProjectFilters, RevapiAcceptBreakTask, RevapiAnalyzeTask, RevapiReportTask and RevapiVersionOverrideTask to abstract classes and removed the Task.project calls by passing in the needed fields as inputs

Added the gradle-plugin-testing plugin and used ConfigurationCacheSpec to allow RevapiSpec to test configuration cache issues

==COMMIT_MSG==
Make gradle-revapi configuration cache friendly
==COMMIT_MSG==

Possible downsides?

@FinlayRJW FinlayRJW changed the title Finlayw/configuration cache Make gradle-revapi configuration cache friendly Jul 23, 2025
getProject().getObjects().property(Justification.class);

public RevapiAcceptBreakTask() {
getOutputs().upToDateWhen(_ignored -> false);
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to doNotTrackState in RevapiPlugin.java

@@ -92,8 +79,4 @@ private void ensurePresent(Property<?> prop, String option) {
throw new IllegalArgumentException("Please supply the --" + option + " param to this task");
}
}

private GroupNameVersion oldGroupNameVersion() {
return getProject().getExtensions().getByType(RevapiExtension.class).oldGroupNameVersion();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the use of getProject that was breaking configuration cache the rest of the changes are just about converting to an abstract class - can just remove this if we want a minimum PR

revapiIgnores(),
ConjureProjectFilters.forProject(getProject()),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the use of getProject that was breaking configuration cache the rest of the changes are just about converting to an abstract class - can just remove this if we want a minimum PR

private final Property<String> oldGroup;
private final Property<String> oldName;
private final ListProperty<String> oldVersions;
private final Provider<GroupAndName> oldGroupAndName;

@Nested
protected abstract GitVersionUtils getGitVersionUtils();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made GitVersionUtils injectable as I think it is a bit cleaner but we could instead keep previousGitTags static and just pass in the dir and provider factory if we think that is tidier

Comment on lines -61 to -72
getProject()
.getTasks()
.withType(RevapiAcceptBreakTask.class)
.getByName(RevapiPlugin.ACCEPT_BREAK_TASK_NAME)
.getPath());
templateData.put("acceptBreakTask", getAcceptAllBreaksTaskPath().get());
templateData.put(
"acceptAllBreaksProjectTask",
getProject()
.getTasks()
.withType(RevapiAcceptAllBreaksTask.class)
.getByName(RevapiPlugin.ACCEPT_ALL_BREAKS_TASK_NAME)
.getPath());
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the bad use of getProject similarly the other changes are all about making it abstract can just do this bit if we prefer

}

private GroupNameVersion oldGroupNameVersion() {
return getProject().getExtensions().getByType(RevapiExtension.class).oldGroupNameVersion();
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as previous this is the actual call to getProject that break configuration cache other changes are about making abstract

import spock.util.environment.RestoreSystemProperties

class RevapiSpec extends IntegrationSpec {
class RevapiSpec extends ConfigurationCacheSpec {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigurationCacheSpec is built on IntegrationTestKitSpec so runTask now returns a BuildResult most of the changes here are focused on converting to using BuildResult

private Git git

def setup() {
git = new Git(projectDir)
System.setProperty("ignoreDeprecations", "true")
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to build.gradle

executionResult.wasSkipped(':revapi')
def buildResult = runTasksSuccessfully('revapi')
assert buildResult.task(':revapiAnalyze').outcome == TaskOutcome.SKIPPED
assert buildResult.task(':revapi').outcome == TaskOutcome.SKIPPED
}

def 'when the previous git tag has failed to publish, it will look back up to a further git tag'() {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test fails on main not sure if it should be @Ignore?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant