@@ -6,11 +6,73 @@ const ms = require('ms')
6
6
const { getId, executeAction } = require ( '../util' )
7
7
const getConfig = require ( '../config' )
8
8
const { COMMENT , CLOSE } = require ( '../constants' )
9
- const { timeToNumber, getLabelConfig, labelToAction } = require ( './util' )
9
+ const {
10
+ timeToNumber,
11
+ getLabelConfig,
12
+ getEffectiveLabel,
13
+ labelToAction,
14
+ labelsByAction,
15
+ } = require ( './util' )
10
16
const analytics = require ( '../analytics' )
11
17
const { closeIssue } = require ( '../api' )
12
18
13
- module . exports = ( queue ) => async ( context ) => {
19
+ module . exports . close = ( queue ) => async ( context ) => {
20
+ const thread = context . payload . pull_request || context . payload . issue
21
+
22
+ if ( thread . state === 'closed' ) {
23
+ return
24
+ }
25
+
26
+ const ID = getId ( context , { action : CLOSE } )
27
+
28
+ const config = await getConfig ( context )
29
+
30
+ const withClosableLabels = thread . labels . filter ( labelsByAction ( config , CLOSE ) )
31
+
32
+ if ( withClosableLabels . length ) {
33
+ const { label, time } = getEffectiveLabel ( config , withClosableLabels )
34
+
35
+ const jobExists = await queue . getJob ( ID )
36
+ if ( ! jobExists ) {
37
+ const { comment } = getLabelConfig ( config , label . name , CLOSE )
38
+
39
+ if ( comment && comment . trim ( ) !== 'false' ) {
40
+ const body = comment
41
+ . replace ( '$DELAY' , time == null ? '' : ms ( time , { long : true } ) )
42
+ . replace ( '$LABEL' , label . name )
43
+ . replace ( '$AUTHOR' , thread . user . login )
44
+ context . octokit . issues . createComment ( context . issue ( { body } ) )
45
+ }
46
+ }
47
+
48
+ if ( time >= 0 ) {
49
+ return queue
50
+ . createJob ( {
51
+ ...context . issue ( { installation_id : context . payload . installation . id } ) ,
52
+ action : CLOSE ,
53
+ } )
54
+ . setId ( ID )
55
+ . delayUntil ( Date . now ( ) + time )
56
+ . save ( )
57
+ . then ( ( job ) => {
58
+ analytics . track ( ( ) => ( {
59
+ userId : context . payload . installation . id ,
60
+ event : `Close job created` ,
61
+ properties : {
62
+ ...job . data ,
63
+ id : job . id ,
64
+ } ,
65
+ } ) )
66
+ return job
67
+ } )
68
+ }
69
+ }
70
+
71
+ // If closable labels are removed, delete job for this issue
72
+ return queue . removeJob ( ID )
73
+ }
74
+
75
+ module . exports . comment = ( queue ) => async ( context ) => {
14
76
const thread = context . payload . pull_request || context . payload . issue
15
77
16
78
const config = await getConfig ( context )
0 commit comments