0

I am looking for a way to grab the pull request ID from the current branch, and pass it to a bash script inside TeamCity.

Right now I am passing in the pull request ID manually in the terminal - but I am looking for a way to grab the current pull request ID, and pass it in through TeamCity parameters into this Bash script (I plan to run this as a build step). The Teamcity API seems not to support grabbing the pull request ID.

 #!/bin/bash
 branch=$(git symbolic-ref --short HEAD)

 repository="${PWD##*/}"


 mvn sonar:sonar -Dsonar.projectKey="$repository" -Dsonar.analysis.mode=issues -Dsonar.stash.comments.reset \
        -Dsonar.stash.notification=true -Dsonar.stash.project=datasmurfen-repos  Dsonar.stash.repository="$repository" \
        -Dsonar.stash.pullrequest.id=$1   Dsonar.stash.password.variable=SONAR_STASH_PASSWORD

I have tried with:

git ls-remote | grep refs/pull-requests/

But this returns all pull requests for all branches.

Does anyone have an idea how to grab the pull request ID from TeamCity, or bash - and pass it into the script?

Robin Green
  • 32,079
  • 16
  • 104
  • 187
datasmurfen
  • 324
  • 8
  • 25

2 Answers2

4

I'm not sure whether TeamCity knows about the pull request ID. Its unlikely because the build is done on a commit, not a pull request, and it doesn't need the pull request to post the result back to Bitbucket Server. There are certainly ways to get the information you need though.

The first option I can think of is by using Bitbucket Server's Pull Request REST API (documentation here). You'd need http credentials to do the request. I'm not sure whether TeamCity has some available for you to use, but if it doesn't then you'll want to generate a personal access token so that this script is restricted with its access.

curl -u username:password https://url.to.bitbucket/rest/api/latest/projects/<project_name>/repos/<repo_name>/pull-requests?state=OPEN&at=refs/heads/<branchname>&direction=OUTGOING

You'll then have to parse the json to get the pull request out of the response (maybe doing it in something like Python would be easier than bash). Another limitation with this is that it won't get you PRs that are from a fork.

If doing it via the REST API is too difficult (because of credentials and json parsing) you may be able to do it with just git by using git name-rev to find the closest pull request ref. This is less conventional and I haven't actually tried doing this, so I think that there are likely going to be more edge cases to take care of, where as the REST API gives you a very straightforward answer.

Something like this:

> git fetch origin refs/pull-requests/*:refs/pull-requests/* # fetch all the pull-request refs
> git name-rev --name-only --refs="refs/pull-requests/*/from" HEAD # Find the pull request 'from' ref that is closest to the latest commit
pull-requests/11732/from~4^2

You'd have to strip out the 'number of commits' part if it is present (everything after the ~), and work out what to do if there were multiple pull requests at that commit (name-rev will only ever give you one ref) but you won't need to set up your credentials, and it does work for PRs from forks.

Another scenario that you'll have to consider with either option is that there may not be a pull request created yet.

Hope this helps!

Kristy Hughes
  • 586
  • 1
  • 6
  • 10
  • Thanks for the help! I ended up using the stash/bitbucket api. Bash came in short because I needed to search inside the json, so I am rewriting it in Python. – datasmurfen May 22 '18 at 08:04
  • 1
    This worked for me `id=$(curl -u user:pw "https://bitbucketserver/rest/api/latest/projects/XXX/repos/yyy/pull-requests?state=OPEN&at=refs/heads/branchName&direction=OUTGOING" | sed 's|.*pull-requests/\([0-9]*\).*|\1|')` – BYTE RIDER Jul 02 '21 at 11:30
0

Thanks to Kristy Hughes for pointing me in the right direction.

I ended up converting my script to Python instead. The XXX is the Personal access token i set under my user on in BitBucket Server, and sonar.stash.password.variable=SONAR_STASH_PASSWORD it's a local environment variable pointing to the password to SonarQube user.

#!/usr/bin/python3

import os
import requests
import subprocess

pwd =  os.getcwd()
repository = str(pwd).split("/")[-1]

getbranch = subprocess.run("git symbolic-ref --short HEAD", shell=True, stdout=subprocess.PIPE,
                    universal_newlines=True)
branch = getbranch.stdout

projectid = "myproject"

url = "https://x.mydomain.com/rest/api/latest/projects/{}/repos/{}/pull-requests".format( projectid, repository )

headers = { "Authorization": "Bearer {}".format("XXXXXX")}
r = requests.get(url, headers=headers)
print(r.json())

jsondict = r.json()
print (jsondict)

for project in jsondict["values"]:
    if project["fromRef"]["displayId"] == branch.strip():
            prid =  project["id"]
            print(prid)


buildproject = "mvn compile && git reset --hard HEAD"
 os.system(buildproject)         
print(buildproject)

buildanalysis = "mvn sonar:sonar -Dsonar.projectKey={} -Dsonar.analysis.mode=issues -Dsonar.stash.comments.reset -Dsonar.stash.notification=true -Dsonar.stash.project={} -Dsonar.stash.repository={} -Dsonar.stash.pullrequest.id={} -Dsonar.stash.password.variable=SONAR_STASH_PASSWORD".format( repository, projectid, repository, prid ) 
os.system(buildanalysis)
print(buildanalysis)
datasmurfen
  • 324
  • 8
  • 25