@@ -27,6 +27,7 @@ import * as core from '@actions/core'
2727import { copyFile } from 'fs/promises'
2828import * as github from '@actions/github'
2929import 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' }
3031import { run as getReport } from '../../../clients-flight-recorder/scripts/types-validator/index.js'
3132import {
3233 getNamespace ,
@@ -81,7 +82,7 @@ async function run() {
8182 const specFiles = files . filter (
8283 ( file ) => file . includes ( 'specification' ) && ! file . includes ( 'compiler/test' )
8384 )
84- const table = [ ]
85+ const reports = new Map ( )
8586
8687 cd ( tsValidationPath )
8788
@@ -104,37 +105,47 @@ async function run() {
104105 ci : false ,
105106 verbose : false
106107 } )
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 ] )
108111 }
109112 } else {
113+ const api = getApi ( file )
110114 const report = await getReport ( {
111- api : getApi ( file ) ,
115+ api,
112116 'generate-report' : false ,
113117 request : true ,
114118 response : true ,
115119 ci : false ,
116120 verbose : false
117121 } )
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 ] )
119126 }
120127 }
121128
122129 cd ( path . join ( __dirname , '..' , '..' ) )
123130
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 ) )
129140
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`
132143 comment += '| API | Status | Request | Response |\n'
133144 comment += '| --- | --- | --- | --- |\n'
134- for ( const line of [ ... new Set ( table ) ] ) {
135- comment += line
145+ for ( const change of changedApis ) {
146+ comment += buildDiffTableLine ( change )
136147 }
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`
138149
139150 await octokit . rest . issues . createComment ( {
140151 owner : 'elastic' ,
@@ -151,39 +162,70 @@ function getApi (file) {
151162 return file . split ( '/' ) . slice ( 1 , 3 ) . filter ( s => ! privateNames . includes ( s ) ) . filter ( Boolean ) . join ( '.' )
152163}
153164
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 )
157174}
158175
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' ) {
161205 return ':orange_circle:'
162206 }
163- if ( report . totalRequest <= 0 || report . totalResponse <= 0 ) {
207+ if ( status === 'missing_test' ) {
164208 return ':white_circle:'
165209 }
166- if ( report . diagnostics . request . length === 0 && report . diagnostics . response . length === 0 ) {
210+ if ( status === 'passing' ) {
167211 return ':green_circle:'
168212 }
169213 return ':red_circle:'
170214}
171215
172216function 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'
176219 return `${ r . passingRequest } /${ r . totalRequest } `
177220}
178221
179222function 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'
183225 return `${ r . passingResponse } /${ r . totalResponse } `
184226}
185227
186228run ( ) . catch ( ( err ) => {
187229 core . error ( err )
188230 process . exit ( 1 )
189- } )
231+ } )
0 commit comments