@@ -18,16 +18,28 @@ export async function getIssues(labels: string[], token: string) {
1818 } ) ;
1919}
2020
21+ // Issue processing steps
22+ // Step 1: Skip closed/merged/locked
23+ // Step 2: If the issue is a PR, use the PR configuration, else use the issue configuration
24+ // Step 3: Iterate all labels in the issue. If labeled, iterate over the configured labels and see if the issue's labels
25+ // match the configured ones.
26+ // Step 4: If they do, take the action specified in the configuration line, and repeat for all configuration lines
27+ // Step 5: Do step 4 but for the updateRemoveLabels
2128export async function processIssues ( issues : Issue [ ] , args : args ) {
2229 issues . forEach ( async issue => {
30+ // Skip closed and locked issues
31+ if ( issue . state === 'closed' || issue . state === 'merged' || issue . locked ) return ;
32+
2333 const timeline = await getIssueLabelTimeline ( issue . number , args . token ) ;
34+ const expirationLabelMap = isPr ( issue ) ? args . prExpirationLabelMap : args . expirationLabelMap ;
35+ const removeLabelMap = isPr ( issue ) ? args . prUpdateRemoveLabels : args . updateRemoveLabels ;
2436 // Enumerate labels in issue and check if each matches our action list
2537 issue . labels . forEach ( label => {
2638 const issueLabel = typeof label === 'string' ? label : label . name ;
2739 if ( issueLabel ) {
28- if ( args . expirationLabelMap ) {
40+ if ( expirationLabelMap ) {
2941 // These are labels that we apply if an issue hasn't been updated in a specified timeframe
30- args . expirationLabelMap . forEach ( async lam => {
42+ expirationLabelMap . forEach ( async lam => {
3143 const sourceLabelList = lam . split ( ':' ) [ 0 ] . split ( ',' ) ;
3244 const configuredAction = lam . split ( ':' ) [ 1 ] ;
3345 const configuredTime = parseInt ( lam . split ( ':' ) [ 2 ] ) ;
@@ -36,25 +48,25 @@ export async function processIssues(issues: Issue[], args: args) {
3648 // Issue contains label specified and configured time has elapsed
3749 switch ( configuredAction ) {
3850 case 'add' :
39- await addLabelToIssue ( issue . number , lam . split ( ':' ) [ 3 ] ) ;
51+ await addLabelToIssue ( issue . number , lam . split ( ':' ) [ 3 ] , args . token ) ;
4052 break ;
4153 case 'remove' :
42- await removeLabelFromIssue ( issue . number , lam . split ( ':' ) [ 3 ] ) ;
54+ await removeLabelFromIssue ( issue . number , lam . split ( ':' ) [ 3 ] , args . token ) ;
4355 break ;
4456 case 'close' :
45- await closeIssue ( issue . number ) ;
57+ await closeIssue ( issue . number , args . token ) ;
4658 break ;
4759 default :
4860 core . error ( `Unknown action ${ configuredAction } for issue #${ issue . number } , doing nothing` ) ;
4961 }
5062 }
5163 } ) ;
5264 }
53- if ( args . updateRemoveLabels ) {
65+ if ( removeLabelMap ) {
5466 // These are labels that need removed if an issue has been updated after they were applied
55- args . updateRemoveLabels . forEach ( async removeMe => {
67+ removeLabelMap . forEach ( async removeMe => {
5668 if ( Date . parse ( issue . updated_at ) > getIssueLabelDate ( timeline , removeMe ) ) {
57- removeLabelFromIssue ( issue . number , removeMe ) ;
69+ removeLabelFromIssue ( issue . number , removeMe , args . token ) ;
5870 }
5971 } ) ;
6072 }
@@ -74,6 +86,36 @@ async function getIssueLabelTimeline(issueNumber: number, token: string) {
7486 ) . filter ( event => event . event === 'labeled' ) ;
7587}
7688
89+ async function addLabelToIssue ( issue : number , label : string , token : string ) {
90+ const octokit = github . getOctokit ( token ) ;
91+ await octokit . rest . issues . addLabels ( {
92+ owner : github . context . repo . owner ,
93+ repo : github . context . repo . repo ,
94+ issue_number : issue ,
95+ labels : [ label ] ,
96+ } ) ;
97+ }
98+
99+ async function removeLabelFromIssue ( issue : number , label : string , token : string ) {
100+ const octokit = github . getOctokit ( token ) ;
101+ await octokit . rest . issues . removeLabel ( {
102+ owner : github . context . repo . owner ,
103+ repo : github . context . repo . repo ,
104+ issue_number : issue ,
105+ name : label ,
106+ } ) ;
107+ }
108+
109+ async function closeIssue ( issue : number , token : string ) {
110+ const octokit = github . getOctokit ( token ) ;
111+ await octokit . rest . issues . update ( {
112+ owner : github . context . repo . owner ,
113+ repo : github . context . repo . repo ,
114+ issue_number : issue ,
115+ state : 'closed' ,
116+ } ) ;
117+ }
118+
77119function getIssueLabelDate ( timeline : Timeline , label : string ) {
78120 // Return when the label was last applied
79121 return timeline . reduce ( ( p , c ) => {
@@ -94,3 +136,7 @@ function issueDateCompare(issueDate: string, configuredDays: number) {
94136 d . setDate ( d . getDate ( ) + configuredDays ) ;
95137 return d . valueOf ( ) < Date . now ( ) ;
96138}
139+
140+ function isPr ( issue : Issue ) {
141+ return ! ! issue . pull_request ;
142+ }
0 commit comments