@@ -20,13 +20,14 @@ import { DataChangeTimingManager } from './util/DataChangeTimingManager.js';
2020
2121import githubContributionsService from "./services/github/github-contributions.js" ;
2222import discourseService from "./services/discourse/discourse.js" ;
23- import githubTestContributionsService , { USER_TEST_RESULT_REGEX } from "./services/github/github-test-contributions.js" ;
23+ import githubTestContributionsService from "./services/github/github-test-contributions.js" ;
2424import gitHubMilestonesService from './services/github/github-milestones.js' ;
2525
2626import { testUserTestComment } from './keymanapp-test-bot/test-user-test-results-comment.js' ;
2727import { performanceLog } from './performance-log.js' ;
2828import { consoleLog } from './util/console-log.js' ;
2929import { buildVersion } from '../shared/version.js' ;
30+ import { processGithubWebhookEvent } from './webhooks/github-webhook.js' ;
3031
3132sms . install ( ) ;
3233
@@ -95,7 +96,7 @@ if(debugTestBot) {
9596const port = 80 ;
9697const REFRESH_INTERVAL = environment == Environment . Development ? 180000 : 60000 ;
9798
98- const timingManager = new DataChangeTimingManager ( ) ;
99+ export const timingManager = new DataChangeTimingManager ( ) ;
99100
100101/* Logging all requests and responses */
101102
@@ -216,7 +217,7 @@ wsServer.on('connection', socket => {
216217 sendInitialRefreshMessages ( socket ) ;
217218} ) ;
218219
219- function reportError ( error ) {
220+ export function reportError ( error ) {
220221 console . error ( error ) ;
221222 Sentry . captureMessage ( error ) ;
222223}
@@ -227,84 +228,6 @@ function respondKeymanDataChange() {
227228 . catch ( error => reportError ( error ) ) ;
228229}
229230
230- async function respondGitHubDataChange ( request : express . Request ) {
231- // For now, removing this so that we get all refreshes -- check_run and
232- // check_suite are busy but only do anything significant if they reference a
233- // specific PR, so majority of those events should have no real impact. The
234- // problem here is that we lose the individual refreshes as they are coalesced
235- // by timingManager, but we need them to keep issues and PRs in sync, so a
236- // redesign is needed.
237- //
238- // if(timingManager.isTooSoon('github', GitHubRefreshRate, () => respondGitHubDataChange(request))) {
239- // return;
240- // }
241-
242- timingManager . start ( 'github' ) ;
243- try {
244- const event = request ?. headers ?. [ 'x-github-event' ] ;
245- const issueNumber = request ?. body ?. issue ?. number ;
246- const pullNumber = request ?. body ?. pull_request ?. number ;
247- const repo = request ?. body ?. repository ?. name ;
248- const action = request ?. body ?. action ;
249-
250- if ( ( event == 'issues' || event == 'issue_comment' ) && ! request ?. body ?. issue ?. pull_request ) {
251- consoleLog ( 'main' , 'github' , `POST webhook ${ event } .${ action } : keymanapp/${ repo } #${ issueNumber } ` ) ;
252- try {
253- if ( await statusData . refreshGitHubIssueData ( repo , issueNumber ) ) {
254- sendWsAlert ( true , 'github-issues' ) ;
255-
256- await respondGitHubContributionsDataChange (
257- { issue :true , post :false , pull :false , review :false , test :false }
258- ) ;
259- }
260- } catch ( error ) {
261- reportError ( error ) ;
262- }
263- /* } else if(event == 'check_run') {
264- // TODO: only refresh data related to check runs?
265- const prNumbers = request.body?.check_suite?.pull_requests?.map(pr => pr.number) ?? [];
266- } else if(event == 'check_suite') {
267- // TODO: only refresh data related to check suites?
268- const prNumbers = request.body?.check_suite?.pull_requests?.map(pr => pr.number) ?? [];
269- } else if(event == 'pull_request') {
270- // TODO: only refresh data related to pull requests
271- const prNumber = request.body?.pull_request?.number;
272- */
273- } else {
274- try {
275- const prNumbers : { hasBeenClosed : boolean , repo : string , pullNumber : number } [ ] = [ ] ;
276- if ( issueNumber && repo && request ?. body ?. issue ?. pull_request ) {
277- prNumbers . push ( { hasBeenClosed : false , repo, pullNumber : issueNumber } ) ;
278- } else if ( pullNumber && repo ) {
279- prNumbers . push ( { hasBeenClosed : request . body . action == 'closed' , repo, pullNumber} ) ;
280- } else if ( event == 'check_suite' ) {
281- prNumbers . push ( ...request . body ?. check_suite ?. pull_requests ?. map ( pr => ( { hasBeenClosed : false , repo : pr . base . repo . name , pullNumber : pr . number } ) ) ?? [ ] ) ;
282- } else if ( event == 'check_run' ) {
283- prNumbers . push ( ...request . body ?. check_run ?. check_suite ?. pull_requests ?. map ( pr => ( { hasBeenClosed : false , repo : pr . base . repo . name , pullNumber : pr . number } ) ) ?? [ ] ) ;
284- }
285-
286- consoleLog ( 'main' , 'github' , `POST webhook ${ event } .${ action } : ${ prNumbers . map ( p => `keymanapp/${ p . repo } #${ p . pullNumber } ` ) . join ( ',' ) } ` ) ;
287-
288- if ( await statusData . refreshGitHubPullRequestsData ( prNumbers ) ) {
289- sendWsAlert ( true , 'github' ) ; // TODO: later just refresh prs
290-
291- if ( event != 'check_run' && event != 'check_suite' ) {
292- // We'll only refresh contribution data if the event type merits it -- checks do not impact contributions
293- const isUserTestComment =
294- event == 'issue_comment' &&
295- ( request ?. body ?. comment ?. body ?? '' ) . match ( USER_TEST_RESULT_REGEX ) ;
296- await respondGitHubContributionsDataChange ( { issue :event == 'issues' , post :false , pull :event == 'pull_request' , review :event == 'pull_request' || event == 'pull_request_review' , test :isUserTestComment } ) ;
297- }
298- }
299- } catch ( error ) {
300- reportError ( error ) ;
301- }
302- }
303- } finally {
304- timingManager . finish ( 'github' ) ;
305- }
306- }
307-
308231function respondCodeOwnersDataChange ( ) {
309232 return statusData . refreshCodeOwnersData ( )
310233 . then ( hasChanged => sendWsAlert ( hasChanged , 'code-owners' ) )
@@ -317,7 +240,7 @@ function respondSiteLivelinessDataChange() {
317240 . catch ( error => reportError ( error ) ) ;
318241}
319242
320- function respondGitHubContributionsDataChange ( contributionChanges : ContributionChanges ) {
243+ export function respondGitHubContributionsDataChange ( contributionChanges : ContributionChanges ) {
321244 return statusData . refreshGitHubContributionsData ( 'current' , contributionChanges )
322245 . then ( hasChanged => sendWsAlert ( hasChanged , 'github-contributions' ) )
323246 . catch ( error => reportError ( error ) ) ;
@@ -395,10 +318,11 @@ app.use('/', express.static((environment == Environment.Development ? '' : '../'
395318
396319/* Web hooks */
397320
398- app . post ( '/webhook/github' , ( request : express . Request , response ) => {
321+ app . post ( '/webhook/github' , ( request : express . Request , response : express . Response ) => {
399322 ( async ( ) => {
400- respondGitHubDataChange ( request ) ;
401- slackLGTM ( request . body ) ;
323+ if ( await processGithubWebhookEvent ( request , response ) ) {
324+ slackLGTM ( request . body ) ;
325+ }
402326 } ) ( ) ;
403327 response . send ( 'ok' ) ;
404328} ) ;
@@ -435,7 +359,7 @@ app.post('/webhook/discourse', (request, response) => {
435359
436360app . use ( '/webhook/keymanapp-test-bot' , keymanAppTestBotMiddleware ) ;
437361
438- function sendWsAlert ( hasChanged : boolean , message : string ) : boolean {
362+ export function sendWsAlert ( hasChanged : boolean , message : string ) : boolean {
439363 if ( hasChanged ) {
440364 wsServer . clients . forEach ( ( client ) => {
441365 if ( client . readyState === ws . OPEN ) {
0 commit comments