tcWebHookTrigger is a TeamCity Build Trigger plugin for receiving webhook requests and using the information from them to trigger a build.
It presents a URL on the TeamCity server that when POST'd to will attempt to read the payload and extract pre-configured variables.
WebHook events can be sent from another system to TeamCity using this plugin. For the
rest of this document the system sending webhooks to TeamCity will be referred to as the WebHook Sender.
The first version supports payloads in the JSON format. It uses JSON Path to parse the json payload looking for values. Those values are then converted to TeamCity Build Parameters, and used to customise the build when it is triggered.
Example webhook payload.
{
"project" : {
"name" : "foo",
"branch_name" : "bugfix/12345-fix-indenting",
"ticket_number" : "12345",
"ticket_title" : "Fix indenting on Application.java source code",
"ticket_state" : "Approved"
}
}Suppose you received a webhook from a WebHook Sender with the above payload contained within it. When this payload
is sent to teamcity, the build should run against the bugfix/12345-fix-indenting branch
if the ticket_state is "Approved".
As part of the build, we'd also like to log ticket number in the format ticket-#12345
Using JSON-Path, we can extract values from the json payload using the json-path syntax.
Path Mappings are defined one per line with key/value pairs separated by double colon ::
name=branch::path=$.project.branch_name::required=true
There are four keys for which values can be assigned.
| Key | Value | Is required |
|---|---|---|
| name | Specifies the name of the variable to be defined. | Yes |
| path | The json-path specification determining how to find the value in the webhook payload | Yes |
| required | Determines if the path must be found in the document. If required, and not found, the build will not be triggered | No |
| defaultValue | A default value to use if the path is not found | No |
Filters are define one per line with key/value pairs seperated by double colon ::
name=branch::template=${branch}::regex=[\w\/-]+
There are three key for which values can be assigned.
| Key | Value | Is required |
|---|---|---|
| name | Specifies the name of the variable to be defined. | Yes |
| template | Allows creating a string made up of text and path mappings | Yes |
| regex | Specifies the regular expression to use to validate the rendered template matches. If the regex does not match, the build will not be triggered | Yes |
Note: Templates contain one or more variables in a string. The format for referencing variables is ${variable_name}.
Templates can contain multiple variables and other text. For example, the following template is valid:
template=A build on branch ${branch} was triggered by ticket number ${ticket_number}.
A path mapping or a filter named branch has a special meaning. If this is found, then the build will be triggered against that branch.
⚠️ If the branch is not valid, TeamCity will still attempt to run the build. However the build will normally fail with an error.
For the above example payload and example configuration, the build would be triggered in the following way.
- The value found at
$.project.branch_namewould be assigned to the variablebranch. It is required, so the value must be present in the payload. - The value found at
$.project.ticket_statewould be assigned to the variableticket_state. It is required, so the value must be present in the payload. - The value found at
$.project.ticket_numberwould be assigned to the variableticket_number. It is required, so the value must be present in the payload. - A new filter variable will be created called
branchfrom the value of the variable calledbranch. This value is then validated against the regular expression[\w\/-]+. - A new filter variable will be created called
ticket_state_is_approvedfrom the variable calledticket_state. This value is validated against the regular expressionApproved. - A new filter variable will be created called
ticket_number_descfrom the templateticket-#${ticket_number}. This value is validated against the regular expressionticket-#\d+. It will result in a variable calledticket_number_desccontaining the valueticket-#12345. - The following build parameters will be defined and passed to the build.
| Name | Value |
|---|---|
| branch | bugfix/12345-fix-indenting |
| ticket_state | Approved |
| ticket_number | 12345 |
| ticket_state_is_approved | Approved |
| ticket_number_desc | ticket-#12345 |
- Download the plugin zip file from releases here on github.
- Install the plugin into TeamCity as described in the docuementation
In TeamCity, triggers are configured on a build configuration.
- Navigate to the configuration page in TeamCity and select the
Triggerstab. - Click
+ Add new triggerand chooseWebhook build triggerfrom the bottom of the list. - Configure the trigger settings. See the above screenshot for an example configuration.
- Click Save, and the settings will be validated and saved.
- Go to the
General Settingstab and note theBuild Configuration ID. This will be part of the URL for the webhook endpoint.
The WebHook Trigger endpoint is installed in TeamCity by this plugin. The location is <teamcity_root_url>/app/rest/webhook-trigger/BuildConfigId. This endpoint is authenticated by TeamCity so there are two options for authenticating:
- Using Bearer Authentication (TeamCity Access Tokens) to allow the WebHook Sender to authenticate with TeamCity. This is the preferred option.
- Using Basic Authentication (username/password) to allow the WebHook Sender to authenticate with TeamCity.
An access token allows using a token to represent a user. The token can be deleted at any time and a new one created. This token represents an existing user, and allows authentication without disclosing a user's username or password.
Create a token using the following steps
- Click your username in the top right corner of TeamCity and choose
Profile. - Select the
Access Tokenstab and click theCreate access tokenbutton. - Choose your Name, Duration and Permissions. An example is shown below.

