Part 1: Initializing the Project
Learn the basics of developing Gradle plugins starting with gradle init
.
Step 0: Before you Begin
Before we start, make sure you have everything you need:
-
Gradle Installed: Check that you have Gradle installed by running
gradle -v
in your terminal. If not, follow the link to the installation guide. -
IntelliJ IDEA: Install the free IntelliJ IDEA Community Edition. It’s a great tool for working with Gradle projects.
Step 1: Initializing the Project
Let’s get started by creating our project.
First, create a new directory called plugin-tutorial
and navigate into it:
$ mkdir plugin-tutorial
$ cd plugin-tutorial
Now, run the gradle init
command to automatically generate a basic plugin project.
You can build this plugin in either Groovy or Kotlin:
$ gradle init --type kotlin-gradle-plugin --dsl kotlin
$ gradle init --type groovy-gradle-plugin --dsl groovy
When prompted for additional options, just accept the default values.
All examples in this tutorial are based on a macOS environment. |
Step 2: Understanding the Project Layout
After gradle init
finishes, you’ll have a new project structure.
The plugin-tutorial
directory is our root project, and inside, there’s a subproject named plugin
where we’ll do most of our work.
The project should look like this:
.
├── gradle (1)
│ ├── libs.versions.toml (2)
│ └── wrapper
├── gradlew (3)
├── gradlew.bat (3)
├── settings.gradle.kts (4)
└── plugin/
├── build.gradle.kts (5)
└── src
├── main
│ └── kotlin (6)
│ └── org/example
│ └── PluginTutorialPlugin.kt
├── test
│ └── kotlin (7)
│ └── org/example
│ └── PluginTutorialPluginTest.kt
└── functionalTest
└── kotlin (8)
└── org/example
└── PluginTutorialPluginFunctionalTest.kt
1 | This folder holds the wrapper files that allow us to run Gradle without a local installation. |
2 | This is a version catalog, a tool for managing all your project’s dependencies in one place. |
3 | These are the Gradle wrapper scripts for macOS/Linux and Windows. |
4 | This file defines the name of our build and includes our plugin subproject. |
5 | The build script for our plugin subproject. This is where we’ll add our dependencies and configure the plugin. |
6 | The default source folder for our new plugin. |
7 | The default folder for unit tests. |
8 | The default folder for functional tests. |
.
├── gradle (1)
│ ├── libs.versions.toml (2)
│ └── wrapper
├── gradlew (3)
├── gradlew.bat (3)
├── settings.gradle (4)
└── plugin/
├── build.gradle (5)
└── src
├── main
│ └── groovy (6)
│ └── org/example
│ └── PluginTutorialPlugin.groovy
├── test
│ └── groovy (7)
│ └── org/example
│ └── PluginTutorialPluginTest.groovy
└── functionalTest
└── groovy (8)
└── org/example
└── PluginTutorialPluginFunctionalTest.groovy
1 | This folder holds the wrapper files that allow us to run Gradle without a local installation. |
2 | This is a version catalog, a tool for managing all your project’s dependencies in one place. |
3 | These are the Gradle wrapper scripts for macOS/Linux and Windows. |
4 | This file defines the name of our build and includes our plugin subproject. |
5 | The build script for our plugin subproject. This is where we’ll add our dependencies and configure the plugin. |
6 | The default source folder for our new plugin. |
7 | The default folder for unit tests. |
8 | The default folder for functional tests. |
Step 3: Review the Gradle Build File
Let’s take a look at the build.gradle(.kts)
file inside the plugin
directory.
This is where the magic happens.
When you’re writing a plugin, you’ll use the java-gradle-plugin
to:
-
Automatically generate the necessary plugin metadata.
-
Add plugin development conventions and tasks.
-
Simplify the publishing process.
This is what the gradlePlugin {}
and plugins {}
block looks like:
plugins {
// Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins
`java-gradle-plugin`
// Apply the Kotlin JVM plugin to add support for Kotlin.
alias(libs.plugins.kotlin.jvm)
}
gradlePlugin {
// Define the plugin
val greeting by plugins.creating {
id = "org.example.greeting"
implementationClass = "org.example.PluginTutorialPlugin"
}
}
plugins {
// Apply the Java Gradle plugin development plugin to add support for developing Gradle plugins
id 'java-gradle-plugin'
// Apply the Groovy plugin to add support for Groovy
id 'groovy'
}
gradlePlugin {
// Define the plugin
plugins {
greeting {
id = 'org.example.greeting'
implementationClass = 'org.example.PluginTutorialPlugin'
}
}
}
-
gradlePlugin {}
: This is where you configure the plugins you’re authoring. -
val greeting by plugins.creating {}
orplugins.greeting {}
: This registers a new plugin definition with the IDorg.example.greeting
. -
implementationClass = "org.example.PluginTutorialPlugin"
: This points to the main class that contains your plugin’s logic.
Step 4: Review the Plugin Code
The plugin code is a simple "Hello, World!" example that gradle init
generated for us.
You can find it at `plugin/src/main/kotlin/org/example/PluginTutorialPlugin.kt`:
You can find it at `plugin/src/main/groovy/org/example/PluginTutorialPlugin.groovy`:
package org.example
import org.gradle.api.Project
import org.gradle.api.Plugin
/**
* A simple 'hello world' plugin.
*/
class PluginTutorialPlugin: Plugin<Project> {
override fun apply(project: Project) {
// Register a task
project.tasks.register("greeting") { task ->
task.doLast {
println("Hello from plugin 'org.example.greeting'")
}
}
}
}
package org.example
import org.gradle.api.Project
import org.gradle.api.Plugin
/**
* A simple 'hello world' plugin.
*/
class PluginTutorialPlugin implements Plugin<Project> {
void apply(Project project) {
// Register a task
project.tasks.register("greeting") {
doLast {
println("Hello from plugin 'org.example.greeting'")
}
}
}
}
-
Plugin<Project>
: Our plugin needs to implement this interface to work with aProject
object. -
apply()
: This method is the entry point. Gradle calls it when the plugin is applied to a project. -
tasks.register("greeting")
: This is how we register a new task. Users can run it from the command line with./gradlew greeting
. -
doLast {}
: This block contains the code that runs when the task is executed.
Step 5: Understand the Plugin’s Behavior
To see the plugin in action, you can apply the plugin using its ID (org.example.greeting
) in a plugins
block:
plugins {
id("org.example.greeting")
}
After applying it, running the greeting
task with ./gradlew greeting
will produce the following output:
Hello from plugin 'org.example.greeting'
Step 6: What we will Build
This tutorial will guide you in building a powerful Slack Notification Gradle Plugin. This plugin will make it easy to automatically report your build results to a Slack channel.
The finished plugin will be able to:
-
Send a custom Slack message with a simple task (
sendTestSlackMessage
). -
Automatically report build success or failure at the end of the build.
-
Integrate seamlessly with the build lifecycle using modern Gradle APIs like
FlowAction
.
Step 7: Slack Client API Setup
To get started, you’ll need to set up the Slack API Client.
-
Get a Slack Account and Workspace:
-
Create a Slack Account.
-
Create a Slack Workspace where you have administrative privileges.
-
-
Create a Slack App:
-
Navigate to the Slack App creation page.
-
Select "Create An App" → "From Manifest" and accept the defaults to create a "Demo App".
-
-
Configure Permissions and Get Your Token:
-
Go to "OAuth & Permissions" in your app’s settings.
-
Under "Bot Token Scopes," click "Add an OAuth Scope" and select
chat:write
. This gives your app permission to post messages. -
Select "Install App" to install it in your workspace.
-
A Bot User OAuth Token will be generated. It will start with
xoxb-
. Be sure to save this token! It’s what we’ll use to authenticate our plugin’s API calls.
-
You’re all set! Now you have a working Gradle plugin project and all the tools you need to connect to Slack.
Next Step: Add an Extension >>