chore(dashboard): http function to list pull requests with conflicts (#6675)

Introduces a new http trigger in the Dashboard functions that returns all Pull Requests with merge conflicts. This allows us to show a list of PRs with merge conflicts in the dashboard.

To ensure that the API calls are as fast as possible, the pull requests with conflicts are queried using Github's new GraphQL API.
This commit is contained in:
Paul Gschwendtner
2017-09-29 01:05:46 +02:00
committed by Jeremy Elbourn
parent 248dee8265
commit c021e94fce
6 changed files with 87 additions and 24 deletions
+1
View File
@@ -1 +1,2 @@
export {payloadGithubStatus} from './payload-github-status';
export {pullRequestsWithConflicts} from './pull-requests-with-conflicts';
@@ -0,0 +1,22 @@
import {GraphQLClient} from 'graphql-request';
import {config} from 'firebase-functions';
import * as GithubApi from 'github';
/** API token for the Github repository. Required to set the github status on commits and PRs. */
const githubAccessToken = config().secret.github;
/** API Endpoint for the Github API v4 using GraphQL. */
const githubApiV4Endpoint = 'https://api.github.com/graphql';
/** Export the GitHub V3 API instance that is authenticated. */
export const githubApiV3 = new GithubApi();
/** Export the GraphQL client that can be used to query the Github API v4. */
export const githubApiV4 = new GraphQLClient(githubApiV4Endpoint, {
headers: {
Authorization: `Bearer ${githubAccessToken}`,
}
});
// Authenticate the Github API package with the user token.
githubApiV3.authenticate({type: 'token', token: githubAccessToken});
@@ -0,0 +1,43 @@
import {githubApiV4} from './github-api';
/** GraphQL query that finds all Pull Requests and their mergeable state. */
const getOpenPullRequestsWithMergeableStateQuery = `
query getOpenPullRequestsWithMergeableState($lastCursor: String) {
repository(owner: "angular", name: "material2") {
pullRequests(states: OPEN, first: 100, after: $lastCursor) {
pageInfo {
hasNextPage,
endCursor
}
nodes {
number,
mergeable
}
}
}
}`;
/** Pull Request node that will be returned by the Github V4 API. */
export interface PullRequestWithMergeableState {
number: number;
mergeable: string;
}
/** Queries the GitHub API to find all open pull requests and their mergeable state. */
export async function getOpenPullRequestsWithMergeableState()
: Promise<PullRequestWithMergeableState[]> {
const nodes: PullRequestWithMergeableState[] = [];
let lastData: any|null = null;
while (!lastData || lastData.repository.pullRequests.pageInfo.hasNextPage) {
lastData = await githubApiV4.request(getOpenPullRequestsWithMergeableStateQuery, {
lastCursor: lastData && lastData.repository.pullRequests.pageInfo.endCursor
});
nodes.push(...lastData.repository.pullRequests.nodes);
}
return nodes;
}
@@ -1,10 +1,4 @@
import {config} from 'firebase-functions';
const request = require('request');
const {version, name} = require('../package.json');
/** API token for the Github repository. Required to set the github status on commits and PRs. */
const repoToken = config().secret.github;
import {githubApiV3} from './github-api';
/** Data that must be specified to set a Github PR status. */
export type GithubStatusData = {
@@ -18,25 +12,13 @@ export type GithubStatusData = {
export function setGithubStatus(commitSHA: string, data: GithubStatusData) {
const state = data.result ? 'success' : 'failure';
const requestData = {
return githubApiV3.repos.createStatus({
owner: 'angular',
repo: 'material2',
sha: commitSHA,
state: state,
target_url: data.url,
description: data.description,
context: data.name,
description: data.description
};
const headers = {
'Authorization': `token ${repoToken}`,
'User-Agent': `${name}/${version}`
};
return new Promise((resolve, reject) => {
request({
url: `https://api.github.com/repos/angular/material2/statuses/${commitSHA}`,
method: 'POST',
body: requestData,
headers: headers,
json: true
}, (error: any, response: any) => error ? reject(error) : resolve(response.statusCode));
});
}
+2
View File
@@ -6,6 +6,8 @@
"@types/jsonwebtoken": "^7.2.1",
"firebase-admin": "~4.2.1",
"firebase-functions": "^0.5.7",
"github": "^10.0.0",
"graphql-request": "^1.3.4",
"jsonwebtoken": "^7.4.1",
"request": "^2.81.0",
"ts-node": "^3.0.6",
@@ -0,0 +1,13 @@
import {https} from 'firebase-functions';
import {getOpenPullRequestsWithMergeableState} from './github/github-graphql-queries';
/**
* Firebase HTTP trigger that responds with a list of Pull Requests that have merge conflicts.
*/
export const pullRequestsWithConflicts = https.onRequest(async (_request, response) => {
const pullRequests = (await getOpenPullRequestsWithMergeableState())
.filter(pullRequest => pullRequest.mergeable === 'CONFLICTING');
response.status(200).json(pullRequests);
});