Run specific Gradle tasks in sequence
Is there any way to run only a certain Gradle task sequentially, while running others in parallel?
Is there any way to turn off parallel execution for a particular Gradle task?
It seems a bit weird to even consider such thing in the first place... But there are some cases in which you actually might want a particular type of task to execute sequentially, even though you are using --parallel=true
for the remaing tasks.
For example, this StackOverflow thread asks for SpotBugs tasks to run in sequence to ease on the resources consumption. Or maybe you have a particular task, say an integration test, that needs to use a shared resource, like a TCP port, and you don't want that particular test to run in parallel with others.
In any case, the solution is simple: we can use a Gradle feature called Build Service.
I could not find a quick answer on Google with examples, so here's one.
First let's create a build service:
import org.gradle.api.services.BuildService;
import org.gradle.api.services.BuildServiceParameters;
public abstract class RunInSequence implements BuildService<BuildServiceParameters.None> {}
Now, add it to the task that needs to run in sequence:
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Internal;
public abstract class MyTask extends DefaultTask {
@Internal
public abstract Property<RunInSequence> getRunInSequence();
}
Great! Now we need to use a service provider in a plugin where our task is declared:
import org.gradle.api.Plugin;
import org.gradle.api.Project;
class MyPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
var serviceProvider = project
.getGradle()
.getSharedServices()
.registerIfAbsent(
"runInSequence",
RunInSequence.class,
s -> { s.getMaxParallelUsages().set(1); }
);
project.getTasks()
.register(
"myTask",
MyTask.class,
t -> {
t.getRunInSequence().set(serviceProvider);
t.usesService(serviceProvider);
});
}
}
And that's it!
Next time you use myTask
in multiple Gradle modules, all occurences of this task will wait for each other and run in sequence!