tcWebHooks

Integrating TeamCity with Slack.com using WebHooks

Posted on

Here is a quick example of how to integrate slack.com with TeamCity using the tcWebHooks plugin.

Messages posted to Slack.com from TeamCity using the tcWebHooks plugin.
Messages posted to Slack.com from TeamCity using the tcWebHooks plugin.

The first three messages were posted using the first example XML configuration below. The last two are more elaborate and utilise the second XML snippet.

Step by step

  1. Create a new integration in Slack by going to the “Integrations” page.
  2. Scroll to near the bottom and click on the “Incoming WebHooks” button.
  3. Choose a channel to post into and click “Add incoming webhook”. A new integration should be created.
  4. Find the section entitled “Your Unique Webhook URL” copy the URL underneath it including the Token at the end.
  5. Switch to your teamcity web page and create a new WebHook.
  6. Paste in the webhook URL from step 4 into the webhook config.
  7. Choose Name Value Pairs payload format and select your trigger events. I suggest only selecting Successful and Failed. Otherwise you will fill your Slack channel with too many events. You may only want to choose when a build changes state to further reduce noise.
  8. After you’ve saved your webhook config, you need to add the Slack specific payload options by editing the WebHooks configuration file on the TeamCity server. In TeamCity 8 it will be located at: $HOME/.BuildServer/config/projects/<your_project_name>/pluginData/plugin-settings.xml
  9. Find your newly created WebHook and add the following block of XML before the </webhook> tag.
<parameters>
    <param name="payload" value="{&quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;}"/>
</parameters>

The above XML snippet shows a simple message. Below is a more sophisticated example showing the use of the attachment JSON field to show a coloured bar and heading text on the message.

<parameters>
   <param name="payload" value="{  &quot;text&quot;: &quot;All your build failures are belong to us&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;danger&quot; } ] }"/>
</parameters>

A more complete example

This shows two full webhook XML configurations so you can see the parameter tag in context. If you look closely, you’ll see the first one only applies to build failures, and the second one only applies to build success messages. That is how you can display a different colour and message for different build results.

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <webhooks enabled="true">
     <webhook url="https://<your_slack_url>.slack.com/services/hooks/incoming-webhook?token=<your_token_here>" enabled="true" format="nvpairs">
      <states>
        <state type="buildSuccessful" enabled="false" />
        <state type="buildInterrupted" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="buildStarted" enabled="false" />
        <state type="buildFailed" enabled="true" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildFixed" enabled="false" />
        <state type="buildFinished" enabled="true" />
        <state type="buildBroken" enabled="false" />
      </states>
      <build-types enabled-for-all="true" enabled-for-subprojects="true" />
      <parameters>
        <param name="payload" value="{  &quot;text&quot;: &quot;All your build failures are belong to us&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;danger&quot; } ] }"/>
      </parameters>
    </webhook>
    <webhook url="https://<your_slack_url>.slack.com/services/hooks/incoming-webhook?token=<your_token_here>" enabled="true" format="nvpairs">
      <states>
        <state type="buildSuccessful" enabled="true" />
        <state type="buildInterrupted" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="buildStarted" enabled="false" />
        <state type="buildFailed" enabled="false" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildFixed" enabled="false" />
        <state type="buildFinished" enabled="true" />
        <state type="buildBroken" enabled="false" />
      </states>
      <build-types enabled-for-all="true" enabled-for-subprojects="true" />
      <parameters>
        <param name="payload" value="{  &quot;text&quot;: &quot;All your build successes should to be celebrated&quot;, &quot;attachments&quot;: [ { &quot;fallback&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;text&quot;: &quot;${buildName} &lt;${buildStatusUrl}|build #${buildNumber}&gt; triggered by ${triggeredBy} has a status of ${buildResult}&quot;, &quot;color&quot;: &quot;good&quot; } ] }"/>
      </parameters>
    </webhook>
  </webhooks>
</settings>

new tcWebHooks release. Proper support for TeamCity nested projects

Posted on Updated on

The alpha release from last week is now available as the main release.

This release includes the following new features.

  1. Proper support for TeamCity’s nested project structure. You can now choose if a webhook is inherited by child projects.
  2. ExtraParameters can now be templated in a similar way to the htmlStatusMessage field. This has come in handy for FlowDock integration.

