The use of plugins allows you to extend the TeamCity functionality. See the list of existing TeamCity plugins created by JetBrains developers and community.

This document provides information on how to develop and publish a server-side plugin for TeamCity using Maven. The plugin will display the Hello World jsp page when using a specific URL to the TeamCity Web UI.

On this page:

A plugin in TeamCity is a zip archive containing a number of classes packed into a JAR file.

Step 1. Set up the environment

To get started writing a plugin for TeamCity, set up the plugin development environment.

  1. Download and install TeamCity on your development machine. Since you are going to use this machine to test your plugin, it is recommended that this TeamCity server is of the same version as your production server. We are using TeamCity 9.0.2 installed on Windows 8 Pro in our setup.
  2. Download and install a Java IDE; we are using Intellij IDEA 14.0.3 Community Edition, which has a built-in Maven integration.
  3. Download and install Oracle Java. Set Java_Home on your system. We are using Java 1.7.0_25.
  4. Download and install Apache Maven. Set M2_HOME. Run mvn -version to verify your setup. We are using Maven 3.2.5. in our setup.

Step 2. Generate a Maven project

We'll generate a Maven project from an archetype residing in JetBrains Maven repository; executing the following command will produce a project for a server-side-only plugin depending on 9.0 TeamCity version:

mvn archetype:generate -DarchetypeRepository=http://repository.jetbrains.com/all -DarchetypeArtifactId=teamcity-server-plugin -DarchetypeGroupId=org.jetbrains.teamcity.archetypes -DarchetypeVersion=9.0

You will be asked to enter the Maven groudId, artifactId, version and packaging for your plugin. The artifactId will be used as the internal name of your plugin.

We are using the following settings:
groudId- teamcity.plugin.demo
artifactId - demo-plugin
version - 1.0
packaging - pom

When the build finishes, you'll see that the demo-plugin directory (the same name as the artifactId) was created in the home directory of the current user.

View the project structure

The root of the demo-plugin directory contains the following:

Step 3. Add information to your plugin description

Edit the teamcity-plugin.xml file in the project root folder and add the plugin display name and description by modifying the corresponding
attributes in the file. You can also specify additional information, such as the plugin author, email and etc.

<?xml version="1.0" encoding="UTF-8"?>
<teamcity-plugin xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:shemas-jetbrains-com:teamcity-plugin-v1-xml">
  <info>
    <name>demo-plugin</name>
    <display-name>TeamCity Demo Plugin</display-name>
    <version><at:var at:name="Version" /></version>
    <description>A demonstration plugin for Quick Start Guide</description>
    <download-url>Plugin download URL</download-url>
    <email>Plugin author e-mail</email>
    <vendor>
      <name><at:var at:name="VendorName" /></name>
      <url><at:var at:name="VendorURL" /></url>
      <logo>Plugin vendor logo URL</logo>
    </vendor>
  </info>
  <deployment use-separate-classloader="true" />
</teamcity-plugin>

Step 4. Create the project sources

Open the pom.xml from the project root folder with Intellij IDEA.

We are going to make a controller class which will return Hello.jsp via a specific TeamCity URL.

A. Create the plugin web-resources

The plugin web resources (files that are accessed via hyperlinks and JSP pages) are to be placed into the buildServerResources subfolder of the plugin's resources:

  1. First we'll create the directory for our jsp: go to the src\main\resources directory in IDEA, right-click the folder, select New -> Directory and create the buildServerResources directory.
  2. Next go to the src\main\resources\buildServerResources, right-click the folder, select New -> File and create the hello.jsp file.

B. Create the controller

Go to \src\main\java\pom and open AppServer.Java to create a custom controller:

  1. We'll create a simple controller which extends the TeamCity
    class and implements BaseController.doHandle(HttpServletRequest, HttpServletResponse) method.
  2. The TeamCity open API provides the which allows registering custom controllers using the path to them: the path is a part of URL starting with a slash / appended to the URL of the server root.
    At the moment our AppServer.Java file looks as follows:
    package zip;
    
    import jetbrains.buildServer.controllers.BaseController;
    import jetbrains.buildServer.web.openapi.WebControllerManager;
    import org.jetbrains.annotations.Nullable;
    import org.springframework.web.servlet.ModelAndView;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class AppServer extends BaseController {
        public AppServer (WebControllerManager manager) {
            manager.registerController("/demo-plugin.html",this);
        }
    
        @Nullable
        @Override
        protected ModelAndView doHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            return null;
        }
    }
    

C. Construct the path to your JSP file

When a plugin is unpacked on the TeamCity server, the paths to its resources change. To obtain valid paths to your JSP after the plugin is installed, use the class which implements the getPluginResourcesPath method; otherwise TeamCity might have difficulties finding your resources.

package zip;

import jetbrains.buildServer.controllers.BaseController;
import jetbrains.buildServer.web.openapi.PluginDescriptor;
import jetbrains.buildServer.web.openapi.WebControllerManager;
import org.jetbrains.annotations.Nullable;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class AppServer extends BaseController {
    private PluginDescriptor myDescriptor;

    public AppServer(WebControllerManager manager,PluginDescriptor descriptor) {
        myDescriptor = descriptor;
        manager.registerController("/demo-plugin.html",this);
    }


    @Nullable
    @Override
    protected ModelAndView doHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        return new ModelAndView(myDescriptor.getPluginResourcesPath("Hello.jsp"));
    }
}

D. Update the Spring bean definition

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans default-autowire="constructor">
    <bean class="zip.AppServer"/>
</beans>

Build your project with Maven

Go to the root directory of your project and run

mvn package

The target directory of the project root will contain the <artifactId>.zip file. It is our plugin package, ready to be installed.

Step 4. Install the plugin to TeamCity

Copy the plugin zip to <TeamCity Data Directory>/plugins directory.
Restart the server and locate the TeamCity Demo Plugin in the Administration|Plugins List to verify the plugin was installed correctly.

The hello World page is available via <TeamCity server URL>/demo-plugin.html