Initially, we shared our view on the TeamCity plugins and the motivation behind revising our plugin development approach in the dedicated blog post.
This document explains the new way of the plugin development in TeamCity. The updated plugin system lets you write any sophisticated plugin and integrate it both in the experimental UI (code-named Sakura) and classic UI. There is also a Workshop from the TeamCity Technology Day.
In addition to the previous plugin development workflow, we made a significant improvement, concentrating on the front-end aspects of the plugin development.
We guarantee that previously written plugins will work as they worked before 2020.2 EAP. New plugins will work starting from TeamCity 2020.2.
Prepare environment – instruction on how to get ready to plugin development
TeamCity 2020.2: updated Plugin Development – a blog post with Plugin Development Overview
TeamCity Technology Day 2020: Creating Plugins Using the New TeamCity Plugin UI Framework – an online workshop with the Plugin Ecosystem overview and live coding session
- Feedback and issue reporting
Demo Plugin repository – a repo with 5 dedicated branches, explaining Basic, Controlled, and React plugins
NPM module – a Node Package Manager module suitable to build rich UI plugins
- Explanation how plugins are loaded
Tutorial on remote debugging using the IntelliJ IDEA debugger
Key features of the new plugin development approach:
There is a way to integrate plugins both to the Sakura UI and the Classic UI.
All existing plugins continue to work as they worked before 2020.2.
UI plugins could be written in a more frontend-centric way, which involves modern web techs.
UI plugins are framework-agnostic, so you can use any library, framework, and bundler.
For those who prefer React, we expose our internal components, so you can write a plugin composing existing components from the Sakura UI – not only by writing everything yourself.
PlaceID – ID of a container that will render the plugin. Since 2020.2, we provide a new set of PlaceIDs, which have a prefix
SAKURA_. For example,
SAKURA_HEADER_RIGHT. The full list of SAKURA
PlaceID's is available in the NPM module
@jetbrains/teamcity-api. Those PlaceIDs are accessible only in the Sakura UI. To integrate your Frontend Plugin in the Classic UI, use the classic PlaceID (the full list is available in TeamCity OpenAPI definitions).
This list is not final. We are open to get the feedback about your expectations and needs.
PlaceID's work both in the Sakura and classic UI:
PlaceID's are available only in the Sakura UI:
PluginUIContext – context object which represents the plugin location. It contains currently selected
agentTypeId. TeamCity guarantees that each plugin will receive the latest context.
Plugin Lifecycle – set of events, each of them is invoked when the plugin content passes a certain step. For example, the plugin is mounted to a DOM, context is updated, plugin is unmounted.
Plugin Wrapper – Sakura UI entity, a React component which manages a certain
PlaceID. It reacts on the plugin UI context changes, passes updates to a plugin and manages plugin lifecycles.
TeamCityAPI – publicly exposed JS toolset which helps developers to manage plugins. Available as an NPM module and as a global JS variable (
Basic plugin – the simplest plugin. Its behavior and reaction to the
PluginUIContext are defined implicitly. It re-renders automatically every time
Controlled plugin – plugin which behavior and reaction on
Plugin Lifecycle are defined by the developer explicitly.
Development mode – special mode which shows
PlaceID containers in DOM and makes the plugin write debug information in the console. Accessible via the
Public API Reference
window.TeamCityAPI is a set of handy tools, which will help you retrieve, update, and manipulate plugins. It consists of:
Components - internal TeamCity React components we are ready to expose. Right now, there is only the one component
AllBuilds. We are looking forward to your feedback on this.
React - exposed React library. It's vital to use the same React library version to integrate your plugin into the TeamCity React vDOM tree (see the full explanation).
ReactDOM - exposed ReactDOM library. It's vital to use the same React library version to integrate your plugin into the TeamCity React vDOM tree (see the full explanation).
- utils- set of utilities:
requestJSON- function to request and parse a JSON from the server. It already contains all the headers for the request and automatically parses the response.
requestTEXT- function to request and parse a TEXT from the server. It already contains all the headers for the request and automatically parses the response.
Plugin - plugin constructor. It expects you to specify
PlaceIDand content options as arguments (read more about controlled plugins).
pluginRegistry- plugin registry which you could use to find a certain instance of your plugin.
Before starting the development, please checkout this demo repository. It will help you to avoid tons of a boilerplate Java code.
Types of Plugins
There are three types of plugins you can write with the new API:
Basic plugins rely on a simple JSP/HTML code that is requested automatically on every navigation event, for example, when a user switches between projects or build configurations or moves to a new page.
Controlled plugins – using this type, a developer explicitly defines, how the Plugin should react to the navigation events, for example, define the Context Update handler, add / remove custom event listeners.
(Single-page Application) SPA plugins are "controlled plugins" on steroids, which use React under the hood and offer you to use shared Components and Libraries.
The following documentation sections contain more detailed explanations and guides on how to create a plugin of each type:
See also Basic vs. controlled plugins.