Developing Standalone Gradle Custom Plugin using Groovy DSL

Luis Trigueiros
4 min readOct 22, 2023

--

Problem context

Let’s imagine an hypothetical scenario, you are part of sizeable organization that have some time ago adopted microservices as an architectural style to develop their applications and by now the company have dozens of microservices.

Let’s also consider that this microservices are all written in Java using using Spring Cloud each with their own Git repository with their own build logic expressed in Gradle.

Each of this repositories and build will naturally share a lot of commonality, like their all need to do the common things one would expect to find in a Gradle build like for example:

  • Define the Java Version to use
  • Define their library dependencies
  • Define how test are run as part of the build
  • Define code quality and security checks are performed as part of build

There is a lot more on the above list I just enumerated a few very obvious ones that are common on any Java/SpringBoot project build.

In a situation like this it makes sense to create your own custom Gradle build plugin to centralize the management and maintenance of your own build options across the estate of applications/repositories that your company cares about.

Once you have developed this plugin you can it can be published into the company wide Maven repository and referenced from the downstream applications repository, making easy to for example upgrade common build logic across all the application.

Another example let’s say new version of shared library that is used across all of this applications was published either because of a security vulnerability was found or new features where developed and now you need to update all of microservices that are part of your deployment, well now you can just update in the plugin and it will be picked up the next time you run the build of the microservices in Jenkins.

Developing of your own custom Gradle plugin can sound like a daunting task as a well established project if you go over the Gradle user documentation it can fell a bit like TL;DR.

For this type of requirement there is a very easy and convenient way of implementing the plugin using the plain Groovy DSL that it easy probably duplicated across all the repositories, using Precompiled script plugins as documented in:

Developing Custom Gradle Plugins

The complete example is available in my personal GitHub account at:

luistrigueiros/example-gradle-convections-plugin: Example of writing a gradle plugin using gradle-convections-plugin (github.com)

In the following I will describe the key points of the implemented solution.

Problem solution

In the GitHub repository linked about you will find the 2 folders under the root:

  • the-plugin, this is Gradle plugin project
  • the-consumer-project, this is one example project using the plugin

The plugin project

In this plugin project build file we only need to declare the plugin block and add the “groovy-gradle-plugin” .

By doing this Gradle will pickup any Gradle DSL convection plugin present in the directory “src/main/groovy”.

Bellow is the example build script now turned into plugin.

The advantage of this approach is that we can literally grab all the existing build files duplicated across dozens of code repositories and can centralize then into a single repository making easier the maintenance of the share build logic in one single place.

Because there is nothing particularly advanced about this plugin we don’t need to go down to the level of the plugin using the Gradle API’s and we can stay just at the level of the Gradle Groovy DSL.

The plugin consumer

In the plugin consumer project in order to consume this plugin all that we have to do is declared that it consumes the plugin the the plugins block as show in the image bellow:

As you can see from the above the id of the plugin is the file name as it was declared in the source folder removing from it the “.gradle” extension.

As you can see from the above the consuming project build file is now very compact and does not declare things like the Java version to use or how test are run as or repositories from where to source libraries as this is all packed in the plugin.

On the above example I didn’t have to packed the plugin as library and publish into a Maven repository because it possible in Gradle to include additional sources into a build using using the “includeBuild” as show in the image bellow:

Hope you have found this useful.

I would like to pay homage to:

As his video on Understanding Gradle #03 — Plugins — YouTube helped me grasp how to solve this issue.

--

--