Thoughts on task conventions for developer builds?


(spencer_allain) #1

Before 1.0-milestone-9, pmd and findbugs were second-class plugins and not wired in as dependencies of the “check” task (at least my custom tasks were not, so devs ran them manually and the CI server always ran them).

Anyone who has utilized findbugs knows that it is not always a “quick” execution.

Previously for our java projects, we’d just invoke “gradle build” and assemble tasks and check tasks were quick (1 minute and some change for a clean build of our multi-project build). Attempting to convert over to milestone-9, a single findbugs check on one subproject can take more than that time, so the pending convention is “gradle assemble test” or “gradle test assemble”.

Gradle is nice in that there are several options: don’t specify a task and let it use the defaultTasks (set them to assemble and test), create some special meta-task that simply depends upon assemble and test, explicitly adjust the doFirst() of the findbugs tasks to not do anything unless some property is set, etc.

Should there be something like a “fastBuild/devBuild” task that developers utilize for quick compiles and simple tests, and some progressively named “checkedBuild” that runs static analyzers, and maybe “integrationBuild” that runs heavier-weight tests? I’m not really sure where to go with this other than I need to do something so that developers used to typing “gradle build” don’t start complaining to me because their 10-30 second builds bloat into several minutes because one or more findbugs analysis tasks is no longer up-to-date.

Thoughts?

-Spencer


(Michael Brand) #2

I’ve been struggling with this as well (in fact it was the motivation for my earlier question about dependencies). I’ve come up with the following phases for our process:

  1. Compilation and local unit tests (fast tests without dependencies) 2. Integration tests (unit tests that are slower or have external dependencies) 3. Deployment and in-container tests 4. Reports (findbugs, checkstyle, etc.)

The current test/check convention doesn’t support this well. I think one issue is a confusing of the “test” task. Gradle uses this as a convention for unit tests, which is itself ambiguous. “Check” is then overloaded to mean “all tests” and “reports”. But there is no clear identification of the four kinds of test types listed above. I’ve seen this ambiguity in test-driven and CI environments for many years and I agree that a clear convention would help.


(René Groeschke) #3

Hello there, I think there is no one fits all solution for this. For the gradle project itself, we declared a “quickCheck” task that runs “test”, “classes” and “check”. Since we have different sourcesets for pure (fast) unit tests and (more expensive) integration tests (we recommend this pattern) quickCheck does not execute our integration tests but ensures that everything compiles, at least the unit tests are fine and our checkstyle and codenarc rules are not violated. We don’t yet configured findbugs for our codebase. In my previous projects I’ve also noticed, that findbugs execution is expensive and can cost quite some time. Maybe another approach would be to split the one findbugs task into different findbugs tasks (e.g. one checking against your API and one against your internal classes and run your devBuild just against the API classes.

regards, René


(Luke Daley) #4

The longer term goal here is to provide modelling of different “types” of builds. This would roughly equate to a pre-canned invocation (e.g. quickCheck = ‘gradle check -x findbugs’), but will be more than that.

There are a few workarounds and approximations out there for this now, including the one that René talks about above that we use in the Gradle build.