6
6
Usage:
7
7
```shell
8
8
BASE_DIST_FILES='{"src/Autocomplete/assets/dist/controller.js":{"size":15382,"size_gz":3716,"size_brotli":3125},"src/Chartjs/assets/dist/controller.js":{"size":2281,"size_gz":771,"size_brotli":642},"src/Cropperjs/assets/dist/controller.js":{"size":1044,"size_gz":475,"size_brotli":371}}' \
9
- PR_DIST_FILES='{"src/Chartjs/assets/dist/controller.js":{"size":2281,"size_gz":771,"size_brotli":642},"src/Cropperjs/assets/dist/controller.js":{"size":1044,"size_gz":475,"size_brotli":371},"src/Cropperjs/assets/dist/style.min.css":{"size":32,"size_gz":66,"size_brotli":34},"src/Dropzone/assets/dist/controller.js":{"size":3199,"size_gz":816,"size_brotli":634}}' \
9
+ PR_DIST_FILES='{"src/Chartjs/assets/dist/controller.js":{"size":1281,"size_gz":171,"size_brotli":641},"src/Cropperjs/assets/dist/controller.js":{"size":1044,"size_gz":475,"size_brotli":371},"src/Cropperjs/assets/dist/style.min.css":{"size":32,"size_gz":66,"size_brotli":34},"src/Dropzone/assets/dist/controller.js":{"size":3199,"size_gz":816,"size_brotli":634},"src/Map/src/Bridge/Google/assets/dist/foo.js":{"size":3199,"size_gz":816,"size_brotli":634}}' \
10
+ GITHUB_REPOSITORY='symfony/ux' \
11
+ GITHUB_HEAD_REF='my-branch-name' \
10
12
node .github/generate-dist-files-size-diff.mjs
11
13
```
12
14
*/
@@ -19,6 +21,14 @@ if (!process.env.PR_DIST_FILES) {
19
21
throw new Error ( 'Missing or invalid "PR_DIST_FILES" env variable.' ) ;
20
22
}
21
23
24
+ if ( ! process . env . GITHUB_REPOSITORY ) {
25
+ throw new Error ( 'Missing or invalid "GITHUB_REPOSITORY" env variable.' ) ;
26
+ }
27
+
28
+ if ( ! process . env . GITHUB_HEAD_REF ) {
29
+ throw new Error ( 'Missing or invalid "GITHUB_HEAD_REF" env variable.' ) ;
30
+ }
31
+
22
32
/**
23
33
* Adapted from https://gist.github.com/zentala/1e6f72438796d74531803cc3833c039c?permalink_comment_id=4455218#gistcomment-4455218
24
34
* @param {number } bytes
@@ -44,8 +54,8 @@ function computeDiffPercent(from, to) {
44
54
if ( from === to ) {
45
55
return 0 ;
46
56
}
47
-
48
- return Number ( ( ( from - to ) / to * - 100 ) . toFixed ( 2 ) ) ;
57
+
58
+ return Number ( ( ( from - to ) / to * - 100 ) . toFixed ( 1 ) ) ;
49
59
}
50
60
51
61
/**
@@ -57,54 +67,106 @@ function formatDiffPercent(percent) {
57
67
}
58
68
59
69
export function main ( ) {
60
- let base = JSON . parse ( process . env . BASE_DIST_FILES ) ;
61
- let pr = JSON . parse ( process . env . PR_DIST_FILES ) ;
62
- let output = '<h1>📊 Dist files size difference</h1>\n\n' ;
63
-
64
- const files = [ ...new Set ( [ ...Object . keys ( pr ) , ...Object . keys ( base ) ] ) ] . sort ( ) . reduce ( ( acc , file ) => {
65
- const added = ! base [ file ] && pr [ file ] ;
66
- const removed = base [ file ] && ! pr [ file ] ;
67
- const diff_percent_size = removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( base [ file ] . size , pr [ file ] . size ) ) ) ;
68
- const diff_percent_size_gz = removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( base [ file ] . size_gz , pr [ file ] . size_gz ) ) ) ;
69
- const diff_percent_size_brotli = removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( base [ file ] . size_brotli , pr [ file ] . size_brotli ) ) ) ;
70
-
71
- if ( diff_percent_size !== 0 && diff_percent_size_gz !== 0 && diff_percent_size_brotli !== 0 ) {
72
- acc . set ( file , {
73
- state : added ? 'added' : ( removed ? 'removed' : 'changed' ) ,
74
- diff_percent_size,
75
- diff_percent_size_gz,
76
- diff_percent_size_brotli
77
- } ) ;
78
- }
70
+ const repoUrl = `https://github.com/${ process . env . GITHUB_REPOSITORY } ` ;
71
+ /** @type {Record<string, {size: number, size_gz: number, size_brotli: number}> } */
72
+ const base = JSON . parse ( process . env . BASE_DIST_FILES ) ;
73
+ /** @type {Record<string, {size: number, size_gz: number, size_brotli: number}> } */
74
+ const pr = JSON . parse ( process . env . PR_DIST_FILES ) ;
75
+ let output = '<h1>📊 Dist packagesFiles size difference</h1>\n\n' ;
79
76
80
- return acc ;
81
- } , new Map ) ;
77
+ /**
78
+ * @type {Map<string, {
79
+ * meta: {
80
+ * packageName: string,
81
+ * bridgeName: string,
82
+ * url: string,
83
+ * },
84
+ * files: Set<{
85
+ * state: 'added' | 'removed' | 'changed',
86
+ * before: {size: number, sizeGz: number, sizeBrotli: number},
87
+ * after: {size: number, sizeGz: number, sizeBrotli: number},
88
+ * diffPercent: {size: number, sizeGz: number, sizeBrotli: number},
89
+ * meta: {fileNameShort: string, fileNameUrl: string}
90
+ * }>
91
+ * }> }
92
+ */
93
+ const packagesFiles = [ ...new Set ( [ ...Object . keys ( pr ) , ...Object . keys ( base ) ] ) ]
94
+ . sort ( )
95
+ . reduce ( ( acc , file ) => {
96
+ const beforeSize = base [ file ] ?. size || 0 ;
97
+ const afterSize = pr [ file ] ?. size || 0 ;
98
+ const beforeSizeGz = base [ file ] ?. size_gz || 0 ;
99
+ const afterSizeGz = pr [ file ] ?. size_gz || 0 ;
100
+ const beforeSizeBrotli = base [ file ] ?. size_brotli || 0 ;
101
+ const afterSizeBrotli = pr [ file ] ?. size_brotli || 0 ;
82
102
83
- if ( files . size === 0 ) {
84
- output += 'ℹ️ No difference in dist files.\n' ;
103
+ if ( beforeSize !== afterSize ) {
104
+ const isBridge = file . includes ( 'src/Bridge' ) ; // we assume that's enough for now
105
+ const packageName = file . split ( '/' ) [ 1 ] ;
106
+ const bridgeName = isBridge ? file . split ( '/' ) [ 4 ] : '' ;
107
+ const key = isBridge ? `${ packageName } (Bridge ${ bridgeName } )` : packageName ;
108
+ if ( ! acc . has ( key ) ) {
109
+ acc . set ( key , {
110
+ meta : {
111
+ packageName,
112
+ bridgeName,
113
+ url : isBridge ? `${ repoUrl } /tree/${ process . env . GITHUB_HEAD_REF } /src/${ packageName } /src/Bridge/${ bridgeName } /assets/dist` : `${ repoUrl } /tree/${ process . env . GITHUB_HEAD_REF } /src/${ packageName } /assets/dist` ,
114
+ } , files : new Set ( ) ,
115
+ } ) ;
116
+ }
117
+
118
+ const added = ! base [ file ] && pr [ file ] ;
119
+ const removed = base [ file ] && ! pr [ file ] ;
120
+
121
+ acc . get ( key ) . files . add ( {
122
+ state : added ? 'added' : ( removed ? 'removed' : 'changed' ) ,
123
+ before : { size : beforeSize , sizeGz : beforeSizeGz , sizeBrotli : beforeSizeBrotli } ,
124
+ after : { size : afterSize , sizeGz : afterSizeGz , sizeBrotli : afterSizeBrotli } ,
125
+ diffPercent : {
126
+ size : removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( beforeSize , afterSize ) ) ) ,
127
+ sizeGz : removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( beforeSizeGz , afterSizeGz ) ) ) ,
128
+ sizeBrotli : removed ? - 100 : ( added ? 100 : ( computeDiffPercent ( beforeSizeBrotli , afterSizeBrotli ) ) ) ,
129
+ } ,
130
+ meta : {
131
+ fileNameShort : file . replace ( isBridge ? `src/${ file . split ( '/' ) [ 1 ] } /src/Bridge/${ file . split ( '/' ) [ 4 ] } /assets/dist/` : `src/${ file . split ( '/' ) [ 1 ] } /assets/dist/` , '' ) ,
132
+ fileNameUrl : `${ repoUrl } /blob/${ process . env . GITHUB_HEAD_REF } /${ file } ` ,
133
+ } ,
134
+ } ) ;
135
+ }
136
+
137
+ return acc ;
138
+ } , new Map ) ;
139
+
140
+ if ( packagesFiles . size === 0 ) {
141
+ output += 'ℹ️ No difference in dist packagesFiles.\n' ;
85
142
return output ;
86
143
}
87
144
88
- output += 'Thanks for the PR! Here is the difference in size of the dist files between the base and the PR.\n' ;
145
+ output += 'Thanks for the PR! Here is the difference in size of the dist packagesFiles between the base and the PR.\n' ;
89
146
output += 'Please review the changes and make sure they are expected.\n\n' ;
90
147
output += `<table>
91
- <thead><tr><th>File</th><th>Diff (B )</th><th>Diff (% )</th></tr></thead>
148
+ <thead><tr><th>File</th><th>Before (Size / Gzip / Brotli )</th><th>After (Size / Gzip / Brotli )</th></tr></thead>
92
149
<tbody>` ;
93
- for ( const [ file , details ] of files . entries ( ) ) {
94
- output += `<tr>
95
- <td><code>${ file } </code> ${ details . state === 'added' ? '(new)' : ( details . state === 'removed' ? '(deleted)' : '' ) } </td>
96
- <td>
97
- Size: <code>${ formatBytes ( base [ file ] ?. size || 0 ) } </code> → <code>${ formatBytes ( pr [ file ] ?. size || 0 ) } </code><br>
98
- Gzip: <code>${ formatBytes ( base [ file ] ?. size_gz || 0 ) } </code> → <code>${ formatBytes ( pr [ file ] ?. size_gz || 0 ) } </code><br>
99
- Brotli: <code>${ formatBytes ( base [ file ] ?. size_brotli || 0 ) } </code> → <code>${ formatBytes ( pr [ file ] ?. size_brotli || 0 ) } </code>
100
- </td>
101
- <td align="right">
102
- Size: <b>${ formatDiffPercent ( details . diff_percent_size ) } </b><br>
103
- Gzip: <b>${ formatDiffPercent ( details . diff_percent_size_gz ) } </b><br>
104
- Brotli: <b>${ formatDiffPercent ( details . diff_percent_size_brotli ) } </b>
105
- </td>
106
- </tr>
107
- ` ;
150
+ for ( const [ pkgKey , pkg ] of packagesFiles . entries ( ) ) {
151
+ output += `<tr><td colspan="3"><a href="${ pkg . meta . url } "><b>${ pkgKey } </b></a></td></tr>` ;
152
+ for ( const file of pkg . files ) {
153
+ output += `<tr>
154
+ <td><a href="${ file . meta . fileNameUrl } "><code>${ file . meta . fileNameShort } </code></a></td>
155
+ ` ;
156
+ output += file . state === 'added'
157
+ ? `<td><em>Added</em></td>`
158
+ : `<td>
159
+ <code>${ formatBytes ( file . before . size ) } </code> / <code>${ formatBytes ( file . before . sizeGz ) } </code> / <code>${ formatBytes ( file . before . sizeBrotli ) } </code>
160
+ </td>` ;
161
+ output += file . state === 'removed'
162
+ ? `<td><em>Removed</em></td>`
163
+ : `<td>
164
+ <code>${ formatBytes ( file . after . size ) } </code>${ file . state === 'changed' ? `<sup>${ formatDiffPercent ( file . diffPercent . size ) } </sup>` : '' }
165
+ / <code>${ formatBytes ( file . after . sizeGz ) } </code>${ file . state === 'changed' ? `<sup>${ formatDiffPercent ( file . diffPercent . sizeGz ) } </sup>` : '' }
166
+ / <code>${ formatBytes ( file . after . sizeBrotli ) } </code>${ file . state === 'changed' ? `<sup>${ formatDiffPercent ( file . diffPercent . sizeBrotli ) } </sup>` : '' }
167
+ </td>` ;
168
+ output += `</tr>` ;
169
+ }
108
170
}
109
171
output += `</tbody>
110
172
</table>
0 commit comments