forked from npm/statusboard
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrest.js
119 lines (102 loc) · 3.63 KB
/
rest.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
const { Octokit } = require('@octokit/rest')
const { retry } = require('@octokit/plugin-retry')
const { throttling } = require('@octokit/plugin-throttling')
const log = require('proc-log')
const { groupBy, orderBy } = require('lodash')
const config = require('../config')
module.exports = ({ auth }) => {
const REST = new (Octokit.plugin(retry, throttling))({
auth,
log,
retry: {
doNotRetry: [404, 422],
},
request: {
retries: 1,
retryAfter: 5,
},
throttle: {
onRateLimit: (retryAfter, options, octokit) => {
octokit.log.warn(
`Request quota exhausted for request ${options.method} ${options.url}`
)
if (options.request.retryCount === 0) {
// only retries once
octokit.log.info(`Retrying after ${retryAfter} seconds!`)
return true
}
},
onSecondaryRateLimit: (__, options, octokit) => {
octokit.log.warn(
`SecondaryRateLimit detected for request ${options.method} ${options.url}`
)
},
},
})
const getRepo = (owner, repo) => {
log.verbose(`rest:repo:get`, `${owner}/${repo}`)
return REST.repos.get({ owner, repo }).then(d => d.data)
}
const getCommit = async (owner, name, p) => {
log.verbose(`rest:repo:commit`, `${owner}/${name}${p ? `/${p}` : ''}`)
return REST.repos.listCommits({
owner,
repo: name,
path: p,
per_page: 1,
}).then((r) => r.data[0])
}
const getStatus = async (owner, name, ref) => {
log.verbose(`rest:repo:status`, `${owner}/${name}#${ref}`)
const allCheckRuns = await REST.paginate(REST.checks.listForRef, {
owner,
repo: name,
ref,
// since we are paginating through all checks for the ref, you might
// think we should make per_page=100 since that is the max, but that
// makes it very flaky and prone to 500 for npm/cli. its safer (but slower)
// to make more but smaller requests
per_page: 30,
})
// For some of our repos that don't get very many commits, we still run
// a lot of scheduled actions against them. This reduces a status to the
// latest check for each run name (eg, 'test (12.13.0, windows-latest, cmd)')
const runsByName = groupBy(allCheckRuns, 'name')
const checkRuns = Object.entries(runsByName).reduce((acc, [checkName, runs]) => {
if (config.checkRunFilter(checkName, runs)) {
const [latestRun] = orderBy(runs, 'completed_at', 'desc')
acc.push(latestRun)
}
return acc
}, [])
log.verbose(`rest:repo:status:names`, checkRuns.map(c => c.name).join('\n'))
const failures = ['action_required', 'cancelled', 'failure', 'stale', 'timed_out', null]
const statuses = { neutral: false, success: false, skipped: false }
for (const checkRun of checkRuns) {
// return early for any failures
if (failures.includes(checkRun.conclusion)) {
return { url: checkRun.html_url, conclusion: 'failure' }
}
statuses[checkRun.conclusion] = true
}
// Skipped or neutral and no successes is neutral
if ((statuses.neutral || statuses.skipped) && !statuses.success) {
return { conclusion: 'neutral' }
}
// otherwise allow some neutral/skipped as long as there
// are other successful runs
return { conclusion: 'success' }
}
const getAllIssuesAndPullRequests = (owner, name, query = '') => {
log.verbose('rest:issues:getAll', `${owner}/${name}`)
return REST.paginate(REST.search.issuesAndPullRequests, {
q: `repo:${owner}/${name}+${query}`,
})
}
return {
getRepo,
getCommit,
getStatus,
getAllIssuesAndPullRequests,
}
}