Nested Project support

Webhooks can be inherited by subprojects
Webhooks can be inherited by subprojects

Previous versions of the tcWebHooks plugin did not support nested projects at all. A webhook was configured for a project and only builds in that project would fire them. This version adds support for webhooks to be inherited from parent (and higher) projects.

To enable the old behaviour, I also added control of that feature to the UI as “sub-project builds”. By default webhooks are inherited, but that inheritance can be disabled by deselecting the “All Sub-Project Builds” check box.

Extra Parameter templates

Prior to the latest release, additional parameters were static text only. This release adds the ability to template them in the same manner as the buildStatusHtml message Custom Templates detailed in a previous post.

Here is an example of their use for integration with FlowDock.

 <webhook url="https://api.flowdock.com/v1/messages/chat/your-api-key" enabled="true" format="nvpairs">
   <states>
     <state type="buildFixed" enabled="false" />
     <state type="buildStarted" enabled="false" />
     <state type="buildBroken" enabled="false" />
     <state type="buildSuccessful" enabled="true" />
     <state type="buildFinished" enabled="true" />
     <state type="responsibilityChanged" enabled="false" />
     <state type="beforeBuildFinish" enabled="false" />
     <state type="buildFailed" enabled="true" />
     <state type="buildInterrupted" enabled="false" />
   </states>
   <build-types enabled-for-all="false" enabled-for-subprojects="true">
     <build-type id="bt3" />
   </build-types>
   <parameters>
     <param name="content" value="${message}" />
     <param name="external_user_name" value="teamcity" />
     <param name="tags" value="${projectExternalId},${buildExternalTypeId},${buildResult},teamcity" />
   </parameters>
 </webhook>

These parameters will appear as part of the POST payload and have the ${variables} resolved as per the details in the previous post.

Download and feedback

As usual, please download and post any issues you find on the bugs page.

tcWebHooks 0.9 out of alpha

Posted on

The 0.9.9.155 release has been promoted to be the default download

It supports TC8 and TC7 (and probably earlier versions) and is ready for anybody who wants to use it. Please post any feedback below or on the bugs page.

tcWebHooks 0.9 update

Posted on

For those trying out the new 0.9 branch of tcWebHooks, here is a new version that supports editing webhooks applicable to the build you are viewing.

Also a couple of bug fixes.

  • Adding a new webhook was broken when there were no existing webhooks (adding the first webhook for a project).
  • Some Javascript debugging using Firebugs console, which might have errored on browsers that don’t have Firebug installed.
  • Removed some extra debugging from the javascript code.

Please try it out and let me know if you find any more bugs.

Updated tcWebHooks plugin with build specific webhooks

Posted on Updated on

A frequently requested feature for tcWebHooks is to be able to trigger webhook requests from specific builds in a TeamCity project rather than all builds in a project.

tl;dr

  • You can now select which build(s) a webhook triggers on.
  • Completely rewritten UI – might be bugs.
  • Tested on TC7 and TC8.
  • It’s alpha – Download and feedback please.

The whole story

I’m excited to announce an alpha release of the 0.9 branch which supports choosing which builds a webhook triggers on. I’d really like feedback on the usability and any bugs you find.

Editing Webhooks UI completely re-written

There are a few changes in the core webhook triggering logic which are fairly well tested. However, there has been a major re-write of the javascript and backend MVC controllers to support this extra hierarchy of information being sent back to the browser after an update. This includes moving to JSON as the edit response payload and re-writing nearly all the javascript in the edit webhooks page. This is primarily where any bugs could have crept in. I have tested on Firefox and Chrome, but don’t own a non-linux PC, so have no opportunity to test on browsers from proprietary operating systems.

The changes in the UI are visible on the following pages:

The updated WebHooks edit page

The tcWebHooks editing page now shows how many builds are configured for each webhook.

Screenshot of Edit webhooks page.
On the WebHooks editing page, each webhook shows how many builds in this project will trigger.

Updated WebHooks edit dialog

When editing a WebHook, you can choose which builds to run it on by clicking a new tab inside the Edit Webhooks popup dialog. Clicking the build count will open the dialog directly on the Builds tab. Clicking anywhere else on a webhook opens the dialog on the Webhook Config tab.

Screenshot of new Edit Webhooks dialog
The Edit Webhook dialog now has a Builds tab.

