I've been having fun setting up TeamCity builds, specifically trying to run a static analysis build that shows it's results on a pull request. This lead me to discover some issues with the built-in TeamCity support.

It is really easy to set up a build task that runs PowerShell as its build step. With this I can arbitrarily run code and get static analysis checking. It is even easy to push the results back to GitHub using the api (see the Statuses api on GitHub for just how easy). Again it is easy to trigger a build off of the 'special' pull request branch github uses. A guide to getting all of these links working is available on the teamcity blog. But triggering the git source control checking on TeamCity turned out the be the hard bit.

There are Webhooks in GitHub. There are also Service Hooks. There is a TeamCity Service Hook. Unfortunately there are issues with both that requires some third set of code to actually make it work. Here is why.

You would think that the existing team city hook would be exactly what you need. In the settings of your repository, you can configure this, with credentials, to either start a build, or just check for changes on the associated VCS Root. This check may actually trigger a build, depending on how your build triggers are set up. The problem is that only the "push" event will trigger this service hook to fire off. Why is this an issue for Pull Requests? Because creating a Pull Request creates the "pull request" event. This means that creating a pull request does not trigger a git check for changes, and so doesn't trigger the Pull Request to run the build, which won't publish the results back to the Pull Request.

Ok, lets try the custom Web Hooks. Still a no-go. GitHub Web Hooks are ultra flexible. There is great documentation on setting up a Webhook. It event supports Secrets for signing, specifying specific events, and which format you want it to give you the information in. But its a PUSH. This means you need a particular endpoint that receives that push, and processes it's payload. There is nothing on TeamCity that matches that description. You will have to write something to catch that response and trigger the behaviour you want to see happen.

Now don't get me wrong, this is exactly what you would expect. You need to determine what the business logic to respond to the event should be. But it means to solve my Pull Request problem, I now need to actually build and host this thing to make it all work.

So for anyone else wondering why the existing tutorials don't trigger your PR builds automatically, now you know why. Enjoy building a middleman to make TeamCity do what you want as a result of what GitHub sends you :) I suggest you read the implementation of the existing service for some ideas of what your middleman might look like. This was highlighted for us even more glaringly, since we only trigger a forced fetch on TeamCity every 24 hours, so it would only run my build on a PR if I manually triggered it (or someone else happened to accept a merge or push something directly to GitHub). I'm sure this was also made worse by us always doing our Pull Requests between forks and trunk, so only on merging a PR would it trigger an update on TeamCity. And then there are the multiple VCS Roots, that updating one doesn't actually trigger all the related builds. Meh.