How to pack agent plugin for TeamCity

In this post I'll describe how to pack build agent plugins for TeamCity 6.5 or newer.

To start, have a look at plugin development page in TeamCity documentation. There you'll find information on how to prepare server-side plugin for TeamCity. Server-side plugin package may contain agent plugin(s). Below you'll find only description of agent-side plugins.

TeamCity build agent supports 3 type plugins:
- old plugin type (with plugin name folder in .zip)
- new plugin (with teamcity-plugin.xml)
- tool plugin (with teamcity-plugin.xml)

Starting from pre 1.0 versions old plugin schema was widely used. Every plugin must be packaged in .zip file with following structure inside:
agent-plugin-name.zip | - agent-plugin-name | - lib | - plugin.jar - plugin-lib.jar
There should be no other items in the root of .zip but folder with plugin name. TeamCity build agent detects and loads such plugins using shared classloader.

Starting from 6.5 we added new plugin schema of packing. For now, every plugin may be packed in more flexible structure:
agent-plugin-name.zip | - teamcity-plugin.xml
- lib | plugin.jar plugin.lib 
Plugin name now is obtained from plugin .zip file name. There is no plugin named folder inside a plugin archive.
The main change is that now it's required to have teamcity-plugin.xml file under the root of agent plugin .zip file.

This file provides description of plugin (same as it is done on the server-side):

In TeamCity 6.5 we introduced tool plugin for agent. This is a kind of plugin without any classes loaded into runtime. If you like to deploy a tool, use the following teamcity-plugin.xml file:

Tool plugins for agent may be useful if you need to distribute a binary files only, i.e. git binaries or some other tool. For example: NuGet plugin for TeamCity creates a tool plugin for agent to distribute downloaded NuGet.exe to agents.

Do you like to see .xsd schema for teamcity-agent.xml. This is the schema:

Agent tries to validate plugin-provided teamcity-plugin.xml file against given schema. If teamcity-plugin.xml is not valid plugin will be loaded, but no data from the descriptor is used.