@@ -3,6 +3,17 @@ import { version as VERSION } from '../package.json';
33
44start ( ) . catch ( console . error ) ;
55
6+ const benchmarkPlatforms = [ 'chrome' , 'firefox' ] ;
7+ const buildTypes = [ 'browserify' , 'webpack' ] ;
8+
9+ type BenchmarkResults = Record <
10+ ( typeof benchmarkPlatforms ) [ number ] ,
11+ Record <
12+ ( typeof buildTypes ) [ number ] ,
13+ Record < string , Record < string , Record < string , string > > >
14+ >
15+ > ;
16+
617function getHumanReadableSize ( bytes : number ) : string {
718 if ( ! bytes ) {
819 return '0 Bytes' ;
@@ -165,17 +176,6 @@ async function start(): Promise<void> {
165176 const exposedContent = `Builds ready [${ SHORT_SHA1 } ]` ;
166177 const artifactsBody = `<details><summary>${ exposedContent } </summary>${ hiddenContent } </details>\n\n` ;
167178
168- const benchmarkPlatforms = [ 'chrome' , 'firefox' ] ;
169- const buildTypes = [ 'browserify' , 'webpack' ] ;
170-
171- type BenchmarkResults = Record <
172- ( typeof benchmarkPlatforms ) [ number ] ,
173- Record <
174- ( typeof buildTypes ) [ number ] ,
175- Record < string , Record < string , Record < string , string > > >
176- >
177- > ;
178-
179179 const benchmarkResults : BenchmarkResults = { } ;
180180 for ( const platform of benchmarkPlatforms ) {
181181 benchmarkResults [ platform ] = { } ;
@@ -294,7 +294,9 @@ async function start(): Promise<void> {
294294 . join ( '' ) } </tr></thead>`;
295295 const benchmarkTableBody = `<tbody>${ tableRows . join ( '' ) } </tbody>` ;
296296 const benchmarkTable = `<table>${ benchmarkTableHeader } ${ benchmarkTableBody } </table>` ;
297- const benchmarkBody = `<details><summary>${ benchmarkSummary } </summary>${ benchmarkTable } </details>\n\n` ;
297+ const benchmarkWarnings = await runBenchmarkGate ( benchmarkResults ) ;
298+ const benchmarkBody = `<details><summary>${ benchmarkSummary } </summary>${ benchmarkTable } ${ benchmarkWarnings } </details>\n\n` ;
299+
298300 commentBody += `${ benchmarkBody } ` ;
299301 } catch ( error ) {
300302 console . error ( `Error constructing benchmark results: '${ error } '` ) ;
@@ -373,17 +375,97 @@ async function start(): Promise<void> {
373375 const JSON_PAYLOAD = JSON . stringify ( { body : commentBody } ) ;
374376 const POST_COMMENT_URI = `https://api.github.com/repos/metamask/metamask-extension/issues/${ PR_NUMBER } /comments` ;
375377 console . log ( `Announcement:\n${ commentBody } ` ) ;
376- console . log ( `Posting to: ${ POST_COMMENT_URI } ` ) ;
377-
378- const response = await fetch ( POST_COMMENT_URI , {
379- method : 'POST' ,
380- body : JSON_PAYLOAD ,
381- headers : {
382- 'User-Agent' : 'metamaskbot' ,
383- Authorization : `token ${ PR_COMMENT_TOKEN } ` ,
384- } ,
385- } ) ;
386- if ( ! response . ok ) {
387- throw new Error ( `Post comment failed with status '${ response . statusText } '` ) ;
378+
379+ if ( PR_COMMENT_TOKEN ) {
380+ console . log ( `Posting to: ${ POST_COMMENT_URI } ` ) ;
381+
382+ const response = await fetch ( POST_COMMENT_URI , {
383+ method : 'POST' ,
384+ body : JSON_PAYLOAD ,
385+ headers : {
386+ 'User-Agent' : 'metamaskbot' ,
387+ Authorization : `token ${ PR_COMMENT_TOKEN } ` ,
388+ } ,
389+ } ) ;
390+ if ( ! response . ok ) {
391+ throw new Error (
392+ `Post comment failed with status '${ response . statusText } '` ,
393+ ) ;
394+ }
395+ }
396+ }
397+
398+ async function runBenchmarkGate (
399+ benchmarkResults : BenchmarkResults ,
400+ ) : Promise < string > {
401+ const benchmarkGateUrl = `${ process . env . CLOUDFRONT_REPO_URL } /benchmark-gate/benchmark-gate.json` ;
402+ const exceededSums = { mean : 0 , p95 : 0 } ;
403+ let benchmarkGateBody = '' ;
404+
405+ console . log ( `Fetching benchmark gate from ${ benchmarkGateUrl } ` ) ;
406+ try {
407+ const benchmarkResponse = await fetch ( benchmarkGateUrl ) ;
408+ if ( ! benchmarkResponse . ok ) {
409+ throw new Error (
410+ `Failed to fetch benchmark gate data, status ${ benchmarkResponse . statusText } ` ,
411+ ) ;
412+ }
413+
414+ const { gates, pingThresholds } = await benchmarkResponse . json ( ) ;
415+
416+ // Compare benchmarkResults with benchmark-gate.json
417+ for ( const platform of Object . keys ( gates ) ) {
418+ for ( const buildType of Object . keys ( gates [ platform ] ) ) {
419+ for ( const page of Object . keys ( gates [ platform ] [ buildType ] ) ) {
420+ for ( const measure of Object . keys ( gates [ platform ] [ buildType ] [ page ] ) ) {
421+ for ( const metric of Object . keys (
422+ gates [ platform ] [ buildType ] [ page ] [ measure ] ,
423+ ) ) {
424+ const benchmarkValue =
425+ benchmarkResults [ platform ] [ buildType ] [ page ] [ measure ] [ metric ] ;
426+
427+ const gateValue =
428+ gates [ platform ] [ buildType ] [ page ] [ measure ] [ metric ] ;
429+
430+ if ( benchmarkValue > gateValue ) {
431+ const ceiledValue = Math . ceil ( parseFloat ( benchmarkValue ) ) ;
432+
433+ if ( measure === 'mean' ) {
434+ exceededSums . mean += ceiledValue - gateValue ;
435+ } else if ( measure === 'p95' ) {
436+ exceededSums . p95 += ceiledValue - gateValue ;
437+ }
438+
439+ benchmarkGateBody += `Benchmark value ${ ceiledValue } exceeds gate value ${ gateValue } for ${ platform } ${ buildType } ${ page } ${ measure } ${ metric } <br>\n` ;
440+ }
441+ }
442+ }
443+ }
444+ }
445+ }
446+
447+ if ( benchmarkGateBody ) {
448+ benchmarkGateBody += `<b>Sum of mean exceeds: ${
449+ exceededSums . mean
450+ } ms | Sum of p95 exceeds: ${
451+ exceededSums . p95
452+ } ms<br>\nSum of all benchmark exceeds: ${
453+ exceededSums . mean + exceededSums . p95
454+ } ms</b><br>\n`;
455+
456+ if (
457+ exceededSums . mean > pingThresholds . mean ||
458+ exceededSums . p95 > pingThresholds . p95 ||
459+ exceededSums . mean + exceededSums . p95 >
460+ pingThresholds . mean + pingThresholds . p95
461+ ) {
462+ // Soft gate, just pings @HowardBraham
463+ benchmarkGateBody = `cc: @HowardBraham<br>\n${ benchmarkGateBody } ` ;
464+ }
465+ }
466+ } catch ( error ) {
467+ console . error ( `Error encountered fetching benchmark gate data: '${ error } '` ) ;
388468 }
469+
470+ return benchmarkGateBody ;
389471}
0 commit comments