Build pull requests to specific branch using TeamCity and Github - github

I want TeamCity to build all pull requests to specific target branch, e.g. develop.
So, I want to build following pull requests:
develop...foo_branch
develop...bar_branch
and skip this:
master...foo_branch
master...bar_branch
In TeamCity I can define branch specification to build all pull requests:
+:refs/pull/*/head
or define filter by source branch:
-:refs/heads/(spikes-*)
But I need filter by target branch. Is it possible?

I've written a script to work around this issue. It can be run as one of the first build steps in TC's build configuration. The script will ask for pull request details from Github, parse the response and inject source and target branch names as TeamCity parameters and environment variables. In the next build steps, you'll be able to abort the build or do whatever else you need based on these variables.
https://gist.github.com/dzzh/a6d8631e9617777fb5237bc9ec7b356b
For the script to work, you'll have to submit PR's id as a command-line argument. We use the recommended refspec (refs/pulls/*/head) to run our builds, I extract the PR id from it and invoke the script with it.

Currently it's not possible to differentiate pull request branches based on their target branch in TeamCity. Please watch/vote for the request https://youtrack.jetbrains.com/issue/TW-43759 which is planned for the upcoming release.

Build Feature: Pull Request
Pull request support is implemented as a build feature in TeamCity. The feature extends the VCS root’s original branch specification to include pull requests that match the specified filtering criteria.
To configure the pull requests support for a build configuration, go to Build Configuration Settings | Build Features, click Add build feature, and select the Pull Requests feature from the dropdown list in the dialog.
Source: https://blog.jetbrains.com/teamcity/2019/08/building-github-pull-requests-with-teamcity/
So the filtering is done with the Build Feature: Pull Request, where By target branch: should be set to the targetet branch for example refs/head/master or refs/head/myspecialbranch

Related

How can I access the artefact from a pull request for which a build was run?

