Skip to content

Commit a804d21

Browse files
author
Fran Ortiz
committed
Add Github Check (noServerNovember)
1 parent 9897044 commit a804d21

File tree

11 files changed

+6336
-0
lines changed

11 files changed

+6336
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ serverless install -u https://github.com/serverless/examples/tree/master/folder-
5252
| [Aws Fetch File And Store In S3](https://github.com/serverless/examples/tree/master/aws-node-fetch-file-and-store-in-s3) <br/> Fetch an image from remote source (URL) and then upload the image to a S3 bucket. | nodeJS |
5353
| [Aws Function Compiled With Babel](https://github.com/serverless/examples/tree/master/aws-node-function-compiled-with-babel) <br/> Demonstrating how to compile all your code with Babel | nodeJS |
5454
| [Aws Github Webhook Listener](https://github.com/serverless/examples/tree/master/aws-node-github-webhook-listener) <br/> Extend your github repositories with this github webhook listener | nodeJS |
55+
| [Aws Github Check](https://github.com/serverless/examples/tree/master/aws-node-github-check) <br/> Check that your Pull Requests contain some desired rules | nodeJS |
5556
| [Aws Node Graphql Api With Dynamodb](https://github.com/serverless/examples/tree/master/aws-node-graphql-api-with-dynamodb) <br/> A single-module GraphQL endpoint with query and mutation functionality. | nodeJS |
5657
| [Aws Iot Event](https://github.com/serverless/examples/tree/master/aws-node-iot-event) <br/> Example on how to setup a AWS IoT Rule to send events to a Lambda function | nodeJS |
5758
| [Dropbox](https://github.com/serverless/examples/tree/master/aws-node-oauth-dropbox-api) <br/> dropbox integration | nodeJS |

aws-node-github-check/.babelrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"plugins": ["source-map-support", "transform-runtime"],
3+
"presets": [
4+
["env", { "node": "8.10" }],
5+
"stage-3"
6+
]
7+
}

aws-node-github-check/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
node_modules
3+
.serverless
4+
.webpack

aws-node-github-check/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Serverless Github Check
2+
Serverless Github Check. This repo is part of the [Serverless November Challengue](https://serverless.com/blog/no-server-november-challenge/)
3+
4+
The idea is to validate that all Pull Requests are related to a specific trello card.
5+
6+
Check rules:
7+
8+
* To pass the check, the Pull Request body should start with: "Related trello card: https://trello.com/"
9+

aws-node-github-check/handler.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { client } from 'octonode'
2+
import { success, failure, githubSuccessPayload, githubFailurePayload } from './libs/response-lib'
3+
import {
4+
isAValidPullRequest, eventIsAPullRequest, updatePullRequestStatus, checkWebhookSecret
5+
} from './libs/github-service'
6+
7+
export async function githubCheck(event, context, callback) {
8+
const githubClient = client(process.env.GITHUB_TOKEN)
9+
checkWebhookSecret(process.env.GITHUB_WEBHOOK_SECRET)
10+
11+
let body = JSON.parse(event.body)
12+
if (!eventIsAPullRequest(body)) return callback(null, success('Event is not a Pull Request'))
13+
const payload = isAValidPullRequest(body) ? githubSuccessPayload() : githubFailurePayload()
14+
try {
15+
await updatePullRequestStatus(githubClient, payload, body.repository, body.pull_request)
16+
callback(null, success(`Process finished with state: ${payload.state}`))
17+
} catch (e) {
18+
callback(null, failure(`Process finished with error`))
19+
}
20+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export function isAValidPullRequest(body) {
2+
if (!body.pull_request.body.startsWith('Related trello card: https://trello.com')) return false
3+
return true
4+
}
5+
6+
export function eventIsAPullRequest(body) {
7+
if (!body || !body.hasOwnProperty('pull_request')) return false
8+
return true
9+
}
10+
11+
export function updatePullRequestStatus(githubClient, payload, repository, pullRequest) {
12+
return new Promise((resolve, reject) => {
13+
githubClient.post(`/repos/${repository.full_name}/statuses/${pullRequest.head.sha}`, payload, {}, (err, _body) => {
14+
if (err) {
15+
reject(err)
16+
} else {
17+
resolve()
18+
}
19+
})
20+
})
21+
}
22+
23+
export function checkWebhookSecret(secret) {
24+
if (typeof secret !== 'string') {
25+
return callback(null, failure('Must provide a \'GITHUB_WEBHOOK_SECRET\' env variable'))
26+
}
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
export function success(body) {
2+
return buildResponse(204, body)
3+
}
4+
5+
export function failure(body) {
6+
return buildResponse(500, body)
7+
}
8+
9+
export function githubSuccessPayload() {
10+
return buildGithubPayload('success', 'PR body according to format')
11+
}
12+
13+
export function githubFailurePayload() {
14+
return buildGithubPayload('failure', 'PR body should start with the related trello card')
15+
}
16+
17+
function buildGithubPayload(state, description) {
18+
return {
19+
state: state,
20+
description: description,
21+
context: 'serverless-webhook/pr-body'
22+
}
23+
}
24+
25+
function buildResponse(statusCode, body) {
26+
return {
27+
statusCode: statusCode,
28+
body: JSON.stringify(body)
29+
}
30+
}

0 commit comments

Comments
 (0)