You shall not forget - reminding about pull requests in VSTS #1

Code reviews are one of the best ways to make sure, that everyone is aligned with recent code changes and allow a team to actually keep the codebase clean and well-maintained. The is one "meh" however - they require a developer to take a look and review changes. This require time and many people tend to postpone and forget about PRs(which I consider a bad practice, which discourage people from selecting different team members as reviewers). I'll show you a really easy way to remind people about waiting pull requests using VSTS REST API and Azure Functions.

Prerequisites

I won't go into details regarding authenticating REST API in VSTS in this post. If you're not sure how can you query it, check my other posts from VSTS category or read VSTS REST API basics.

Finding active pull requests

We'll start from a very easy task - we'll find active pull requests, which might require our attention. To do so we can use following endpoint:

/
GET https://{instance}/DefaultCollection/{project}/_apis/git/repositories/{repository}/pullRequests?api-version={version}[&status={string}&creatorId={GUID}&reviewerId={GUID}&sourceRefName={string}&targetRefName={string}&$top={integer}&$skip={integer}]

It's very flexible and allow you to specify many different parameters to return exactly what you wany. In our case we can simply use following version of this request:

/
https://{instance}.visualstudio.com/{project}/_apis/git/repositories/{repository}/pullRequests?api-version=3.0

It returns either an empty array of PRs(if none is active) or an array of active pull requests. In my case it returns a following result:

/
{
	"value": [{
		"repository": {
			"id": "...",
			"name": "LicznikNET vNext",
			"url": "...",
			"project": {
				"id": "...",
				"name": "LicznikNET vNext",
				"state": "unchanged",
				"visibility": "unchanged"
			}
		},
		"pullRequestId": 1,
		"codeReviewId": 1,
		"status": "active",
		"createdBy": {
			"id": "...",
			"displayName": "Kamil Mrzygłód",
			"uniqueName": "",
			"url": "...",
			"imageUrl": "..."
		},
		"creationDate": "2017-07-12T07:18:36.1561898Z",
		"title": "Merge branch ",
		"description": "Merge branch 'feature/LNETVN-204-data-should-not-be-collected-for-non-existing-locations' into develop",
		"sourceRefName": "refs/heads/develop",
		"targetRefName": "refs/heads/feature/LNETVN-204-data-should-not-be-collected-for-non-existing-locations",
		"mergeStatus": "succeeded",
		"mergeId": "...",
		"lastMergeSourceCommit": {
			"commitId": "...",
			"url": "..."
		},
		"lastMergeTargetCommit": {
			"commitId": "...",
			"url": "..."
		},
		"lastMergeCommit": {
			"commitId": "...",
			"url": "..."
		},
		"reviewers": [{
			"reviewerUrl": "...",
			"vote": 0,
			"id": "...",
			"displayName": "[LicznikNET vNext]\\LicznikNET vNext Team",
			"uniqueName": "...",
			"url": "...",
			"imageUrl": "...",
			"isContainer": true
		}],
		"url": "...",
		"supportsIterations": true
	}],
	"count": 1
}

It provides some information but there's no way to check how long we're waiting for reviewers. Let's try to find something, which will help us here.

Checking votes

Ok, let's try following approach - what if we go to our PR and try to actually mark it as Waiting for the author, as in real scenario?

I changed my PR status to "Waiting for the author"

Now let's query API once more and check results. This is what I got(I removed lines, which were not changed):

/
"reviewers": [{
	"reviewerUrl": "...",
	"vote": -5,
	"id": "...",
	"displayName": "[LicznikNET vNext]\\LicznikNET vNext Team",
	"uniqueName": "...",
	"url": "...",
	"imageUrl": "...",
	"isContainer": true
}, {
	"reviewerUrl": "...",
	"vote": -5,
	"votedFor": [{
		"reviewerUrl": "...",
		"vote": 0,
		"id": "...",
		"displayName": "[LicznikNET vNext]\\LicznikNET vNext Team",
		"uniqueName": "...",
		"url": "...",
		"imageUrl": "...",
		"isContainer": true
	}],
	"id": "...",
	"displayName": "Kamil Mrzygłód",
	"uniqueName": "...",
	"url": "...",
	"imageUrl": "..."
}],

As you can see we got some additional values for reviewers property. What is more interesting here is the vote property, which has changed from to -5. This is what will help us in the next post to make a working solution notifying team members about waiting pull requests - we'll try to find PRs with no votes, which are older than 24 hours and try to send a message to people involved in it, encouraging them to take a look at proposed changes.

Connect a release to a build in VSTS

For some reason there's no easy way to connect a release to a build when using REST API provided by VSTS. Something which should be fairly trivial seems like a task, which is impossible to finish. However there's a "dirty" way of finding a build identifier, which is related to a release we're interested in.

Digging into release data

Let's consider following request:

/
https://{account}.vsrm.visualstudio.com/defaultcollection/{projectId}/_apis/release/releases/{releaseId}?api-version=3.0-preview.2

When called it'll returns a detailed information about a release including approvals, deployment steps, workflow and many more. When you dig deeper into a response, you'll find one section, which may help us here:

"artifacts": [{
	"sourceId": "{sourceId}",
	"type": "Build",
	"alias": "some_alias",
	"definitionReference": {
		"artifactSourceDefinitionUrl": {
			"id": "https://{account}.visualstudio.com/_permalink/_build/index?collectionId=",
			"name": ""
		},
		"definition": {
			"id": "{definitionId}",
			"name": "Name"
		},
		"project": {
			"id": "{projectId}",
			"name": "Name"
		},
		"version": {
			"id": "5854",
			"name": "2017.97"
		},
		"artifactSourceVersionUrl": {
			"id": "https://{account}.visualstudio.com/_permalink/_build/index?collectionId=&buildId=5854",
			"name": ""
		},
		"defaultVersionType": {
			"id": "selectDuringReleaseCreationType",
			"name": "Specify at the time of release creation"
		},
		"branch": {
			"id": "refs/heads/develop",
			"name": "refs/heads/develop"
		}
	},
	"isPrimary": true
}]

Of course I obscured it a little, but you should be able to get the picture. In the artifactSourceVersionUrl property you can see a URL, which itself isn't helping much. What we're interested in is the very end of it - it the query string it contains a buildId key, which directly points to the build used for this release. The only thing you have to do is to parse the JSON and extract identifier, which can be used further to query for a build.

Summary

Although REST API provided by VSTS is really helpful in most cases, this time I was really confused. Fortunately even indirect solutions are still solutions so as long as there's no other API version, this workaround seems valid uncomplicated.