All python code is Python 3.5+.
Having an automatic way to build GitHub pull requests before merging saves a lot of time and trouble compared with pulling, building and testing a GitHub pull request locally. TeamCity makes it easy to set this up using branch specifications. The blog post refers to a much older version of TeamCity than I’m currently working with, but the VCS root setup and branch specifications are essentially unchanged.
This article also goes into detail about how to set up build status checks in pull requests through GitHub’s branch protections settings. There’s one update I’d like to make to the Build per Pull Request section: TeamCity provides the option to disable builds in the default branch since version 2017.1.
A build configuration may need to be aware of details about the pull request: base and target branches for example. This information can be useful for configuring build and test environments. Repository information is provided by GitHub through REST or GraphQL queries. As discussed previously, GitHub is encouraging developers to move away from REST, so it makes sense use the GraphQL API.
TeamCity checks out pull request code as refs/pull/id#/head for the branch itself and refs/pull/id#/merge for the merge with the target branch. Pull request ids can be parsed in a command line build step from the Git branch name, which is stored in a VCS branch parameter, and reported to subsequent build steps using TeamCity service messages.
Building a GraphQL query by hand is difficult and not worth the effort. Designing the query in the GraphiQL app is a much better approach that also allows testing along the way:
After designing the query, I wrote some Python code using the requests library to call the GitHub GraphQL API with the query json appropriately formatted and with quotes escaped. The OAuth token used in the request was available in TeamCity as a hidden read-only parameter. The Python code was embedded into a build step since TeamCity has a plugin for running Python code in builds.
When this Python code was run, the TeamCity build parameters (%endpoint_url%, %token%, %owner%, %repo%) were replaced with values that were either set up in the build project or set in previous build steps (%pull_request_number%) and added to the build using TeamCity service messages as described above. TeamCity also supports declaring environment variables to be shared among builds.
The last two lines of the query_github_graphql function show how to set build parameters that can be used in other build steps using TeamCity service messages.