Updated WebHooks list on the Project and Build WebHook tabs

The WebHooks tab on Project pages and Build pages list webhooks per build.

I have broken down the webhooks tabs on the builds and projects pages to show webhooks relevant to all builds in a project as well as webhooks tied to specific builds.

Screenshot of Project tab.
The webhooks tab on Project and Build pages show webhooks grouped by build.

NOTE: this is one aspect that has not been completed. Editing the webhooks for a project takes you to the project webhooks page (shown above) and that page is all working. However, clicking “Edit Build Webhooks” is not currently working. I’ll keep working on that, but wanted to get this alpha out for testing while I worked on that page.

Tested on TC 7.1 and TC8

I have run the plugin on both TeamCity 7.1.5 and 8.0.0. They appear to be working fine despite the huge changes in the TeamCity OpenAPI between those versions. TeamCity introduced the ability to change ProjectId and BuildId values. This means there are now getInternal and getExternal (or similar) methods on the SProject and SBuildType interfaces. Compliing against the old API breaks stuff at runtime in TC8 and compiling against the TC8 API throws no such method errors everywhere.

To mitigate this, I’ve written a wrapper around the methods I use which falls back to the old methods if the new ones are not available. I’m hoping I’ve caught them all and from my testing of the plugin it works on both TC7.1 and TC8. Please post a comment below or on the bugs page if you experience any issues.

Please try it and post any feedback

You can download the 0.9.8.155 release from sourceforge. Please post any feedback in the comments of this post or on the tcWebHooks bugs page.

Making tcWebHooks configurable via TeamCity’s REST API : please discuss

Posted on Updated on

The TeamCity REST API looks to be quite popular (I’ve not knowingly used it). I’ve had a request to add REST API support to tcWebHooks. I’ve not written a public webservices API before. Only really web APIs for services that I control both ends of.

Note: This is not a commitment to build it, more a place to put my thoughts on whether it’s worthwhile or not and how it might work.

I see the four basic requirements.

  • List
  • Create
  • Update
  • Delete
  • Is there anything else needed? Perhaps test?

I think there are three ways it could be accomplished.

  1. Write it myself and probably get it wrong.
  2. Write it myself with a lot input from the users. Who is willing to commit to helping me spec it and test it?
  3. Write a Java API and let someone else write the webservice parts.

The stuff I’ve done before was sending and receiving JSON, and only used POST and GET. Do I need to worry about the whole strict PUT, DELETE etc verbs?

What should the request payload look like? XML? JSON? Name Value Pairs?
What should the response payload look like?

Any good examples? I presume basing it on the existing TeamCity REST API would be the path of least surprise for users. I’ve not used it so don’t have a lot of experience on how it works.

tcWebHooks release to support TeamCity 8

Posted on

TeamCity 8 has just been released and the UI in tcWebhooks was not working correctly due to the new Internal/External Project naming changes.

Basically, the page was being redirected by Teamcity whenever you went to the edit webhooks screen. My JSP controller was looking for “projectId=project01″ in the URL so it was never loading the settings into the UI.

Existing settings appeared to be fine, but editing webhooks required hacking the XML files on the server. This new release fixes that, and adds the projectExternalId value to the webhook payload.

Other than that. Webhooks appear to be firing correctly on my test server running TC8. If you find anything different, please post a comment below or on the Bugs page.

NOTE: Due to changes in the TeamCity API, this version will only work on version 8.0 and above of TeamCity.

If you’re keen to try it out, you can download it from here: tcWebHooksPlugin-0.8.29.142.zip

Extra tricks for sending webhooks to HipChat from tcWebHooks

Posted on Updated on

Brian asked in the comments about setting the notify flag and changing the colour of messages sent to HipChat channels from tcWebHooks.

I emailed the wonderfully responsive HipChat support and Garret from HipChat replied that those extra options are already enabled on the TeamCity endpoint. Because of that you can make use of an undocumented feature of tcWebHooks. “ExtraParmameters”

Edit the ${HOME}/.BuildServer/config/ProjectName/plugin-settings.xml file and add the following before the closing tag of your webhook(s).

       <parameters>
        <param name="color" value="red" />
        <param name="notify" value="1" />
      </parameters>

