-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Because of recent changes from the Octokit library (relying on Node internal fetch), we can't use `nock` anymore during tests. We must now pass a custom `fetch` to the Octokit class to mock request. To do that, we can no longer only use `handler` with all the code inside it, but use classes. It's also more clean :)
- Loading branch information
Showing
10 changed files
with
926 additions
and
1,057 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import got from 'got' | ||
import parse from 'diffparser' | ||
import { Handler } from './Handler' | ||
|
||
export class ExtensionHandler extends Handler { | ||
constructor(githubToken, namespace, fetch = null) { | ||
super(githubToken, fetch) | ||
|
||
this.namespace = namespace | ||
} | ||
|
||
async handle(body, callback) { | ||
let response = this.validateEvent(body) | ||
|
||
if (response !== true) { | ||
return callback(null, response) | ||
} | ||
|
||
console.log(`Working on repo ${body.repository.full_name} for PR #${body.pull_request.number}`) | ||
|
||
const payload = { | ||
success: { | ||
state: 'success', | ||
description: 'passed', | ||
context: `${this.namespace} - File extension check`, | ||
}, | ||
failure: { | ||
state: 'failure', | ||
description: 'failed', | ||
context: `${this.namespace} - File extension check`, | ||
}, | ||
} | ||
|
||
let diffResponse | ||
try { | ||
diffResponse = await got(body.pull_request.diff_url) | ||
} catch (e) { | ||
console.log(e.message) | ||
|
||
return callback(null, { | ||
statusCode: 500, | ||
body: e.message, | ||
}) | ||
} | ||
|
||
const validation = parse(diffResponse.body).every((diff) => { | ||
// we don't need to validate deleted file | ||
if (diff.deleted === true) { | ||
return true | ||
} | ||
|
||
if (/\.txt$/.test(diff.to) === false) { | ||
payload.failure.description = `Fail: "${diff.to}" has not a txt extension` | ||
|
||
console.log(`Fail: "${diff.to}" has not a txt extension`) | ||
|
||
return false | ||
} | ||
|
||
return true | ||
}) | ||
|
||
response = await this.updateStatus(body, validation ? payload.success : payload.failure) | ||
|
||
return callback(null, response) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { Octokit } from '@octokit/rest' | ||
|
||
export class Handler { | ||
constructor(githubToken, fetch = null) { | ||
const options = { | ||
auth: githubToken, | ||
} | ||
|
||
if (fetch) { | ||
options.request = { | ||
fetch, | ||
} | ||
} | ||
|
||
this.githubClient = new Octokit(options) | ||
} | ||
|
||
// eslint-disable-next-line class-methods-use-this | ||
validateEvent(body) { | ||
// when creating the webhook | ||
if (body && 'hook' in body) { | ||
try { | ||
if (!body.hook.events.includes('pull_request')) { | ||
throw new Error(`This webhook needs the "${'pull_request'}" event. Please tick it.`) | ||
} | ||
|
||
let message | ||
|
||
if ('organization' in body) { | ||
message = `Hello ${body.sender.login}, the webhook is now enabled for the organization ${body.organization.login}, enjoy!` | ||
} else { | ||
message = `Hello ${body.sender.login}, the webhook is now enabled for ${body.repository.full_name}, enjoy!` | ||
} | ||
|
||
console.log(message) | ||
|
||
return { | ||
statusCode: 200, | ||
body: message, | ||
} | ||
} catch (e) { | ||
console.log(e.message) | ||
|
||
return { | ||
statusCode: 500, | ||
body: e.message, | ||
} | ||
} | ||
} | ||
|
||
if (!(body && 'pull_request' in body)) { | ||
return { | ||
statusCode: 500, | ||
body: 'Event is not a Pull Request', | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
/** | ||
* Update the GitHub PR Status with the given payload | ||
* | ||
* @param object body JSON body from GitHub event | ||
* @param object payload Object to update PR (keys: status, description, context) | ||
* | ||
* @return string reponse | ||
*/ | ||
async updateStatus(body, payload) { | ||
try { | ||
await this.githubClient.rest.repos.createCommitStatus({ | ||
owner: body.repository.owner.login, | ||
repo: body.repository.name, | ||
sha: body.pull_request.head.sha, | ||
...payload, | ||
}) | ||
|
||
return { | ||
statusCode: 204, | ||
body: `Process finished with state: ${payload.state}`, | ||
} | ||
} catch (e) { | ||
console.error(e) | ||
|
||
return { | ||
statusCode: 500, | ||
body: `Process finished with error: ${e.message}`, | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { Handler } from './Handler' | ||
|
||
export class WeblateHandler extends Handler { | ||
async handle(body, callback) { | ||
const response = this.validateEvent(body) | ||
|
||
if (response !== true) { | ||
return callback(null, response) | ||
} | ||
|
||
console.log(`Working on repo ${body.repository.full_name} for PR #${body.pull_request.number}`) | ||
|
||
if (body.pull_request.user.login !== 'weblate' || body.sender.login !== 'weblate') { | ||
return callback(null, { | ||
statusCode: 204, | ||
body: 'PR is not from Weblate', | ||
}) | ||
} | ||
|
||
const owner = body.repository.owner.login | ||
const repo = body.repository.name | ||
|
||
await this.githubClient.request( | ||
`POST /repos/${owner}/${repo}/issues/${body.pull_request.number}/labels`, | ||
{ | ||
labels: ['Translations'], | ||
} | ||
) | ||
|
||
console.log('Labelled!') | ||
|
||
return callback(null, { | ||
statusCode: 204, | ||
body: 'Process finished', | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,93 +1,7 @@ | ||
import got from 'got' | ||
import parse from 'diffparser' | ||
import { Octokit } from '@octokit/rest' | ||
import { updateStatus, validateWebhook } from './utils/github' | ||
import { ExtensionHandler } from './classes/ExtensionHandler' | ||
|
||
export async function handler(event, context, callback) { | ||
let response | ||
const githubClient = new Octokit({ auth: process.env.GITHUB_TOKEN }) | ||
|
||
const body = JSON.parse(event.body) | ||
|
||
// when creating the webhook | ||
if (body && 'hook' in body) { | ||
try { | ||
const message = validateWebhook(body) | ||
|
||
console.log(message) | ||
|
||
response = { | ||
statusCode: 200, | ||
body: message, | ||
} | ||
} catch (e) { | ||
console.log(e.message) | ||
|
||
response = { | ||
statusCode: 500, | ||
body: e.message, | ||
} | ||
} | ||
|
||
return callback(null, response) | ||
} | ||
|
||
if (!(body && 'pull_request' in body)) { | ||
response = { | ||
statusCode: 500, | ||
body: 'Event is not a Pull Request', | ||
} | ||
|
||
return callback(null, response) | ||
} | ||
|
||
console.log(`Working on repo ${body.repository.full_name} for PR #${body.pull_request.number}`) | ||
|
||
const payload = { | ||
success: { | ||
state: 'success', | ||
description: 'passed', | ||
context: `${process.env.NAMESPACE} - File extension check`, | ||
}, | ||
failure: { | ||
state: 'failure', | ||
description: 'failed', | ||
context: `${process.env.NAMESPACE} - File extension check`, | ||
}, | ||
} | ||
const extension = new ExtensionHandler(process.env.GITHUB_TOKEN, process.env.NAMESPACE) | ||
|
||
let diffResponse | ||
try { | ||
diffResponse = await got(body.pull_request.diff_url) | ||
} catch (e) { | ||
console.log(e.message) | ||
|
||
response = { | ||
statusCode: 500, | ||
body: e.message, | ||
} | ||
|
||
return callback(null, response) | ||
} | ||
|
||
const validation = parse(diffResponse.body).every((diff) => { | ||
// we don't need to validate deleted file | ||
if (diff.deleted === true) { | ||
return true | ||
} | ||
|
||
if (/\.txt$/.test(diff.to) === false) { | ||
payload.failure.description = `Fail: "${diff.to}" has not a txt extension` | ||
|
||
console.log(`Fail: "${diff.to}" has not a txt extension`) | ||
|
||
return false | ||
} | ||
|
||
return true | ||
}) | ||
|
||
response = await updateStatus(githubClient, body, validation ? payload.success : payload.failure) | ||
|
||
return callback(null, response) | ||
export async function handler(event, context, callback) { | ||
await extension.handle(JSON.parse(event.body), callback) | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.