Month: August 2014

Integrating TeamCity with Slack.com using WebHooks

Posted on Updated on

Update: Since version 1.1 of tcWebHooks, this  is now much simpler. See A better way of integrating TeamCity with Slack.com using WebHooks


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>

There is a full list of the variables available.

Advertisements