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