Part 3: Creating Tasks
Learn about custom task types, create one, and add it to your plugin.
Step 1: About Custom Tasks
If your plugin introduces new functionality, you’ll typically define a custom task type. This allows you to encapsulate specific logic, like sending a Slack message, into a reusable and configurable Gradle task. We’ll then register this task in our plugin so users can execute it with a simple command.
Step 2: Create a Custom Task Type
Let’s create the class that will contain our Slack messaging logic.
Create a new file called `SlackTask.kt` in `src/main/kotlin/org/example/` and add the following code:
Create a new file called `SlackTask.groovy` in `src/main/groovy/org/example/` and add the following code:
package org.example
import com.slack.api.Slack
import com.slack.api.methods.request.chat.ChatPostMessageRequest
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import kotlin.text.isNotEmpty
/**
 * A custom Gradle task that sends a test message to a Slack channel.
 *
 * This task is useful for verifying Slack integration during build configuration.
 * It uses the Slack Web API and requires a bot token and a target channel.
 */
abstract class SlackTask : DefaultTask() {
    // The Slack bot token (usually starts with "xoxb-") used to authenticate the API request.
    @get:Input
    abstract val token: Property<String>
    // The Slack channel name or ID (e.g., "#builds" or "C12345678") where the message will be sent.
    @get:Input
    abstract val channel: Property<String>
    // The message content to be sent to the specified Slack channel.
    @get:Input
    abstract val message: Property<String>
    /**
     * Sends a message to Slack when the task is executed.
     * Useful for manual testing of Slack integration from the command line.
     */
    @TaskAction
    fun send() {
        // Initialize the Slack client and get the API methods interface
        val slack = Slack.getInstance()
        val methods = slack.methods(token.get())
        // Create a Slack message request
        val request = ChatPostMessageRequest.builder()
            .channel(channel.get())
            .text(message.get())
            .build()
        // Send the message via the Slack API and check for success
        val response = methods.chatPostMessage(request)
        if (response.isOk) {
            logger.lifecycle("Slack message sent successfully to channel ${channel.get()}")
        } else {
            // Fail the build if the Slack API response indicates an error
            logger.error("Failed to send Slack message: ${response.error}")
            throw RuntimeException("Slack message failed: ${response.error}")
        }
    }
}package org.example
import com.slack.api.Slack
import com.slack.api.methods.request.chat.ChatPostMessageRequest
import org.gradle.api.DefaultTask
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
/**
 * A custom Gradle task that sends a test message to a Slack channel.
 *
 * This task is useful for verifying Slack integration during build configuration.
 * It uses the Slack Web API and requires a bot token and a target channel.
 */
abstract class SlackTask extends DefaultTask {
    // The Slack bot token (usually starts with "xoxb-") used to authenticate the API request.
    @Input
    abstract Property<String> getToken()
    // The Slack channel name or ID (e.g., "#builds" or "C12345678") where the message will be sent.
    @Input
    abstract Property<String> getChannel()
    // The message content to be sent to the specified Slack channel.
    @Input
    abstract Property<String> getMessage()
    /**
     * Sends a message to Slack when the task is executed.
     * Useful for manual testing of Slack integration from the command line.
     */
    @TaskAction
    void send() {
        // Initialize the Slack client and get the API methods interface
        def slack = Slack.getInstance()
        def methods = slack.methods(token.get())
        // Create a Slack message request
        def request = ChatPostMessageRequest.builder()
                .channel(channel.get())
                .text(message.get())
                .build()
        // Send the message via the Slack API and check for success
        def response = methods.chatPostMessage(request)
        if (response.isOk) {
            logger.lifecycle("Slack message sent successfully to channel ${channel.get()}")
        } else {
            // Fail the build if the Slack API response indicates an error
            logger.error("Failed to send Slack message: ${response.error}")
            throw new RuntimeException("Slack message failed: ${response.error}")
        }
    }
}This custom task type does a few important things:
- 
It extends DefaultTask, which gives it all the basic functionality of a Gradle task.
- 
It uses annotations like @Inputand@TaskActionto clearly define its inputs and its primary action.
- 
The @TaskActionmethod uses the Slack API client to post a message.
- 
It includes robust error handling: if the Slack API call fails, the task will fail the build with a clear error message. 
Step 3: Add the Slack API Dependency
Since our custom task uses the Slack API client, we need to add it as a dependency in our plugin’s build.gradle(.kts) file.
dependencies {
    // Use the Java Slack Client APIs
    implementation("com.slack.api:slack-api-client:1.45.3")
}dependencies {
    // Use the Java Slack Client APIs
    implementation("com.slack.api:slack-api-client:1.45.3")
}Step 4: Register it in the Plugin
Now that we’ve defined our custom SlackTask class, we need to register it in our plugin’s apply method.
This makes it available for users to run with a command like ./gradlew sendTestSlackMessage.
Open your plugin implementation file, `SlackPlugin.kt` (in `src/main/kotlin/org/example/`), and modify it to look like this:
Open your plugin implementation file, `SlackPlugin.groovy` (in `src/main/groovy/org/example/`), and modify it to look like this:
import org.gradle.api.tasks.TaskProvider
abstract class SlackPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        // Create the 'slack' extension so users can configure token, channel, and message
        val extension = project.extensions.create("slack", SlackExtension::class.java)
        // Register a task named 'sendTestSlackMessage' of type SlackTask
        val taskProvider: TaskProvider<SlackTask> = project.tasks.register("sendTestSlackMessage", SlackTask::class.java)
        // Configure the task using values from the extension
        taskProvider.configure {
            it.group = "notification" // Logical task grouping for help output
            it.description = "Sends a test message to Slack using the configured token and channel."
            // Bind extension values to the task's input properties
            it.token.set(extension.token)
            it.channel.set(extension.channel)
            it.message.set(extension.message)
        }
    }
}import org.gradle.api.tasks.TaskProvider
abstract class SlackPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        // Create the 'slack' extension so users can configure token, channel, and message
        def extension = project.extensions.create('slack', SlackExtension)
        // Register a task named 'sendTestSlackMessage' of type SlackTask
        TaskProvider<SlackTask> taskProvider = project.tasks.register('sendTestSlackMessage', SlackTask)
        // Configure the task using values from the extension
        taskProvider.configure {
            // Logical task grouping for help output
            it.group = 'notification'
            // Sends a test message to Slack using the configured token and channel.
            it.description = 'Sends a test message to Slack using the configured token and channel.'
            // Bind extension values to the task's input properties
            it.token.set(extension.token)
            it.channel.set(extension.channel)
            it.message.set(extension.message)
        }
    }
}This code:
- 
Registers a new task named sendTestSlackMessageof our customSlackTasktype.
- 
Configures the task with a group and description for better help output. 
- 
Binds the task’s properties ( token,channel,message) to the corresponding properties in our plugin’sSlackExtension. This is how the user’s configuration is passed to the task.
Next Step: Write a Unit Test >>