Run CI build on pull request merge in TeamCity - merge

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)

Related

Can Azure Devops pipelines, where the build failed, show the user of the last commit when triggered with CI?

I'm doing Visual Studio builds on a self hosted agent, which are currently being triggered by the Continuous Integration setting in an Azure Devops pipeline.
When a build completes, it shows: Triggered by Microsoft.VisualStudio.Services.TFS
It also shows the repository, branch and revision number.
However, it is expected it would show Triggered by , If not showing the correct Azure Devops user, at least showing the Subversion user name, that would be something.
There was an expectation it would be possible to send email notifications to the user of the commit. (Not fool proof that they caused the problem, but the most convenient way to give the responsibility to somebody to make sure any build error gets resolved)
Does anybody know if a solution exists?
In both Classic and yaml pipelines, you can specify a condition for a pipeline step. If you want it to run when the pipeline fails, it will be condition: failed() (in yaml), or Control Options -> Run this task -> Only when a previous task has failed (in Classic). Alternativel, you can check Agent.JobStatus variable.
there's no predefined variable for current committer, but you can easily determine the last commit's author by using svn command, then log it. (any other version control system will have its own CLI that should allow it).
In yaml, it could look like this (using git instead of svn):
steps:
... (your build)
- bash: |
author=`git log -1 --pretty=format:'%ae'` # get last commit author from git
echo "last commiter: $author"
# TODO: send email or other kind of notification
condition: failed()
In classic one:
You are using wrong tool for you task. CI build will be triggered after changes was committed to branch. In that case it is not possible to fix those changes. As a result you will have history where a lot of revisions are not stable.
It might be more suitable for you to use PR policy build. It is designed to validate incoming changes so target branch will be always stable and ready to some deploy. In this case, policy build will be triggered by PR creator so he will be informed about it's result. That can be configured in personal notification settings.
In the end I couldn't Continuous Integration triggers to reliably work. They would always stop working after a short time. I'm surprised I have ran into so many issues with this, but I guess it just isn't that well supported.
Instead, now, I am queue the build via an svn post-commit hook which uses the azure devops REST API.
the REST API has setting, requestedFor":{"id":""}, where you can add the user id (which I also needed a rest api command to find)
A lot of messing around to get to this point, for a feature I expected to 'just work', hopefully this keeps working

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:

Build pull requests to specific branch using TeamCity and 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

How you increment the version number using Travis CI?

The project that I am working on is a jQuery plugin. I have managed to get Travis CI to build a test project using Gulp/NodeJS successfully. Now I am trying to work out what workflow to use to bump the version number.
In TeamCity and MyGet there is a setting in the CI server to form a version number pattern that auto increments on each build, which can be used by the build script to update versions in the deployment files and to label the Git repo. However, in the free version of Travis CI, there doesn't seem to be an option for versioning at all.
I have read several articles on continuous deployment with Travis CI, here, here, and here, but none of them even broach the topic of versioning. Obviously, the version needs to be changed for the release. So what am I missing here?
Another problem I noted when going through the documentation is that it mentioned that Travis CI is not able to update the GitHub repository. Doesn't that basically mean it won't be able to create a Git tag?
If there is no way to version from Travis CI, then what is the typical workflow for the release process for such a plugin? Is the versioning always done manually? If so, how could there be "continuous deployment"?
Before it starts running the instructions in your .travis.yml file, Travis will set a bunch of environment variables (in the VM that is building your project) with various bits of information about your build, such as what branch is being built and so on.
You probably want one of these:
TRAVIS_BUILD_NUMBER: The number of the current build (for example, “4”).
TRAVIS_JOB_NUMBER: The number of the current job (for example, “4.1”).
But it's going to be very difficult to do anything sensible if you don't have control of the repository, because you'll need to upload a .travis.yml file into the root of your source code folder, otherwise Travis won't know what to do.
Use bumped for release versioning. When you're satisfied with the changes in master, run:
bumped release <major|minor|patch>
After you push the changes, either directly or through a release PR, you can check for the presence of new tags in Travis CI and publish the package to the registry automatically.
If you consider that every PR must end up to your enduser without thinking of the impact of such changes, then your version numbers have no meaning.
You don't give your user a way to know if it is a major change that break compatibility or a bug fix. You don't allow him to get update without worrying about backward compatibility.
Currently, the commit id is your version number.
If you want to give meaning to your version numbers then you have to think of the impact of your pull requests on the enduser (http://semver.org/). You have to choose a version number for a specific PR or a group of PR.
So basically, since you have to 'think' of a certain version number for a specific version that you want to deliver, you can't automate this process.
Release/tag creation is the way to go : )
You can accomplish this by setting up a script that would create a ~/.netrc file to access the repository. In this file you can specify something like:
machine https://github.com/xxx/yyy.git
login <blah>
And instead of putting in your credentials, you can pass an github access token. You can use the travis encrypt to register it in the .travis.yml file, and export the variable for your script's use. From there in your script, you can issue regular git commands such as:
git add <some file>
git commit -m "This is $TRAVIS_BUILD_NUMBER"
git push origin <branch>

How to stop TeamCity from building a pull request when it is viewed or commented?

Currently, my team is using TeamCity to automatically build pull requests from GitHub.
We have a configuration to build all the pull requests. In the version control settings of the config, our branch specification is
+:refs/pull/*/merge
In the "Build Triggers" configuration setting, we have only one trigger with the following trigger rule:
+:root=Pull Requests on our Repository:\***/*\*
"Pull Requests on our Repository" is our VCS root name.
The issues:
When someone views a pull request on GitHub website without doing anything else, a build would be triggered in the TeamCity build agent. This is quite annoying, because from time to time, we have multiple build agents building the same pull requests (when multiple people view it).
When someone comments on a pull request, a build would also be triggered.
From my perspective, the only time I want TeamCity to start a build is when new commits are pushed to the pull requests.
Is there a way to do it?
Github's refs/pull/*/merge branches are updated every time mergeability of the branch is recalculated, i.e. on every commit to destination (most likely master) branch. They are also updated when pull request is closed and then reopened. Github's support says these branches are not intended for end users use. The only workaround at the moment is to run builds on refs/pull/*/head branches automatically and on refs/pull/*/merge branches manually.
Do you have TeamCity configured as per this blog post? I then activate the TeamCity service hook in GitHub which takes care of triggering a build in TeamCity whenever there is a push. This seems to do the right thing for me. Or am I missing something?
I know this is old but I wanted to post what we've found as alternatives:
Stop using VCS roots altogether as a mechanism for triggering pull requests. Instead, configure a GitHub webhook to notify a web app of yours whenever there is an update to a PR and only then trigger a build via the TeamCity REST API.
In your build config, add a step that checks what changed in the PR. If nothing changed (i.e. no new commits were added), or if the PR is closed, cancel the build. The problem with this is that the build queue will still be populated with builds that will then be cancelled. Also, you'd have to store somewhere the last commit that was built in order to do the check.
According to their TeamCity's issue tracker, the issue of the TeamCity.GitHub plugin causing an infinite loop of builds was fixed in v9.0