This repository has been archived by the owner on Mar 19, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
143 lines (114 loc) Β· 3.96 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
const scheduler = require('node-schedule'),
yaml = require('js-yaml');
const defaultConfig = { cron: '* * * * * 7' },
POSITIVE_REACTIONS = ['+1'],
NEGATIVE_REACTIONS = ['-1'];
let repositories = [];
async function getConfig (repository, authenticator) {
let config = null,
api = await authenticator();
try {
let configFile = await api.repos.getContent({
repo: repository.name,
owner: repository.owner.login,
path: '.github/scheduled-merge.yml'
});
if (configFile) {
let content = Buffer.from(configFile.data.content, 'base64');
config = yaml.safeLoad(content.toString());
}
} catch (error) {
if (error.code != 404) {
throw error;
}
}
return config || defaultConfig;
}
async function addRepository (repository, authenticator) {
let config = await getConfig(repository, authenticator),
schedule = scheduler.scheduleJob(config.cron, () => executeSchedule(repository, authenticator));
repositories.push({ repository, schedule });
}
function removeRepository (repository) {
let index = repositories.findIndex(r => r.repository.id === repository.id);
if (index > -1) {
repositories[index].schedule.cancel();
repositories.splice(index, 1);
}
}
async function executeSchedule (repository, authenticator) {
console.log(`[${new Date()}] Running on ${repository.name}...`);
let api = await authenticator(),
pullRequests = await api.pullRequests.getAll({
repo: repository.name,
owner: repository.owner.login,
state: 'open'
});
if (pullRequests.data && pullRequests.data.length > 0) {
let scores = [];
for (let pullRequest of pullRequests.data) {
let reactions = await api.reactions.getForIssue({
repo: repository.name,
owner: repository.owner.login,
number: pullRequest.number
});
let score = reactions.data.reduce((total, reaction) => {
if (POSITIVE_REACTIONS.includes(reaction.content)) {
return total + 1;
} else if (NEGATIVE_REACTIONS.includes(reaction.content)) {
return total - 1;
}
return total;
}, 0);
for (let reaction of reactions.data) {
await api.reactions.delete({
reaction_id: reaction.id,
headers: {
accept: 'application/vnd.github.squirrel-girl-preview+json'
}
});
}
scores.push({ pullRequest, score });
};
scores.sort((a, b) => a.score - b.score);
console.log(`[${new Date()}]\tSorted pull requests to : `, scores.map(p => ({ id: p.pullRequest.id, score: p.score })));
let pullRequestToMerge = scores.pop().pullRequest;
console.log(`[${new Date()}]\tMerging PR #${pullRequestToMerge.number}...`);
await api.pullRequests.merge({
repo: repository.name,
owner: repository.owner.login,
number: pullRequestToMerge.number
});
for (let score of scores) {
console.log(`[${new Date()}]\tClosing PR #${score.pullRequest.number}...`);
await api.pullRequests.update({
repo: repository.name,
owner: repository.owner.login,
number: score.pullRequest.number,
state: 'closed'
});
}
}
console.log(`[${new Date()}]\tEnded running on ${repository.name}.`);
}
async function getAuthenticatedAPI (installationId, robot) {
return robot.auth(installationId);
}
module.exports = async robot => {
console.log(`Probot-cron started`);
let github = await robot.auth();
console.log(`Adding 'installation' hook...`);
robot.on('installation.created', context => {
context.payload.repositories.forEach(repository => addRepository(repository, () => getAuthenticatedAPI(context.installation.id, robot)));
});
robot.on('installation.deleted', context => {
context.payload.repositories.forEach(repository => removeRepository(repository));
});
console.log(`Rescheduling on older installations...`);
let { data } = await github.apps.getInstallations();
data.forEach(async ({ id }) => {
let installation = await robot.auth(id),
{ data } = await installation.apps.getInstallationRepositories();
data.repositories.forEach(repository => addRepository(repository, () => getAuthenticatedAPI(id, robot)));
});
}