Skip to content

Commit

Permalink
Merge pull request #158 from wallabag/feature/weblate-label
Browse files Browse the repository at this point in the history
Add Weblate automatic label
  • Loading branch information
j0k3r authored Jul 8, 2020
2 parents 19f905d + 2e26065 commit 562e087
Show file tree
Hide file tree
Showing 8 changed files with 682 additions and 425 deletions.
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# Serverless SiteConfig GitHub Check
# wallabag Serverless Bot

[![serverless](http://public.serverless.com/badges/v3.svg)](https://serverless.com/)
[![Build Status](https://travis-ci.org/wallabag/serverless-site-config-github-check.svg?branch=master)](https://travis-ci.org/wallabag/serverless-site-config-github-check)
[![Build Status](https://travis-ci.org/wallabag/serverless-bot.svg?branch=master)](https://travis-ci.org/wallabag/serverless-bot)

This serverless project validates PRs sent to site-config repository: [fivefilters](https://github.com/fivefilters/ftr-site-config) & [graby](https://github.com/j0k3r/graby-site-config).
This serverless project does some stuff to help the wallabag team. It:

- validates PRs sent to site-config repository: [fivefilters](https://github.com/fivefilters/ftr-site-config) & [graby](https://github.com/j0k3r/graby-site-config)
- automatically label PRs created by Weblate
- more to come!

![image](https://user-images.githubusercontent.com/62333/50344781-c0a13100-052c-11e9-9f6b-3a7cb4393262.png)

Expand All @@ -12,6 +16,7 @@ This serverless project validates PRs sent to site-config repository: [fivefilte
Available lambdas:

- **extension**: It validates each file in the diff has a `.txt` extension.
- **weblate**: It automatically label PRs created by Weblate.

## Prerequisites

Expand All @@ -37,7 +42,7 @@ By default

Configure the webhook in [the GitHub repository settings](https://developer.github.com/webhooks/creating/#setting-up-a-webhook).

- In the Payload URL, enter the URL you received after deploying. It would be something like `https://<your_url>.amazonaws.com/dev/webhook`.
- In the Payload URL, enter the URL you received after deploying. It would be something like `https://<your_url>.amazonaws.com/dev/webhook/...`.
- Choose the "application/json" in Content type.
- In the types of events to trigger the webhook, select "Let me select individual events", then select at least `Pull Requests`.

Expand Down
60 changes: 60 additions & 0 deletions functions/weblate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { client } from 'octonode'
import { validateWebhook } from './utils/github'

export async function weblate(event, context, callback) {
const githubClient = client(process.env.GITHUB_TOKEN)

const body = JSON.parse(event.body)

// when creating the webhook
if (body && ('hook' in body)) {
let response

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))) {
return callback(null, {
statusCode: 500,
body: 'Event is not a Pull Request',
})
}

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',
})
}

await githubClient
.issue(body.repository.full_name, body.pull_request.number)
.addLabelsAsync(['Translations'])

console.log('Labelled!')

return callback(null, {
statusCode: 204,
body: 'Process finished',
})
}
2 changes: 2 additions & 0 deletions handler.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { checkExtension } from './functions/extension'
import { weblate } from './functions/weblate'

export {
checkExtension,
weblate,
}
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "serverless-site-config-github-check",
"name": "wallabag-serverless-bot",
"main": "handler.js",
"scripts": {
"test": "jest",
Expand All @@ -9,7 +9,6 @@
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.10.4",
"@babel/plugin-proposal-class-properties": "^7.10.1",
"@babel/preset-env": "^7.10.4",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.1.0",
Expand Down
12 changes: 11 additions & 1 deletion serverless.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
frameworkVersion: ">=1.54.0 <2.0.0"

service: serverless-site-config-github-check
service: wallabag-serverless-bot

plugins:
- serverless-webpack
Expand Down Expand Up @@ -33,3 +33,13 @@ functions:
path: webhook/extension
method: post
cors: true

weblate:
handler: handler.weblate
description: Auto label a PR create by Weblate
events:
-
http:
path: webhook/weblate
method: post
cors: true
15 changes: 0 additions & 15 deletions tests/extension.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,6 @@ describe('Validating GitHub event', () => {

describe('Validating extension', () => {
test('fail to retrieve the diff', async () => {
client.mockReturnValue({
repo: jest.fn((params) => {
expect(params).toBe('foo/bar')

return {
statusAsync: jest.fn((commit, payload) => {
expect(commit).toBe('ee55a1223ce20c3e7cb776349cb7f8efb7b88511')
expect(payload.state).toBe('failure')
expect(payload.context).toBe('Site config - File extension check')
expect(payload.description).toEqual(expect.stringContaining('has not a txt extension'))
}),
}
}),
})

nock('http://git.hub')
.get('/diff')
.reply(404)
Expand Down
181 changes: 181 additions & 0 deletions tests/weblate.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import { client } from 'octonode'
import { weblate } from '../functions/weblate'

jest.mock('octonode')

describe('Validating GitHub event', () => {
test('bad event body', async () => {
const callback = jest.fn()

await weblate({ body: '{}' }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'Event is not a Pull Request',
statusCode: 500,
})
})

test('hook event does not include PR', async () => {
const callback = jest.fn()
const githubEvent = {
zen: 'Speak like a human.',
hook_id: 1,
hook: {
events: [
'issue',
'push',
],
},
repository: {
full_name: '20minutes/serverless-github-check',
},
sender: {
login: 'diego',
},
}

await weblate({ body: JSON.stringify(githubEvent) }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'This webhook needs the "pull_request" event. Please tick it.',
statusCode: 500,
})
})

test('hook event is ok', async () => {
const callback = jest.fn()
const githubEvent = {
zen: 'Speak like a human.',
hook_id: 1,
hook: {
events: [
'pull_request',
'push',
],
},
repository: {
full_name: '20minutes/serverless-github-check',
},
sender: {
login: 'diego',
},
}

await weblate({ body: JSON.stringify(githubEvent) }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'Hello diego, the webhook is now enabled for 20minutes/serverless-github-check, enjoy!',
statusCode: 200,
})
})

test('hook event for an organization is ok', async () => {
const callback = jest.fn()
const githubEvent = {
zen: 'Speak like a human.',
hook_id: 1,
hook: {
events: [
'pull_request',
'push',
],
},
organization: {
login: '20minutes',
},
sender: {
login: 'diego',
},
}

await weblate({ body: JSON.stringify(githubEvent) }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'Hello diego, the webhook is now enabled for the organization 20minutes, enjoy!',
statusCode: 200,
})
})
})

describe('Apply label', () => {
test('PR is NOT ok', async () => {
client.mockReturnValue({
issue: jest.fn((fullName, number) => {
expect(fullName).toBe('foo/bar')
expect(number).toBe(42)

return {
addLabelsAsync: jest.fn((labels) => {
expect(labels[0]).toBe('Translations')
}),
}
}),
})

const callback = jest.fn()
const githubEvent = {
pull_request: {
user: {
login: 'j0k3r',
},
number: 42,
},
repository: {
full_name: 'foo/bar',
},
sender: {
login: 'j0k3r',
},
}

await weblate({ body: JSON.stringify(githubEvent) }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'PR is not from Weblate',
statusCode: 204,
})
})
test('PR is ok', async () => {
client.mockReturnValue({
issue: jest.fn((fullName, number) => {
expect(fullName).toBe('foo/bar')
expect(number).toBe(42)

return {
addLabelsAsync: jest.fn((labels) => {
expect(labels[0]).toBe('Translations')
}),
}
}),
})

const callback = jest.fn()
const githubEvent = {
pull_request: {
user: {
login: 'weblate',
},
number: 42,
},
repository: {
full_name: 'foo/bar',
},
sender: {
login: 'weblate',
},
}

await weblate({ body: JSON.stringify(githubEvent) }, {}, callback)

expect(callback).toHaveBeenCalledTimes(1)
expect(callback).toHaveBeenCalledWith(null, {
body: 'Process finished',
statusCode: 204,
})
})
})
Loading

0 comments on commit 562e087

Please sign in to comment.