@@ -30,13 +30,181 @@ type GetFileResponse = {
3030 } ;
3131} ;
3232
33+
34+ const getPaths = `
35+ query getPaths($owner: String!, $repo: String!, $number: Int!, cursor: String = "") {
36+ repository(name: $repo, owner: $owner) {
37+ pullRequest(number: $number) {
38+ id
39+ files(first: 2, after: $cursor) {
40+ edges {
41+ node {
42+ path
43+ }
44+ cursor
45+ }
46+ }
47+ }
48+ }
49+ }
50+ `
51+
52+ function checkPathsResponse ( paths : GetPathsResponse ) {
53+ const edges = paths . repository . pullRequest . files . edges
54+ const docsChanged = edges . some ( edge => edge . node . path . startsWith ( 'docs/' ) )
55+ const configChanged = edges . some ( edge => [ "docs.json" , "docs.yaml" ] . includes ( edge . node . path ) )
56+ return docsChanged || configChanged ;
57+ }
58+
59+ function getLastFileCursor ( getPathsResponse : GetPathsResponse ) {
60+ const edges = getPathsResponse . repository . pullRequest . files . edges
61+ return edges [ edges . length - 1 ] . cursor
62+ }
63+
64+
65+ function checkCommentsResponse ( comments : GetCommentsResponse ) {
66+ const edges = comments . repository . pullRequest . comments . edges
67+ const docsChanged = edges . some ( edge => edge . node . author . login === "docs-page" )
68+ return docsChanged ;
69+ }
70+
71+ function getLastCommentCursor ( getCommentsResponse : GetCommentsResponse ) {
72+ const edges = getCommentsResponse . repository . pullRequest . comments . edges
73+ return edges [ edges . length - 1 ] . cursor
74+ }
75+
76+ type GetPathsResponse = {
77+ repository : {
78+ pullRequest : {
79+ files : {
80+ edges : {
81+ node : {
82+ path : string
83+ }
84+ cursor : string
85+ } [ ]
86+ }
87+ }
88+ }
89+ }
90+
91+ const getFirstComments = `
92+ query getComments($owner: String!, $repo: String!, $number: Int!) {
93+ repository(name: $repo, owner: $owner) {
94+ pullRequest(number: $number) {
95+ comments(first: 100) {
96+ edges {
97+ node {
98+ author {
99+ login
100+ }
101+ }
102+ cursor
103+ }
104+ totalCount
105+ }
106+ }
107+ }
108+ }
109+ `
110+ const getComments = `
111+ query getComments($owner: String!, $repo: String!, $number: Int!, cursor: String!) {
112+ repository(name: $repo, owner: $owner) {
113+ pullRequest(number: $number) {
114+ comments(first: 100, after: $cursor) {
115+ edges {
116+ node {
117+ author {
118+ login
119+ }
120+ }
121+ cursor
122+ }
123+ }
124+ }
125+ }
126+ }
127+ `
128+
129+ type GetCommentsResponse = {
130+ repository : {
131+ pullRequest : {
132+ comments : {
133+ edges : {
134+ node : {
135+ author : {
136+ login : string
137+ }
138+ }
139+ cursor : string
140+ } [ ] ,
141+ totalCount ?: number
142+ }
143+ }
144+ }
145+ }
146+
147+
33148const app = ( app : Probot ) => {
34- app . on ( 'pull_request.opened' , async context => {
149+ app . on ( [ 'pull_request.opened' , 'pull_request.synchronize' ] , async context => {
35150 app . log . info ( context ) ;
36151
37- const pull_request = context . payload . pull_request ;
152+ const { repository, pull_request } = context . payload ;
153+
154+ const totalChangedFiles = pull_request . changed_files ;
155+
156+ let totalFilesChecked = 0 ;
157+ let shouldComment = false ;
158+ let cursor = '' ;
159+
160+ // check files in batches of 100 until we find a docs file or we've checked all files
161+ while ( totalFilesChecked < totalChangedFiles && ! shouldComment ) {
162+
163+ const getPathsResponse = await context
164+ . octokit
165+ . graphql < GetPathsResponse > ( getPaths , {
166+ owner : repository . owner . login ,
167+ repo : repository . name ,
168+ number : pull_request . number ,
169+ cursor
170+ } ) ;
171+
172+ shouldComment = checkPathsResponse ( getPathsResponse ) ;
173+ cursor = getLastFileCursor ( getPathsResponse ) ;
174+ }
175+
176+ // check to see if we've commented before
177+
178+
179+ // for some reason an empty cursor doesn't work for comments, so we have to obtain the first cursor manually.
180+ const getFirstCommentsResponse = await context
181+ . octokit
182+ . graphql < GetCommentsResponse > ( getFirstComments , {
183+ owner : repository . owner . login ,
184+ repo : repository . name ,
185+ number : pull_request . number ,
186+ } ) ;
187+
188+ let totalComments = getFirstCommentsResponse . repository . pullRequest . comments . totalCount ;
189+ let totalCommentsChecked = getFirstCommentsResponse . repository . pullRequest . comments . edges . length ;
190+ let commentCursor = getLastCommentCursor ( getFirstCommentsResponse ) ;
191+ let hasCommented = checkCommentsResponse ( getFirstCommentsResponse ) ;
192+
193+ while ( totalCommentsChecked < totalComments ! && ! hasCommented ) {
194+ const getCommentsResponse = await context
195+ . octokit
196+ . graphql < GetCommentsResponse > ( getComments , {
197+ owner : repository . owner . login ,
198+ repo : repository . name ,
199+ number : pull_request . number ,
200+ cursor : commentCursor
201+ } ) ;
202+ hasCommented = checkCommentsResponse ( getCommentsResponse ) ;
203+ commentCursor = getLastCommentCursor ( getCommentsResponse ) ;
204+ }
205+
206+ shouldComment = shouldComment && ! hasCommented ;
38207
39- const { repository } = context . payload ;
40208
41209 // e.g. org/repo
42210 const name = repository . full_name . toLowerCase ( ) ;
0 commit comments