Skip to content

Commit a073940

Browse files
committed
Initialize repository
0 parents  commit a073940

File tree

10 files changed

+3895
-0
lines changed

10 files changed

+3895
-0
lines changed

.eslintrc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"parserOptions": {
3+
"ecmaVersion": 2017,
4+
},
5+
"plugins": [
6+
"prettier"
7+
],
8+
"rules": {
9+
"prettier/prettier": ["error", {
10+
"singleQuote": true,
11+
"trailingComma": "all",
12+
"bracketSpacing": false,
13+
"jsxBracketSameLine": true
14+
}]
15+
}
16+
}

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
npm-debug.log
3+
*.pem
4+
.env

.travis.yml

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
dist: trusty
2+
sudo: false
3+
language: node_js
4+
node_js: 8.6.0
5+
before_install:
6+
- curl -o- -L https://yarnpkg.com/install.sh | bash -s -- --version 1.2.0
7+
- export PATH=$HOME/.yarn/bin:$PATH
8+
cache:
9+
yarn: true
10+
before_install: yarn global add greenkeeper-lockfile@1
11+
before_script: greenkeeper-lockfile-update
12+
after_script: greenkeeper-lockfile-upload

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Uber Technologies, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# probot-app-migrations
2+
3+
> a GitHub App built with [probot](https://github.com/probot/probot) that enforces the creation of migration guides
4+
5+
## Setup
6+
7+
```
8+
# Install dependencies
9+
npm install
10+
11+
# Run the bot
12+
npm start
13+
```
14+
15+
See [docs/deploy.md](docs/deploy.md) if you would like to run your own instance of this app.

__tests__/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const t = require('assert');
2+
3+
test('dummy test', () => {
4+
t.ok(true, 'dummy assertion passed');
5+
});

docs/deploy.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Deploying
2+
3+
If you would like to run your own instance of this app, see the [docs for deployment](https://probot.github.io/docs/deployment/).
4+
5+
This app requires these **Permissions & events** for the GitHub App:
6+
7+
> **TODO**: List permissions required for deployment here. See [probot/stale](https://github.com/probot/stale/blob/master/docs/deploy.md) for an example.

index.js

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
const {join, dirname, basename, sep} = require('path');
2+
3+
const statuses = {
4+
passing: {
5+
state: 'success',
6+
description: 'Migration guide provided',
7+
},
8+
failing: {
9+
state: 'failure',
10+
description: 'PRs with breaking changes must provide a migration guide',
11+
// target_url: 'https://github.com/',
12+
},
13+
};
14+
15+
module.exports = robot => {
16+
robot.on('pull_request.opened', check);
17+
robot.on('pull_request.edited', check);
18+
robot.on('pull_request.synchronize', check);
19+
robot.on('pull_request.updated', check);
20+
robot.on('pull_request.labeled', check);
21+
robot.on('pull_request.unlabeled', check);
22+
23+
async function check(context) {
24+
const pr = context.payload.pull_request;
25+
26+
function setStatus(status) {
27+
const params = Object.assign(
28+
{
29+
sha: pr.head.sha,
30+
context: 'migration',
31+
},
32+
status,
33+
);
34+
return github.repos.createStatus(context.repo(params));
35+
}
36+
37+
const filename = `${pr.number.toString().padStart(5, '0')}.md`;
38+
39+
const labels = await context.github.issues.getIssueLabels(
40+
context.repo({number: pr.number}),
41+
);
42+
43+
const isBreaking = labels.data.reduce((breaking, label) => {
44+
return breaking || label.name === 'breaking';
45+
}, false);
46+
47+
if (isBreaking) {
48+
const compare = await context.github.repos.compareCommits(
49+
context.repo({
50+
base: pr.base.sha,
51+
head: pr.head.sha,
52+
}),
53+
);
54+
55+
const packages = [''];
56+
57+
compare.data.files.forEach(file => {
58+
const subpackage = inSubPackage(file.filename);
59+
if (subpackage) {
60+
packages.push(subpackage);
61+
}
62+
});
63+
64+
Promise.all(
65+
packages.map(async pkg => {
66+
try {
67+
const res = await context.github.repos.getContent(
68+
context.repo({
69+
path: join(pkg, 'docs/migrations'),
70+
ref: pr.head.sha,
71+
}),
72+
);
73+
const files = res.data.map(file => file.path);
74+
return files;
75+
} catch (err) {
76+
if (err.code !== 404) {
77+
throw err;
78+
}
79+
return [];
80+
}
81+
}),
82+
).then(res => {
83+
/**
84+
* At least one package needs to have a migration guide
85+
*/
86+
const didPass = res.reduce((outer, files) => {
87+
return files.reduce((inner, filepath) => {
88+
return inner || basename(filepath) === filename;
89+
}, outer);
90+
}, false);
91+
setStatus(didPass ? statuses.passing : statuses.failing);
92+
});
93+
} else {
94+
setStatus(statuses.passing);
95+
}
96+
}
97+
};
98+
99+
function inSubPackage(filepath) {
100+
const dirs = dirname(filepath).split(sep);
101+
if (dirs.length < 2) {
102+
return false;
103+
}
104+
if (dirs[0] !== 'packages') {
105+
return false;
106+
}
107+
return join(dirs[0], dirs[1]);
108+
}

package.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "probot-app-migrations",
3+
"version": "1.0.0",
4+
"description": "GitHub App that that enforces the creation of migration guides",
5+
"author": "Ryan Tsao <[email protected]>",
6+
"contributors": [],
7+
"repository": "https://github.com/uber-web/probot-app-migrations.git",
8+
"scripts": {
9+
"start": "probot run ./index.js",
10+
"test": "npm run lint && jest",
11+
"lint": "eslint .",
12+
"fix": "eslint . --fix"
13+
},
14+
"dependencies": {
15+
"probot": "^0.11.0"
16+
},
17+
"devDependencies": {
18+
"eslint": "^4.8.0",
19+
"eslint-plugin-prettier": "^2.3.1",
20+
"jest": "^21.2.1",
21+
"localtunnel": "^1.8.3",
22+
"prettier": "^1.7.4"
23+
},
24+
"engines": {
25+
"node": ">= 8.6.0"
26+
},
27+
"license": "MIT"
28+
}

0 commit comments

Comments
 (0)