Skip to content

Commit

Permalink
feat(apps): create githubWebhook function
Browse files Browse the repository at this point in the history
Create initial function for handling githubWebhooks to store pull request information.
  • Loading branch information
josephperrott committed Apr 4, 2022
1 parent 82ecd90 commit 28d1d81
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 7 deletions.
3 changes: 2 additions & 1 deletion apps/functions/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ts_library(
"index.ts",
],
deps = [
"//apps/functions/githubWebhook",
"@npm//firebase-functions",
],
)
Expand All @@ -26,7 +27,7 @@ esbuild(
entry_points = [
"index.ts",
],
format = "cjs",
format = "esm",
visibility = ["//apps:__pkg__"],
deps = [
":functions",
Expand Down
29 changes: 29 additions & 0 deletions apps/functions/githubWebhook/BUILD.bazel
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
load("//tools:defaults.bzl", "ts_library")

package(default_visibility = ["//visibility:private"])

ts_library(
name = "githubWebhook",
srcs = [
"index.ts",
],
visibility = [
"//apps/functions:__pkg__",
],
deps = [
":webhooks",
"@npm//firebase-admin",
"@npm//firebase-functions",
],
)

ts_library(
name = "webhooks",
srcs = [
"pull-request.ts",
],
deps = [
"//apps/shared/models:server",
"@npm//@octokit/webhooks-types",
],
)
34 changes: 34 additions & 0 deletions apps/functions/githubWebhook/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import {handlePullRequestEvent} from './pull-request';

admin.initializeApp({...functions.firebaseConfig()});

/**
* Firebase function to handle all incoming webhooks from Github. This function checks the incoming
* webhook to ensure it is a valid request from Github, and then delegates processing of a payload
* to one of the other githubWebhook functions.
*/
export const githubWebhook = functions
.runWith({invoker: 'public', timeoutSeconds: 30, minInstances: 1})
.https.onRequest(async (request, response) => {
if (request.method !== 'POST') {
response.status(405);
response.send('Requests must be made using the POST method.');
return;
}
if (request.headers['content-type'] !== 'application/json') {
response.status(415);
response.send('Request payloads must be "application/json".');
return;
}

if (request.get('X-GitHub-Event') === 'pull_request') {
await handlePullRequestEvent(request.body);
response.send(`Handled pull request update for pr #${request.body.pull_request.number}`);
response.end();
return;
}

response.end();
});
8 changes: 8 additions & 0 deletions apps/functions/githubWebhook/pull-request.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {PullRequestEvent} from '@octokit/webhooks-types';
import {PullRequest} from '../../shared/models/server-models';

export async function handlePullRequestEvent(event: PullRequestEvent) {
const docRef = PullRequest.converter.getFirestoreRefForGithubModel(event.pull_request);
const pullRequest = PullRequest.converter.fromGithub(event.pull_request);
await docRef.set(pullRequest);
}
2 changes: 1 addition & 1 deletion apps/functions/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
import * as functions from 'firebase-functions';
export {githubWebhook} from './githubWebhook/index';
1 change: 0 additions & 1 deletion apps/shared/models/app-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ export const Status = forApp(GithubStatus);
export const Team = forApp(GithubTeam);
export const Check = forApp(GithubCheck);


/**
* Mixin for models, allowing them to be used in web app environments leveraging Firestore. This
* mixin provides the `converter` object used for reading and writing to Firestore, using the
Expand Down
2 changes: 0 additions & 2 deletions apps/shared/models/base.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/**
* Because it is less expensive to store strings than Firestore references, with no change in the
* value it provides, we have this local type to express this usage.
Expand All @@ -21,4 +20,3 @@ export abstract class GithubBaseModel<T> extends BaseModel<T> {
/** Helper functions for translating Github objects to Firestore. */
protected static githubHelpers: GithubHelperFunctions<any, any> | undefined;
}

2 changes: 1 addition & 1 deletion apps/shared/models/pull-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {GithubTeam} from './team';
import {GithubUser, isUserFromGithub} from './user';

interface FirestorePullRequest {
owner: FirestoreReference<GithubUser>;
owner: FirestoreReference<GithubUser>;
repo: string;
node: string;
state: PullRequest['state'];
Expand Down
2 changes: 1 addition & 1 deletion apps/shared/models/server-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ type WithAdminFirestoreDataConverter<Model> = Model & {
/**
* A model which has been setup for usage in a Firebase functions (firebase-admin) environment,
* with additional expectation/support for converting from a Github webhook payload.
*/
*/
type WithAdminFirestoreDataConverterAndGithub<Model, GithubModel> = Model & {
converter: AdminFirestoreDataConverter<Model> & {
fromGithub: (model: GithubModel) => Model;
Expand Down

0 comments on commit 28d1d81

Please sign in to comment.