What is the best practice for granularity of the custom tasks

Should be tasks small and do one simple thing or complex but do some complete thing. Let’s say I need download file from some location, modify it and deploy it into repository, is better to have 3 tasks (download,update,deploy) or 1 which does 3 things? Similar, I need to reseed database, but this process consists of dropping old one, create new one, create schema, insert initial data?

In general, finer-grained tasks are better, because they lead to more flexibility, reusability, finer-grained up-to-date checks, more potential for parallelism, etc. On the other hand, sometimes one bigger task is easier/better to implement. If in doubt, use multiple tasks.

Others may have a different perspective, but I think you can view a task as a class (instance of DefaultTask) and observe good coherence practices like you would with any class. My experience has been that what works well for me is to create granular tasks for different things that I might reasonably want to do and an aggregate task that depends on those tasks in order to execute everything. You can use mustRunAfter in the granular classes to create order without dependency, too, if you need that. So, for your example of reseeding the database, I’d create a task each to drop, create, create schema, and populate the database and then a task called “reseedDatabase” or some such that doesn’t do anything itself but just aggregates the other tasks via dependency.

Thank you for ideas. What if ‘reseedDatabase’ need to operate on multiple databases, same schema, same data but different locations, is it better to make fine granular tasks each operating on set of locations, or just multiple whole set of tasks instead ( reseedDatabases dependsOn {resedDatabaseA, reseedDatabaseB, resedDatabaseC…])?