This will set the message to have a red background and play a sound when the message is posted to the channel. Note the bug below though.

I would suggest splitting up your webhook into two seperate webhooks. One as a “success” webhook and one as a “failed” webhook. Then you can then set the correct background colour based on the result of your build.

Here is a full example. Remember to set your HipChat API URL correctly.

<?xml version="1.0" encoding="UTF-8"?>
<settings>
  <webhooks enabled="true">
    <webhook url="https://api.hipchat.com/.........." enabled="true" format="nvpairs">
      <states>
        <state type="buildStarted" enabled="false" />
        <state type="buildSuccessful" enabled="false" />
        <state type="buildFinished" enabled="true" />
        <state type="buildFixed" enabled="false" />
        <state type="buildBroken" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildInterrupted" enabled="false" />
        <state type="buildFailed" enabled="true" />
      </states>
       <parameters>
        <param name="color" value="red" />
        <param name="notify" value="1" />
      </parameters>
    </webhook>
    <webhook url="https://api.hipchat.com/.........." enabled="true" format="nvpairs">
      <states>
        <state type="buildStarted" enabled="false" />
        <state type="buildSuccessful" enabled="true" />
        <state type="buildFinished" enabled="false" />
        <state type="buildFixed" enabled="false" />
        <state type="buildBroken" enabled="false" />
        <state type="responsibilityChanged" enabled="false" />
        <state type="beforeBuildFinish" enabled="false" />
        <state type="buildInterrupted" enabled="false" />
        <state type="buildFailed" enabled="false" />
      </states>
       <parameters>
        <param name="color" value="green" />
        <param name="notify" value="1" />
      </parameters>
    </webhook>
  </webhooks>
</settings>


Beware of a bug. Editing webhooks in the UI does not properly retain the extra parameters. I’ll fix that in the next release. Until then, you need to add them back in manually.

This is now fixed in the 0.8.27.139 release.

tcWebHooks 0.8 alpha bugfix release

Posted on Updated on

Here is a new version of the tcWebHooks 0.8 alpha.

Bug fixes:

  • buildResult was not being set for NVPAIRS format because getter and setter were missing
    NVPAIRS uses apache commons BeanUtils.describe to build the payload, and that requires getter and setters.
    The other formats use ThroughtWorks XStream which uses fields
  • Changed field buildRunner to buildRunners for NVPAIRS format. Other formats were using new pluralised field name.
  • Tidied up unused imports and variables. No more yellow triangles in Eclipse.

I’m pretty sure Jason’s comment regading the hipchat message field containing a blank build result was caused by the buildResult field missing in the NVPAIRS format.  Hopefully this will fix that message.
TODO:

  • buildStatusHtml needs to be added for ResponsibleChanged.

Download version 0.8.branch-build-25.134

As usual, please put comments below or on the bugs page.

tcWebHooks alpha release available – Now much better!

Posted on Updated on

It’s been a long time coming, but I finally got a chance to work on the tcWebHooks plugin for TeamCity.

I have an alpha release on sourceforge for download here:

The main features are:

  • buildStatusDelta information (broken, fixed, success, failure)
  • being able to trigger webhooks based on deltas (on completion).
  • buildStatusHtml field which contains an html status message containing links back to the build
  • buildStatusUrl field which contains a URL back to the build instance in case you want to roll your own links.
  • Now uses the zip file plugin format. If you are upgrading please remember to remove your old folder and jar as they are no longer required.

There are quite a few refactorings under the hood. Please backup your existing config before you upgrade because the XML format has changed and you won’t be able to roll back.

As usual, please put comments below or on the bugs page.

Here is a screen shot of the new tcWebHooks editor dialog.

It’s very very alpha at the moment. Internally it’s very different. As a result of adding these nested settings, I’ve had to change the XML format. So please please backup your config directory (folder) before installing. I have a format converter, which is unit tested, but you never know ;-)
I’ve removed the “buildStatusChanged” event. It was incredibly misleading, as most people thought it was referring to historical events, rather than in build events.

To install.

  • Shutdown teamcity.
  • Remove the tcWebhooks (or whatever you called it) folder inside your .BuildServer/plugins folder
  • Backup your .BuildServer/config folder
  • Drop the new ZIP into .BuildServer/plugins/
  • Startup teamcity.
Please let me know how you get on using the comment below.