Skip to content

Commit d0bc49c

Browse files
authored
Merge pull request #50 from dscho/add-convenience-scripts
Add two convenience scripts
2 parents 7e9d912 + 8f6735a commit d0bc49c

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

delete-bogus-installations.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
(async () => {
2+
const fs = require('fs')
3+
4+
const localSettings = JSON.parse(fs.readFileSync('local.settings.json'))
5+
process.env.GITHUB_APP_ID = localSettings.Values.GITHUB_APP_ID
6+
process.env.GITHUB_APP_PRIVATE_KEY = localSettings.Values.GITHUB_APP_PRIVATE_KEY
7+
8+
const gitHubRequestAsApp = require('./GitForWindowsHelper/github-api-request-as-app')
9+
const answer = await gitHubRequestAsApp(console, 'GET', '/app/installations?per_page=100')
10+
for (const e of answer.filter(e => e.account.login !== 'git-for-windows' && e.account.login !== 'dscho')) {
11+
console.log(`Deleting installation ${e.id} for ${e.account.login}`)
12+
await gitHubRequestAsApp(console, 'DELETE', `/app/installations/${e.id}`)
13+
}
14+
})().catch(console.log)

get-webhook-event-payload.js

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
(async () => {
2+
const fs = require('fs')
3+
4+
let eventType = undefined
5+
let aroundDate = undefined
6+
7+
// parse arguments, e.g. --event-type=check_run --date='Tue, 21 Nov 2023 11:13:12 GMT'
8+
const args = process.argv.slice(2)
9+
while (args.length) {
10+
let option = args.shift()
11+
12+
const optionWithArgument = option.match(/^(--[^=]+)=(.*)$/)
13+
if (optionWithArgument) {
14+
option = optionWithArgument[1]
15+
args.unshift(optionWithArgument[2])
16+
}
17+
18+
const getArg = () => {
19+
if (!args.length) throw new Error(`'${option} requires an argument!`)
20+
return args.shift()
21+
}
22+
23+
if (option === '--event-type') eventType = getArg()
24+
else if (option === '--date') {
25+
const arg = getArg()
26+
if (isNaN(Date.parse(arg))) throw new Error(`--date requires a valid date (got '${arg}')`)
27+
aroundDate = new Date(arg)
28+
} else
29+
throw new Error(`Unhandled option: '${option}`)
30+
}
31+
32+
const since = aroundDate ? aroundDate.getTime() - 5 * 60 * 1000 : undefined // 5 minutes before
33+
const until = aroundDate ? aroundDate.getTime() + 5 * 60 * 1000 : undefined // 5 minutes after
34+
35+
const localSettings = JSON.parse(fs.readFileSync('local.settings.json'))
36+
process.env.GITHUB_APP_ID = localSettings.Values.GITHUB_APP_ID
37+
process.env.GITHUB_APP_PRIVATE_KEY = localSettings.Values.GITHUB_APP_PRIVATE_KEY
38+
39+
const gitHubRequestAsApp = require('./GitForWindowsHelper/github-api-request-as-app')
40+
41+
const getAtCursor = async cursor => {
42+
const answer = await gitHubRequestAsApp(console, 'GET', `/app/hook/deliveries?per_page=30${cursor ? `&cursor=${cursor}` : ''}`)
43+
answer.forEach(e => {
44+
e.epoch = (new Date(e.delivered_at)).getTime()
45+
})
46+
// sort newest to oldest
47+
answer.sort((a, b) => b.epoch - a.epoch)
48+
const events = answer.filter(e => {
49+
if (eventType && e.event !== eventType) return false
50+
if (since && e.epoch < since) return false
51+
if (until && e.epoch > until) return false
52+
return true
53+
})
54+
const newest = answer.shift()
55+
const oldest = answer.pop() || newest
56+
return {
57+
events, newest, oldest
58+
}
59+
}
60+
61+
const getMatchingEvents = async () => {
62+
let answer = await getAtCursor()
63+
64+
if (!since || !until || answer.newest === answer.oldest) return answer.events
65+
66+
if (answer.oldest.epoch < since) return answer.events
67+
68+
if (answer.oldest.epoch > until) {
69+
let tooNew = answer.oldest
70+
// first find a good starting cursor
71+
while (answer.oldest.epoch > until) {
72+
tooNew = answer.oldest
73+
74+
const rate = (answer.newest.id - answer.oldest.id) / (answer.newest.epoch - answer.oldest.epoch)
75+
let cursor = Math.floor(answer.oldest.id - rate * (answer.oldest.epoch - until))
76+
answer = await getAtCursor(cursor)
77+
}
78+
79+
while (answer.newest.epoch < until) {
80+
const tooOldID = answer.newest.id
81+
// we overshot, now the time window does not include `until`, backtrack via bisecting
82+
const rate = (tooNew.id - answer.newest.id) / (tooNew.epoch - answer.newest.epoch)
83+
let cursor = Math.floor(tooNew.id - rate * (tooNew.epoch - until))
84+
answer = await getAtCursor(cursor)
85+
// if we received events from the same time window, shift back by the same amount
86+
while (tooOldID === answer.newest.id) {
87+
cursor += (cursor - tooOldID)
88+
answer = await getAtCursor(cursor)
89+
}
90+
}
91+
92+
while (answer.oldest.epoch > until) {
93+
// we overshot, maybe again, now even the oldest is too new
94+
answer = await getAtCursor(answer.oldest.id - 1)
95+
}
96+
}
97+
98+
const events = [...answer.events]
99+
while (answer.oldest.epoch > since) {
100+
answer = await getAtCursor(answer.oldest.id - 1)
101+
events.push([...answer.events])
102+
}
103+
104+
return events
105+
}
106+
107+
const events = await getMatchingEvents()
108+
for (const e of events) {
109+
const fullEvent = await gitHubRequestAsApp(console, 'GET', `/app/hook/deliveries/${e.id}`)
110+
console.log(`id: ${e.id}\naction: ${e.action}\nrequest: ${JSON.stringify(fullEvent.request, null, 2)}`)
111+
}
112+
})().catch(console.log)

0 commit comments

Comments
 (0)