I'm using azure for a windows app and so I don't really need to go as far as CD as that isn't really relevant. We eventually plan to move to the cloud but for now that is not the case.
I have now got my .net (c#) build running as a build pipeline and I have a develop branch which Pull Requests are used to merge in changes. What I want is for a tester to be able to pick up the build artefact that was created for a particular bug or product backlog item when the pull request was successfully completed. Is this possible without having a Release Pipeline? I don't currently have a subscription that would allow me to create a release pipeline.
How can I access the artefact from a pull request for which a build was run?
Indeed, just as Lucas said, if we are starting from the pull request to solve this problem, it is really difficult. But we could try reverse thinking to start with the build pipeline.
Azure devops provided us some predefined variables, like Build.BuildId, System.PullRequest.PullRequestId.
So, we could use the REST API Pull Requests - Update in the build pipeline to update the comment with the link to the artifact.
PATCH https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/pullrequests/{pullRequestId}?api-version=5.1
Since the current build is triggered by a pull request, we could use the predefined variable System.PullRequest.PullRequestId to get the pullRequestId directly.
Now, we just need to get the link of the artifact, we could use the Artifacts - Get to get the artifact info:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=4.1
We could get the buildId by the predefined variable Build.BuildId, then we will get the download URL:
So the idea of summing up my solution is to use REST API Pull Requests - Update in the build pipeline to update the comment of the pull request, which contains the download path of the artifact.
Note: You could also add custom conditions in the REST API task in the build pipeline:
and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
So, with this setting, only the build triggered by the pull request will execute this rest api task.
Hope this helps.
The pull request build that you defined can publish artifacts, see this documentation to see how to do it.
Once those artifacts are published, your tested can browse/download them on the build run page (click on header pa> "Related" > click on "#number of artifacts you publish# published").
Alternatively, you could add a task to copy your artifacts to an Azure Blob Storage, but that would require more configuration.
One can find build id with branchName filter :
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.0&reasonFilter=pullRequest&definitions={buildDefinitionId}&branchName=refs/pull/{pullRequestId}/merge
Once builder id has been retrieved, get artifact by name :
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds/{buildId}/artifacts?artifactName={artifactName}&api-version=6.0

Automatically Tagging a PR Build in Azure Devops

I have branch validation in the form of a PR Build, which means I have duplicated my original build and removed some steps (such as pushing to my docker registry).
I would prefer to simply be able to automatically add a tag / some kind of identifier to a PR build and exclude the step on the original build using custom conditions.
Does anyone know if this is possible, and if so how to achieve it? I'd really rather not duplicate each and every build.
If I understand your question correctly, you would like to run a build step based on a custom condition. In this case, the custom condition is whether the build is a PR build or not.
You can check the pre-defined build variables available in Azure Devops here and you can see that there is a Build.Reason variable.
I am listing a few variables here.
Manual: A user manually queued the build.
IndividualCI: Continuous integration (CI) triggered by a Git push or a TFVC check-in.
PullRequest: The build was triggered by a Git branch policy that requires a build.
You can specify the condition in custom condition settings of your build step like this.
More examples available in the docs

VSTS: how to requeue broken build and switch agent queue

Background:
We are running Visual Studio Team Services (VSTS) with Gitflow and have been trying to use a private pipeline with local build agents on our laptops. However, our local agents have been having trouble and for a particular pull request, the build is failing against this local agent. I have edited the build definition to use the Hosted2017 agent and want to requeue the Pull Request. I can manually queue a build off of the sha1 hash for the PR's commit to test out the agent. However, I would like to complete the pull request and I will the build to succeed and it doesn't seem like I can make the PR's build use the updated build definition.
Question:
So how do I get the Pull Request to get this build to work? I don't see an option to switch the build definition for the pull request? Do I just need to abandon and redo the PR or is there a way I can fix this PR without asking the developer that created it to jump through hoops so I can fix the build process?
Thanks!
You can requeue the build for PR validation as below (for two situations):
Situation 1: Same build definition for PR validation, only change the Agent Queue for the build
After saving the changes (change Agent queue) for the build definition, you can just to queue the build manually:
Open the Pull Request -> click ... button (on the right of the build) -> click Queue build.
Then the build to verify the PR will be queued, and after the build is successful, you can merge the PR to continue the gitflow.
Situation 2: Use another build definition for PR validation
For this situation, you just need to change the branch policy to replace the PR build validation with the new build definition:
In branch policy -> Edit the build definition for PR validation -> select the new build definition for it -> save.
Then you can requeue the build as the way in situation 1.

How to set up a github pull request build in a Jenkinsfile?

So, I've been using Jenkins for quite a while. I have set up numerous projects with the Github Pull Request Builder plugin to run tests whenever someone opens a pull request, and then trigger some other job (build, push, deploy, etc) whenever the pull request actually gets merged to master.
So, is there any way to set this up with a Jenkinsfile, or the organization folders, or the multibranch build deal?
The github-organization-folder plugin in combination with the multi-branch plugin plugin offers exactly this awesome feature: It scans a whole organization (optionally restricted to certain patterns in repo/branch names) for Jenkinsfiles and automatically adds jobs. This also happens for Pull Requests.
Once the PR is closed, it automatically removes the job.
To avoid arbitrary code execution, an organization member has to trigger building the job (same as for the GPRB plugin). The phrase can be configured in the Jenkins System settings.
EDIT: Under the Advanced section in Jenkins, you find options about what types of PR you want to build. If you build fork PRs, then there's afaik no way to prevent running code without prior inspecting it.
An example, how this looks like:

Run CI build on pull request merge in TeamCity

I have a CI build that is setup in TeamCity that will trigger when a pull request is made in BitBucket (git). It currently builds against the source branch of the pull request but it would be more meaningful if it could build the merged pull request.
My research has left me with the following possible solutions:
Script run as part of build - rather not do it this way if possible
Server/agent plugin - not found enough documentation to figure out if this is possible
Has anyone done this before in TeamCity or have suggestions on how I can achieve it?
Update: (based on John Hoerr answer)
Alternate solution - forget about TeamCity doing the merge, use BitBucket web hooks to create a merged branch like github does and follow John Hoerr's answer.
Add a Branch Specification refs/pull-requests/*/merge to the project's VCS Root. This will cause TeamCity to monitor merged output of pull requests for the default branch.
It sounds to me like the functionality you're looking for is provided via the 'Remote Run' feature of TeamCity. This is basically a personal build with the merged sources and the target merge branch.
https://confluence.jetbrains.com/display/TCD8/Branch+Remote+Run+Trigger
"These branches are regular version control branches and TeamCity does not manage them (i.e. if you no longer need the branch you would need to delete the branch using regular version control means).
By default TeamCity triggers a personal build for the user detected in the last commit of the branch. You might also specify TeamCity user in the name of the branch. To do that use a placeholder TEAMCITY_USERNAME in the pattern and your TeamCity username in the name of the branch, for example pattern remote-run/TEAMCITY_USERNAME/* will match a branch remote-run/joe/my_feature and start a personal build for the TeamCity user joe (if such user exists)."
Then setup a custom "Pull Request Created" Webhook in Bitbucket.
https://confluence.atlassian.com/display/BITBUCKET/Tutorial%3A+Create+and+Trigger+a+Webhook
So for your particular use case with BitBucket integration, you could utilize the WebHook you create, and then have a shell / bash script (depending on your TeamCity Server OS) that runs the remote run git commands automatically, which will in turn automatically trigger the TeamCity Remote Run CI build on your server. You'll then be able to go to the TeamCity UI, +HEAD:remote-run/my_feature branch, and view the Remote Run results on a per-feature basis, and be confident in the build results of the code you merge to your main line of code.
Seems that BitBucket/Stash creates branches for pull requests under:
refs/pull-requests//from
You should be able to setup a remote run for that location, either by the Teamcity run-from-branch feature, or by a http post receive hook in BitBucket/Stash.
You can also use this plugin : https://github.com/ArcBees/teamcity-plugins/wiki/Configuring-Bitbucket-Pull-Requests-Plugin
(Full disclosure : I'm the main contributor :P, and I use it every day)