NAV
Switch version:

Task Plugins

Extension Information

Availability GoCD version 15.1.0 onwards
Extension Name task
Extension API Version 1.0

The Task extension endpoint allows plugin authors to extend GoCD to run new tasks in addition to the defaults that GoCD provides.

If you’re looking to start away with a basic template for task plugins, we recommend forking this github repository.

Requests from GoCD

In order to implement a task point the following messages must be implemented by the plugin.

Task Configuration

An example response body:

{
  "url": {
    "default-value": "",
    "secure": false,
    "required": true
  },
  "user": {
    "default-value": "bob",
    "secure": true,
    "required": true
  },
  "password": {}
}

This message is sent by the GoCD server to the plugin to know what properties are supported by this plugin that should to be stored in the cruise-config.xml file.

Request name

configuration

Request body

The server will not provide a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin is expected to return an object containing the configuration property along with task configuration properties

Task View

An example response body:

{
  "displayValue": "MavenTask",
  "template": "<div class=\"form_item_block\">...</div>"
}

This message is sent by the GoCD server to the plugin to get an AngularJS based HTML template to allow the task to be configured.

Request name

view

Request body

The server will not provide a request body.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin is expected to return an object containing the view rendering information task view response object

Validate Configuration

An example validation request body

{
  "URL": {
    "secure": false,
    "value": "http://localhost.com",
    "required": true
  },
  "USERNAME": {
    "secure": false,
    "value": "user",
    "required": false
  },
  "PASSWORD": {
    "secure": true,
    "value": "password",
    "required": false
  }
}

An example response body, in case there are validation errors

{
  "errors": {
    "URL": "URL is not well formed",
    "USERNAME": "Invalid character present"
  }
}

An example response body, in case there are no validation errors

{
  "errors": {}
}

This message is sent by the GoCD server to the plugin to validate if the settings entered by the user are valid, so that the server may persist those settings in the cruise-config.xml file.

Request name

validate

Request body

The request body will contain a JSON, which contains an object with the configuration keys and values that the plugin is expected to validate. If the configuration is valid, the errors object should be empty {}.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin is expected to return an error object validation errors.

Execute Task

An example request body:

{
  "config": {
    "ftp_server": {
      "secure": false,
      "value": "ftp.example.com",
      "required": true
    },
    "remote_dir": {
      "secure": false,
      "value": "/pub/",
      "required": true
    }
  },
  "context": {
    "workingDirectory": "working-dir",
    "environmentVariables": {
      "ENV1": "VAL1",
      "ENV2": "VAL2"
    }
  }
}

An example response body, in case of success

{
  "success": true,
  "message": "Finished executing task"
}

An example response body, in case of failure

{
  "success": false,
  "message": "Failed to execute task. The error was: 'Server not found'"
}

Here’s an example snippet of code to help execute custom commands and send their output to GoCD

import com.google.gson.GsonBuilder;
import com.thoughtworks.go.plugin.api.request.GoPluginApiRequest;
import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse;
import com.thoughtworks.go.plugin.api.task.JobConsoleLogger;

import java.io.File;
import java.util.*;

public class PluginExecutor {
  public DefaultGoPluginApiResponse execute(GoPluginApiRequest request) throws Exception {
    JobConsoleLogger console = JobConsoleLogger.getConsoleLogger();

    // create the process with the right cli args environment variables and working directory
    // all this is available in the requestBody
    ProcessBuilder builder = new ProcessBuilder(...);
    builder.directory(...);
    builder.environment().putAll(...);

    // print out the environment variables to the console
    console.printEnvironment(builder.environment());

    // start the process
    Process process = builder.start();

    // ensure that the process's stderr and stdout and connected to GoCD
    console.readErrorOf(process.getErrorStream());
    console.readOutputOf(process.getInputStream());

    // wait for the process to exit
    int exitCode = process.waitFor();

    if (exitCode != 0) {
      // send error response
      return new DefaultGoPluginApiResponse(200, "...");
    } else {
      // send success response
      return new DefaultGoPluginApiResponse(200, "...");
    }
  }
}

This message is sent by the GoCD agent to the plugin to execute the task.

Request name

execute

Request body

The request body will contain a JSON containing the necessary configuration provided by the user, along with the working directory where the task is expected to run, and the environment variables configured.

Response code

The plugin is expected to return status 200 if it can understand the request.

Response Body

The plugin is expected to return a status object indicating success, and a message. During the execution of the plugin, messages that need to be shown on the output console of the job can be sent to the Go Server using the an instance of JobConsoleLogger.

Request/Response JSON Objects

The Task Configuration Response Object

Here’s an example of the task configuration response object:

{
  "url": {
    "default-value": "",
    "secure": false,
    "required": true
  },
  "user": {
    "default-value": "bob",
    "secure": true,
    "required": true
  },
  "password": {
  }
}

Attribute Type Description
default-value String A value to be used as the default if the user provides no value.
secure Boolean If the value should be stored in an encrypted form in the cruise-config.xml file.
required Boolean Whether the field is required.

The Task View Response Object

Here’s an example of the task view response object:

{
  "displayValue": "MavenTask",
  "template": "<div class=\"form_item_block\">...</div>"
}

Attribute Type Description
displayValue String The name of the task that should be rendered in the view.
template String A string containing an HTML AngularJS based view.

This template is an AngularJS based template.

GoCD uses Angular JS as its template engine for the plugin UI. This allows plugin authors to use a limited set of AngularJS features to specify how the UI of their plugins looks.

Getting started with AngularJS based templates

Given a configuration:

<configuration>
  <property>
    <key>username</key>
    <value>alice</username>
  </property>
</configuration>

This gets converted into the following JSON representation in the browser:

{
  "username": "alice"
}

The AngularJS template is expected to bind to the JSON object shown above:

<div class="form_item_block">
  <label>Username:<span class='asterix'>*</span></label>
  <input ng-model="username" />
</div>

When an Angular template is used in a Go plugin, to define the configuration UI, the configuration key which is stored in the configuration XML is used everywhere and is expected to be consistent. Since Angular works off of JSON, GoCD will make sure that the key in the JSON provided to the Angular template is the same as the key in the configuration XML.

Suppose the key of the configuration property stored in the XML is “username”, with value, “alice”, then Go will make sure that the value is available to the template as “username” when used in an Angular-specific HTML attribute like “ng-model”.

Plugin Angular Architecture

So, the name “foobar” needs to be the same across the configuration XML, the Angular template as well as in any code that the plugin has.

Showing validation errors in the UI

We use some simple string replacement
to substitute GOINPUTNAME with a unique identifier
for your plugin in order to render
any server side errors

<div class="form_item_block">
  <label>Username:<span class='asterix'>*</span></label>
  <input ng-model="username" />
  <span class="form_error" ng-show="GOINPUTNAME[username].$error.server">
    {{ GOINPUTNAME[username].$error.server}}
  </span>
</div>

In case of validation errors returned by go.plugin-settings.validate-configuration, the error messages needs to be populated on the UI, use the snippet here to show the validation errors.