@@ -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
@@ -109,37 +110,47 @@ async function run() {
109110 ci : false ,
110111 verbose : false
111112 } )
112- table . push ( buildTableLine ( api , report ) )
113+ const [ namespace , _method ] = api . split ( '.' )
114+ // Asked to validate a specific API, so we only store that one
115+ reports . set ( api , report . get ( namespace ) [ 0 ] )
113116 }
114117 } else {
118+ const api = getApi ( file )
115119 const report = await getReport ( {
116- api : getApi ( file ) ,
120+ api,
117121 'generate-report' : false ,
118122 request : true ,
119123 response : true ,
120124 ci : false ,
121125 verbose : false
122126 } )
123- table . push ( buildTableLine ( getApi ( file ) , report ) )
127+
128+ const [ namespace , _method ] = api . split ( '.' )
129+ // Asked to validate a specific API, so we only store that one
130+ reports . set ( api , report . get ( namespace ) [ 0 ] )
124131 }
125132 }
126133
127134 cd ( path . join ( __dirname , '..' , '..' ) )
128135
129- table . sort ( ( a , b ) => {
130- if ( a < b ) return - 1
131- if ( a > b ) return 1
132- return 0
133- } )
136+ // Compare current reports with baseline and find changes
137+ const changedApis = [ ]
138+ for ( const [ apiName , report ] of reports ) {
139+ const baselineReport = findBaselineReport ( apiName , baselineValidation )
140+ if ( baselineReport && hasChanges ( baselineReport , report , apiName ) ) {
141+ changedApis . push ( { api : apiName , baseline : baselineReport , current : report } )
142+ }
143+ }
144+ changedApis . sort ( ( a , b ) => a . api . localeCompare ( b . api ) )
134145
135- if ( table . length > 0 ) {
136- let comment = `Following you can find the validation results for the API${ table . length === 1 ? '' : 's' } you have changed .\n\n`
146+ if ( changedApis . length > 0 ) {
147+ let comment = `Following you can find the validation changes for the API${ changedApis . length === 1 ? '' : 's' } you have modified .\n\n`
137148 comment += '| API | Status | Request | Response |\n'
138149 comment += '| --- | --- | --- | --- |\n'
139- for ( const line of [ ... new Set ( table ) ] ) {
140- comment += line
150+ for ( const change of changedApis ) {
151+ comment += buildDiffTableLine ( change )
141152 }
142- comment += `\nYou can validate ${ table . length === 1 ? 'this' : 'these' } API${ table . length === 1 ? '' : 's' } yourself by using the ${ tick } make validate${ tick } target.\n`
153+ comment += `\nYou can validate ${ changedApis . length === 1 ? 'this' : 'these' } API${ changedApis . length === 1 ? '' : 's' } yourself by using the ${ tick } make validate${ tick } target.\n`
143154
144155 core . setOutput ( 'has_results' , 'true' )
145156 core . setOutput ( 'comment_body' , comment )
@@ -154,39 +165,70 @@ function getApi (file) {
154165 return file . split ( '/' ) . slice ( 1 , 3 ) . filter ( s => ! privateNames . includes ( s ) ) . filter ( Boolean ) . join ( '.' )
155166}
156167
157- function buildTableLine ( api , report ) {
158- const apiReport = report . get ( getNamespace ( api ) ) . find ( r => r . api === getName ( api ) )
159- return `| ${ tick } ${ api } ${ tick } | ${ generateStatus ( apiReport ) } | ${ generateRequest ( apiReport ) } | ${ generateResponse ( apiReport ) } |\n`
168+
169+ function findBaselineReport ( apiName , baselineValidation ) {
170+ const [ namespace , method ] = apiName . split ( '.' )
171+
172+ if ( ! baselineValidation . namespaces [ namespace ] ) {
173+ return null
174+ }
175+
176+ return baselineValidation . namespaces [ namespace ] . apis . find ( api => api . api === method )
160177}
161178
162- function generateStatus ( report ) {
163- if ( ! report . diagnostics . hasRequestType || ! report . diagnostics . hasResponseType ) {
179+ function hasChanges ( baselineReport , report ) {
180+ if ( ! report ) return false
181+
182+ return baselineReport . status !== report . status ||
183+ baselineReport . passingRequest !== report . passingRequest ||
184+ baselineReport . passingResponse !== report . passingResponse
185+ }
186+
187+ function buildDiffTableLine ( change ) {
188+ const { api, baseline, current } = change
189+
190+ const status = generateStatus ( current . status )
191+ const request = generateRequest ( current )
192+ const response = generateResponse ( current )
193+
194+ const baselineStatus = generateStatus ( baseline . status )
195+ const baselineRequest = generateRequest ( baseline )
196+ const baselineResponse = generateResponse ( baseline )
197+
198+ const statusDiff = status !== baselineStatus ? `${ baselineStatus } → ${ status } ` : status
199+ const requestDiff = request !== baselineRequest ? `${ baselineRequest } → ${ request } ` : request
200+ const responseDiff = response !== baselineResponse ? `${ baselineResponse } → ${ response } ` : response
201+
202+ return `| ${ tick } ${ api } ${ tick } | ${ statusDiff } | ${ requestDiff } | ${ responseDiff } |\n`
203+ }
204+
205+
206+ function generateStatus ( status ) {
207+ if ( status === 'missing_types' || status === 'missing_request_type' || status === 'missing_response_type' ) {
164208 return ':orange_circle:'
165209 }
166- if ( report . totalRequest <= 0 || report . totalResponse <= 0 ) {
210+ if ( status === 'missing_test' ) {
167211 return ':white_circle:'
168212 }
169- if ( report . diagnostics . request . length === 0 && report . diagnostics . response . length === 0 ) {
213+ if ( status === 'passing' ) {
170214 return ':green_circle:'
171215 }
172216 return ':red_circle:'
173217}
174218
175219function generateRequest ( r ) {
176- if ( r . totalRequest === - 1 ) return 'Missing recording'
177- if ( ! r . diagnostics . hasRequestType ) return 'Missing type'
178- if ( r . totalRequest === 0 ) return 'Missing test'
220+ if ( r . status === 'missing_test' ) return 'Missing test'
221+ if ( r . status === 'missing_types' || r . status == 'missing_request_type' ) return 'Missing type'
179222 return `${ r . passingRequest } /${ r . totalRequest } `
180223}
181224
182225function generateResponse ( r ) {
183- if ( r . totalResponse === - 1 ) return 'Missing recording'
184- if ( ! r . diagnostics . hasResponseType ) return 'Missing type'
185- if ( r . totalResponse === 0 ) return 'Missing test'
226+ if ( r . status === 'missing_test' ) return 'Missing test'
227+ if ( r . status === 'missing_types' || r . status == 'missing_response_type' ) return 'Missing type'
186228 return `${ r . passingResponse } /${ r . totalResponse } `
187229}
188230
189231run ( ) . catch ( ( err ) => {
190232 core . error ( err )
191233 process . exit ( 1 )
192- } )
234+ } )
0 commit comments