1
1
import * as core from '@actions/core' ;
2
- import { context , getOctokit } from '@actions/github' ;
2
+ import { context , getOctokit } from '@actions/github' ;
3
+
4
+ const RELEASE_COMMENT_HEADING = '## A PR closing this issue has just been released 🚀' ;
3
5
4
6
async function run ( ) {
5
7
const { getInput } = core ;
6
8
7
9
const githubToken = getInput ( 'github_token' ) ;
8
- const version = getInput ( 'version' ) ;
10
+ const version = getInput ( 'version' ) ;
9
11
10
12
if ( ! githubToken || ! version ) {
11
13
core . debug ( 'Skipping because github_token or version are empty.' ) ;
12
14
return ;
13
15
}
14
16
15
- const { owner, repo} = context . repo ;
17
+ const { owner, repo } = context . repo ;
16
18
17
19
const octokit = getOctokit ( githubToken ) ;
18
20
@@ -21,34 +23,50 @@ async function run() {
21
23
repo,
22
24
tag : version ,
23
25
headers : {
24
- 'X-GitHub-Api-Version' : '2022-11-28'
25
- }
26
+ 'X-GitHub-Api-Version' : '2022-11-28' ,
27
+ } ,
26
28
} ) ;
27
29
28
-
29
30
const prNumbers = extractPrsFromReleaseBody ( release . data . body ) ;
30
31
31
- if ( ! prNumbers . length ) {
32
+ if ( ! prNumbers . length ) {
32
33
core . debug ( 'No PRs found in release body.' ) ;
33
34
return ;
34
35
}
35
36
36
37
core . debug ( `Found PRs in release body: ${ prNumbers . join ( ', ' ) } ` ) ;
37
38
38
- const linkedIssues = await Promise . all ( prNumbers . map ( ( prNumber ) => getLinkedIssuesForPr ( octokit , { repo , owner , prNumber } ) ) ) ;
39
-
40
- console . log ( linkedIssues ) ;
39
+ const linkedIssues = await Promise . all (
40
+ prNumbers . map ( prNumber => getLinkedIssuesForPr ( octokit , { repo , owner , prNumber } ) ) ,
41
+ ) ;
41
42
42
- for ( const pr of linkedIssues ) {
43
- if ( ! pr . issues . length ) {
43
+ for ( const pr of linkedIssues ) {
44
+ if ( ! pr . issues . length ) {
44
45
core . debug ( `No linked issues found for PR #${ pr . prNumber } ` ) ;
45
46
continue ;
46
47
}
47
48
48
49
core . debug ( `Linked issues for PR #${ pr . prNumber } : ${ pr . issues . map ( issue => issue . number ) . join ( ',' ) } ` ) ;
49
- }
50
50
51
+ for ( const issue of pr . issues ) {
52
+ if ( await hasExistingComment ( octokit , { repo, owner, issueNumber : issue . number } ) ) {
53
+ core . debug ( `Comment already exists for issue #${ issue . number } ` ) ;
54
+ continue ;
55
+ }
56
+
57
+ const body = `${ RELEASE_COMMENT_HEADING } \n\nThis issue was closed by PR #${ pr . prNumber } , which was included in the [${ version } release](https://github.com/${ owner } /${ repo } /releases/tag/${ version } ).` ;
58
+
59
+ core . debug ( `Creating comment for issue #${ issue . number } ` ) ;
60
+ core . debug ( body ) ;
51
61
62
+ /* await octokit.rest.issues.createComment({
63
+ repo,
64
+ owner,
65
+ issue_number: issue.number,
66
+ body,
67
+ }); */
68
+ }
69
+ }
52
70
}
53
71
54
72
/**
@@ -58,10 +76,12 @@ async function run() {
58
76
*/
59
77
function extractPrsFromReleaseBody ( body ) {
60
78
const regex = / \[ # ( \d + ) \] \( h t t p s : \/ \/ g i t h u b \. c o m \/ g e t s e n t r y \/ s e n t r y - j a v a s c r i p t \/ p u l l \/ (?: \d + ) \) / gm;
61
- const prNumbers = Array . from ( new Set ( [ ...body . matchAll ( regex ) ] . map ( ( match ) => parseInt ( match [ 1 ] ) ) ) ) ;
79
+ const prNumbers = Array . from ( new Set ( [ ...body . matchAll ( regex ) ] . map ( match => parseInt ( match [ 1 ] ) ) ) ) ;
80
+
81
+ return prNumbers . filter ( number => ! ! number && ! Number . isNaN ( number ) ) ;
82
+ }
62
83
63
- return prNumbers . filter ( number => ! ! number && ! Number . isNaN ( number ) ) ;
64
- } /**
84
+ /**
65
85
*
66
86
* @param {ReturnType<import('@actions/github').getOctokit> } octokit
67
87
* @param {{ repo: string, owner: string, prNumber: number} } options
@@ -92,13 +112,27 @@ query issuesForPr($owner: String!, $repo: String!, $prNumber: Int!) {
92
112
} ,
93
113
) ;
94
114
95
- console . log ( res ) ;
96
-
97
115
const issues = res . repository ?. pullRequest ?. closingIssuesReferences . edges . map ( edge => edge . node ) ;
98
116
return {
99
117
prNumber,
100
- issues
118
+ issues,
101
119
} ;
102
120
}
103
121
122
+ /**
123
+ *
124
+ * @param {ReturnType<import('@actions/github').getOctokit> } octokit
125
+ * @param {{ repo: string, owner: string, issueNumber: number} } options
126
+ * @returns {Promise<boolean> }
127
+ */
128
+ async function hasExistingComment ( octokit , { repo, owner, issueNumber } ) {
129
+ const { data : commentList } = await octokit . rest . issues . listComments ( {
130
+ repo,
131
+ owner,
132
+ issue_number : issueNumber ,
133
+ } ) ;
134
+
135
+ return commentList . some ( comment => comment . body . startsWith ( RELEASE_COMMENT_HEADING ) ) ;
136
+ }
137
+
104
138
run ( ) ;
0 commit comments