2017-02-11 14:27:47 -07:00
import * as EventEmitter from 'events' ;
2017-01-31 08:12:49 -07:00
import * as express from 'express' ;
2018-03-29 05:32:18 -06:00
//const crypto = require('crypto');
import User from '../../../models/user' ;
2018-04-01 22:15:53 -06:00
import config from '../../../config' ;
2018-04-04 07:45:55 -06:00
import { createHttp } from '../../../queue' ;
2017-01-31 08:12:49 -07:00
2017-01-31 08:43:06 -07:00
module . exports = async ( app : express.Application ) = > {
2017-01-31 08:12:49 -07:00
if ( config . github_bot == null ) return ;
2017-01-31 08:43:06 -07:00
const bot = await User . findOne ( {
2018-03-29 22:00:05 -06:00
usernameLower : config.github_bot.username.toLowerCase ( ) ,
host : null
2017-01-31 08:43:06 -07:00
} ) ;
if ( bot == null ) {
console . warn ( ` GitHub hook bot specified, but not found: @ ${ config . github_bot . username } ` ) ;
return ;
}
2018-04-07 11:30:37 -06:00
const post = text = > require ( '../endpoints/notes/create' ) ( { text } , bot ) ;
2017-01-31 08:43:06 -07:00
2017-02-11 14:27:47 -07:00
const handler = new EventEmitter ( ) ;
2017-01-31 08:12:49 -07:00
2017-02-11 14:27:47 -07:00
app . post ( '/hooks/github' , ( req , res , next ) = > {
2017-08-10 07:06:47 -06:00
// req.headers['x-hub-signature'] および
// req.headers['x-github-event'] は常に string ですが、型定義の都合上
// string | string[] になっているので string を明示しています
2018-03-28 10:20:40 -06:00
// if ((new Buffer(req.headers['x-hub-signature'] as string)).equals(new Buffer(`sha1=${crypto.createHmac('sha1', config.github_bot.hook_secret).update(JSON.stringify(req.body)).digest('hex')}`))) {
2017-08-10 07:06:47 -06:00
handler . emit ( req . headers [ 'x-github-event' ] as string , req . body ) ;
2017-02-16 04:08:28 -07:00
res . sendStatus ( 200 ) ;
2018-03-28 10:20:40 -06:00
// } else {
// res.sendStatus(400);
// }
2017-02-11 14:27:47 -07:00
} ) ;
2017-01-31 08:12:49 -07:00
2017-03-17 10:42:43 -06:00
handler . on ( 'status' , event = > {
const state = event . state ;
switch ( state ) {
2017-03-31 05:24:14 -06:00
case 'error' :
2017-03-17 10:42:43 -06:00
case 'failure' :
2017-03-17 10:51:08 -06:00
const commit = event . commit ;
2017-03-17 14:42:07 -06:00
const parent = commit . parents [ 0 ] ;
2018-04-04 07:45:55 -06:00
createHttp ( {
2018-03-31 04:55:00 -06:00
type : 'gitHubFailureReport' ,
2018-03-28 10:20:40 -06:00
userId : bot._id ,
parentUrl : parent.url ,
htmlUrl : commit.html_url ,
message : commit.commit.message ,
} ) . save ( ) ;
2017-03-17 10:42:43 -06:00
break ;
}
} ) ;
2017-01-31 12:25:02 -07:00
handler . on ( 'push' , event = > {
2017-02-11 14:44:16 -07:00
const ref = event . ref ;
2017-03-13 18:37:07 -06:00
switch ( ref ) {
case 'refs/heads/master' :
const pusher = event . pusher ;
const compare = event . compare ;
2017-03-16 09:21:32 -06:00
const commits = event . commits ;
post ( [
2017-03-17 10:22:28 -06:00
` Pushed by ** ${ pusher . name } ** with ?[ ${ commits . length } commit ${ commits . length > 1 ? 's' : '' } ]( ${ compare } ): ` ,
2017-03-17 11:47:55 -06:00
commits . reverse ( ) . map ( commit = > ` ・[?[ ${ commit . id . substr ( 0 , 7 ) } ]( ${ commit . url } )] ${ commit . message . split ( '\n' ) [ 0 ] } ` ) . join ( '\n' ) ,
2017-03-16 09:21:32 -06:00
] . join ( '\n' ) ) ;
2017-03-13 18:37:07 -06:00
break ;
case 'refs/heads/release' :
const commit = event . commits [ 0 ] ;
2017-03-16 09:21:32 -06:00
post ( ` RELEASED: ${ commit . message } ` ) ;
2017-03-13 18:37:07 -06:00
break ;
}
2017-01-31 08:12:49 -07:00
} ) ;
2017-01-31 08:43:06 -07:00
handler . on ( 'issues' , event = > {
2017-02-11 14:44:16 -07:00
const issue = event . issue ;
const action = event . action ;
2017-01-31 08:43:06 -07:00
let title : string ;
2017-01-31 12:07:30 -07:00
switch ( action ) {
2017-03-26 06:34:04 -06:00
case 'opened' : title = 'Issue opened' ; break ;
case 'closed' : title = 'Issue closed' ; break ;
case 'reopened' : title = 'Issue reopened' ; break ;
2017-01-31 09:04:32 -07:00
default : return ;
2017-01-31 08:43:06 -07:00
}
2017-03-13 18:37:07 -06:00
post ( ` ${ title } : < ${ issue . number } >「 ${ issue . title } 」 \ n ${ issue . html_url } ` ) ;
2017-01-31 08:43:06 -07:00
} ) ;
2017-01-31 12:25:02 -07:00
handler . on ( 'issue_comment' , event = > {
2017-02-11 14:44:16 -07:00
const issue = event . issue ;
const comment = event . comment ;
const action = event . action ;
2017-01-31 12:25:02 -07:00
let text : string ;
switch ( action ) {
2017-03-13 18:37:07 -06:00
case 'created' : text = ` Commented to「 ${ issue . title } 」: ${ comment . user . login } 「 ${ comment . body } 」 \ n ${ comment . html_url } ` ; break ;
2017-01-31 12:25:02 -07:00
default : return ;
}
post ( text ) ;
} ) ;
2017-02-16 18:25:23 -07:00
handler . on ( 'watch' , event = > {
2017-02-11 14:44:16 -07:00
const sender = event . sender ;
2017-08-28 11:56:07 -06:00
post ( ` ⭐️ Starred by ** ${ sender . login } ** ⭐️ ` ) ;
2017-02-07 07:52:58 -07:00
} ) ;
2017-01-31 12:25:02 -07:00
handler . on ( 'fork' , event = > {
2017-02-11 14:44:16 -07:00
const repo = event . forkee ;
2017-08-28 11:56:07 -06:00
post ( ` 🍴 Forked: \ n ${ repo . html_url } 🍴 ` ) ;
2017-01-31 12:25:02 -07:00
} ) ;
handler . on ( 'pull_request' , event = > {
2017-02-11 14:44:16 -07:00
const pr = event . pull_request ;
const action = event . action ;
2017-01-31 12:25:02 -07:00
let text : string ;
switch ( action ) {
case 'opened' : text = ` New Pull Request:「 ${ pr . title } 」 \ n ${ pr . html_url } ` ; break ;
case 'reopened' : text = ` Pull Request Reopened:「 ${ pr . title } 」 \ n ${ pr . html_url } ` ; break ;
case 'closed' :
text = pr . merged
? ` Pull Request Merged!:「 ${ pr . title } 」 \ n ${ pr . html_url } `
: ` Pull Request Closed:「 ${ pr . title } 」 \ n ${ pr . html_url } ` ;
break ;
default : return ;
}
post ( text ) ;
} ) ;
2017-01-31 08:12:49 -07:00
} ;