@@ -27,6 +27,7 @@ import * as core from '@actions/core'
27
27
import { copyFile } from 'fs/promises'
28
28
import * as github from '@actions/github'
29
29
import specification from '../../output/schema/schema.json' with { type : 'json' }
30
+ import baselineValidation from '../../../clients-flight-recorder/recordings/types-validation/types-validation.json' with { type : 'json' }
30
31
import { run as getReport } from '../../../clients-flight-recorder/scripts/types-validator/index.js'
31
32
import {
32
33
getNamespace ,
@@ -81,7 +82,7 @@ async function run() {
81
82
const specFiles = files . filter (
82
83
( file ) => file . includes ( 'specification' ) && ! file . includes ( 'compiler/test' )
83
84
)
84
- const table = [ ]
85
+ const reports = new Map ( )
85
86
86
87
cd ( tsValidationPath )
87
88
@@ -104,37 +105,47 @@ async function run() {
104
105
ci : false ,
105
106
verbose : false
106
107
} )
107
- table . push ( buildTableLine ( api , report ) )
108
+ const [ namespace , _method ] = api . split ( '.' )
109
+ // Asked to validate a specific API, so we only store that one
110
+ reports . set ( api , report . get ( namespace ) [ 0 ] )
108
111
}
109
112
} else {
113
+ const api = getApi ( file )
110
114
const report = await getReport ( {
111
- api : getApi ( file ) ,
115
+ api,
112
116
'generate-report' : false ,
113
117
request : true ,
114
118
response : true ,
115
119
ci : false ,
116
120
verbose : false
117
121
} )
118
- table . push ( buildTableLine ( getApi ( file ) , report ) )
122
+
123
+ const [ namespace , _method ] = api . split ( '.' )
124
+ // Asked to validate a specific API, so we only store that one
125
+ reports . set ( api , report . get ( namespace ) [ 0 ] )
119
126
}
120
127
}
121
128
122
129
cd ( path . join ( __dirname , '..' , '..' ) )
123
130
124
- table . sort ( ( a , b ) => {
125
- if ( a < b ) return - 1
126
- if ( a > b ) return 1
127
- return 0
128
- } )
131
+ // Compare current reports with baseline and find changes
132
+ const changedApis = [ ]
133
+ for ( const [ apiName , report ] of reports ) {
134
+ const baselineReport = findBaselineReport ( apiName , baselineValidation )
135
+ if ( baselineReport && hasChanges ( baselineReport , report , apiName ) ) {
136
+ changedApis . push ( { api : apiName , baseline : baselineReport , current : report } )
137
+ }
138
+ }
139
+ changedApis . sort ( ( a , b ) => a . api . localeCompare ( b . api ) )
129
140
130
- if ( table . length > 0 ) {
131
- let comment = `Following you can find the validation results for the API${ table . length === 1 ? '' : 's' } you have changed .\n\n`
141
+ if ( changedApis . length > 0 ) {
142
+ let comment = `Following you can find the validation changes for the API${ changedApis . length === 1 ? '' : 's' } you have modified .\n\n`
132
143
comment += '| API | Status | Request | Response |\n'
133
144
comment += '| --- | --- | --- | --- |\n'
134
- for ( const line of [ ... new Set ( table ) ] ) {
135
- comment += line
145
+ for ( const change of changedApis ) {
146
+ comment += buildDiffTableLine ( change )
136
147
}
137
- comment += `\nYou can validate ${ table . length === 1 ? 'this' : 'these' } API${ table . length === 1 ? '' : 's' } yourself by using the ${ tick } make validate${ tick } target.\n`
148
+ comment += `\nYou can validate ${ changedApis . length === 1 ? 'this' : 'these' } API${ changedApis . length === 1 ? '' : 's' } yourself by using the ${ tick } make validate${ tick } target.\n`
138
149
139
150
await octokit . rest . issues . createComment ( {
140
151
owner : 'elastic' ,
@@ -151,39 +162,70 @@ function getApi (file) {
151
162
return file . split ( '/' ) . slice ( 1 , 3 ) . filter ( s => ! privateNames . includes ( s ) ) . filter ( Boolean ) . join ( '.' )
152
163
}
153
164
154
- function buildTableLine ( api , report ) {
155
- const apiReport = report . get ( getNamespace ( api ) ) . find ( r => r . api === getName ( api ) )
156
- return `| ${ tick } ${ api } ${ tick } | ${ generateStatus ( apiReport ) } | ${ generateRequest ( apiReport ) } | ${ generateResponse ( apiReport ) } |\n`
165
+
166
+ function findBaselineReport ( apiName , baselineValidation ) {
167
+ const [ namespace , method ] = apiName . split ( '.' )
168
+
169
+ if ( ! baselineValidation . namespaces [ namespace ] ) {
170
+ return null
171
+ }
172
+
173
+ return baselineValidation . namespaces [ namespace ] . apis . find ( api => api . api === method )
157
174
}
158
175
159
- function generateStatus ( report ) {
160
- if ( ! report . diagnostics . hasRequestType || ! report . diagnostics . hasResponseType ) {
176
+ function hasChanges ( baselineReport , report ) {
177
+ if ( ! report ) return false
178
+
179
+ return baselineReport . status !== report . status ||
180
+ baselineReport . passingRequest !== report . passingRequest ||
181
+ baselineReport . passingResponse !== report . passingResponse
182
+ }
183
+
184
+ function buildDiffTableLine ( change ) {
185
+ const { api, baseline, current } = change
186
+
187
+ const status = generateStatus ( current . status )
188
+ const request = generateRequest ( current )
189
+ const response = generateResponse ( current )
190
+
191
+ const baselineStatus = generateStatus ( baseline . status )
192
+ const baselineRequest = generateRequest ( baseline )
193
+ const baselineResponse = generateResponse ( baseline )
194
+
195
+ const statusDiff = status !== baselineStatus ? `${ baselineStatus } → ${ status } ` : status
196
+ const requestDiff = request !== baselineRequest ? `${ baselineRequest } → ${ request } ` : request
197
+ const responseDiff = response !== baselineResponse ? `${ baselineResponse } → ${ response } ` : response
198
+
199
+ return `| ${ tick } ${ api } ${ tick } | ${ statusDiff } | ${ requestDiff } | ${ responseDiff } |\n`
200
+ }
201
+
202
+
203
+ function generateStatus ( status ) {
204
+ if ( status === 'missing_types' || status === 'missing_request_type' || status === 'missing_response_type' ) {
161
205
return ':orange_circle:'
162
206
}
163
- if ( report . totalRequest <= 0 || report . totalResponse <= 0 ) {
207
+ if ( status === 'missing_test' ) {
164
208
return ':white_circle:'
165
209
}
166
- if ( report . diagnostics . request . length === 0 && report . diagnostics . response . length === 0 ) {
210
+ if ( status === 'passing' ) {
167
211
return ':green_circle:'
168
212
}
169
213
return ':red_circle:'
170
214
}
171
215
172
216
function generateRequest ( r ) {
173
- if ( r . totalRequest === - 1 ) return 'Missing recording'
174
- if ( ! r . diagnostics . hasRequestType ) return 'Missing type'
175
- if ( r . totalRequest === 0 ) return 'Missing test'
217
+ if ( r . status === 'missing_test' ) return 'Missing test'
218
+ if ( r . status === 'missing_types' || r . status == 'missing_request_type' ) return 'Missing type'
176
219
return `${ r . passingRequest } /${ r . totalRequest } `
177
220
}
178
221
179
222
function generateResponse ( r ) {
180
- if ( r . totalResponse === - 1 ) return 'Missing recording'
181
- if ( ! r . diagnostics . hasResponseType ) return 'Missing type'
182
- if ( r . totalResponse === 0 ) return 'Missing test'
223
+ if ( r . status === 'missing_test' ) return 'Missing test'
224
+ if ( r . status === 'missing_types' || r . status == 'missing_response_type' ) return 'Missing type'
183
225
return `${ r . passingResponse } /${ r . totalResponse } `
184
226
}
185
227
186
228
run ( ) . catch ( ( err ) => {
187
229
core . error ( err )
188
230
process . exit ( 1 )
189
- } )
231
+ } )
0 commit comments