- On the next screen, take care to copy the Token value. This is the bearer authentication token, and will not be visible again.
- Configure your WebHook Sender to use Bearer authentication with the above token, or configure a specific header in the following format..
Authorization: Bearer TOKEN_VALUE, whereTOKEN_VALUEis the token from the token creation screen.
[2021-09-29 10:50:03,102] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerResolverService: Found matching SBuildType. buildType='TcPlugins_TcWebHooksOnQuimby'
[2021-09-29 10:50:03,102] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Starting Webhook Trigger processing. buildType='TcPlugins_TcWebHooksOnQuimby', triggerName='webhookBuildTrigger', triggerId='TRIGGER_6'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Webhook Payload content:
{ "project" : { "name" : "foo", "branch_name" : "bugfix/12345-fix-indenting", "ticket_number" : "12345", "ticket_title" : "Fix indenting on Application.java source code", "ticket_state" : "Approved" }}
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Parameter is resolved. Parameter will be passed to the build. name='branch', value='bugfix/12345-fix-indenting'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Parameter is resolved. Parameter will be passed to the build. name='ticket_state', value='Approved'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Parameter is resolved. Parameter will be passed to the build. name='ticket_number', value='12345'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Regex match found. name='branch', regex='[\w\/-]+', value='bugfix/12345-fix-indenting'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Regex match found. name='ticket_state_is_approved', regex='Approved', value='Approved'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Regex match found. name='ticket_number_desc', regex='ticket-#\d+', value='ticket-#12345'
[2021-09-29 10:50:03,103] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Found filter named 'branch'. Build will be requested against branch 'bugfix/12345-fix-indenting'. buildType='TcPlugins_TcWebHooksOnQuimby', triggerName='webhookBuildTrigger', branchName='bugfix/12345-fix-indenting', triggerId='TRIGGER_6'
[2021-09-29 10:50:03,107] INFO - tbrains.buildServer.ACTIVITIES - Build added to queue; Queued build {Build promotion {id=713, configuration={id=TcPlugins_TcWebHooksOnQuimby/bt2}, branch=bugfix/12345-fix-indenting, queued, custom parameters={ticket_number_desc=ticket-#12345, ticket_state=Approved, ticket_state_is_approved=Approved, ticket_number=12345, branch=bugfix/12345-fix-indenting}, creatorNodeId="MAIN_SERVER"}, triggered by "Webhook Build Trigger" (Webhook Build Trigger)}
[2021-09-29 10:50:03,107] INFO - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Build queued by Webhook Trigger processing. buildType='TcPlugins_TcWebHooksOnQuimby', triggerName='webhookBuildTrigger', triggerId='TRIGGER_6', buildId='713'
[2021-09-29 10:50:03,107] DEBUG - tbrains.buildServer.ACTIVITIES - tcWebHookTrigger-BuildTriggerHandlerService: Completed Webhook Trigger processing. buildType='TcPlugins_TcWebHooksOnQuimby', triggerName='webhookBuildTrigger', triggerId='TRIGGER_6'
