@@ -20,206 +20,237 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
20
SOFTWARE.
21
21
*/
22
22
23
- const { setFailed, startGroup, endGroup, debug } = require ( '@actions/core' ) ;
24
- const { GitHub, context } = require ( '@actions/github' ) ;
25
- const { exec } = require ( '@actions/exec' ) ;
26
- const { getInput, runBenchmark, averageBenchmarks, toDiff, diffTable, toBool } = require ( './utils.js' ) ;
23
+ const { setFailed, startGroup, endGroup, debug } = require ( "@actions/core" ) ;
24
+ const { GitHub, context } = require ( "@actions/github" ) ;
25
+ const { exec } = require ( "@actions/exec" ) ;
26
+ const {
27
+ getInput,
28
+ runBenchmark,
29
+ averageBenchmarks,
30
+ toDiff,
31
+ diffTable,
32
+ toBool,
33
+ } = require ( "./utils.js" ) ;
34
+
35
+ const benchmarkParallel = 2 ;
36
+ const benchmarkSerial = 2 ;
37
+ const runBenchmarks = async ( ) => {
38
+ let results = [ ] ;
39
+ for ( let i = 0 ; i < benchmarkSerial ; i ++ ) {
40
+ results = results . concat (
41
+ await Promise . all ( Array ( benchmarkParallel ) . fill ( ) . map ( runBenchmark ) )
42
+ ) ;
43
+ }
44
+ return averageBenchmarks ( results ) ;
45
+ } ;
27
46
28
47
async function run ( octokit , context , token ) {
29
- const { number : pull_number } = context . issue ;
30
-
31
- const pr = context . payload . pull_request ;
32
- try {
33
- debug ( 'pr' + JSON . stringify ( pr , null , 2 ) ) ;
34
- } catch ( e ) { }
35
- if ( ! pr ) {
36
- throw Error ( 'Could not retrieve PR information. Only "pull_request" triggered workflows are currently supported.' ) ;
37
- }
38
-
39
- console . log ( `PR #${ pull_number } is targetted at ${ pr . base . ref } (${ pr . base . sha } )` ) ;
40
-
41
- const buildScript = getInput ( 'build-script' ) ;
42
- startGroup ( `[current] Build using '${ buildScript } '` ) ;
43
- await exec ( buildScript ) ;
44
- endGroup ( ) ;
45
-
46
- startGroup ( `[current] Running benchmark` ) ;
47
- const newBenchmarks = await Promise . all ( [ runBenchmark ( ) , runBenchmark ( ) ] ) . then ( averageBenchmarks ) ;
48
- endGroup ( ) ;
49
-
50
- startGroup ( `[base] Checkout target branch` ) ;
51
- let baseRef ;
52
- try {
53
- baseRef = context . payload . base . ref ;
54
- if ( ! baseRef ) throw Error ( 'missing context.payload.pull_request.base.ref' ) ;
55
- await exec ( `git fetch -n origin ${ context . payload . pull_request . base . ref } ` ) ;
56
- console . log ( 'successfully fetched base.ref' ) ;
57
- } catch ( e ) {
58
- console . log ( 'fetching base.ref failed' , e . message ) ;
59
- try {
60
- await exec ( `git fetch -n origin ${ pr . base . sha } ` ) ;
61
- console . log ( 'successfully fetched base.sha' ) ;
62
- } catch ( e ) {
63
- console . log ( 'fetching base.sha failed' , e . message ) ;
64
- try {
65
- await exec ( `git fetch -n` ) ;
66
- } catch ( e ) {
67
- console . log ( 'fetch failed' , e . message ) ;
68
- }
69
- }
70
- }
71
-
72
- console . log ( 'checking out and building base commit' ) ;
73
- try {
74
- if ( ! baseRef ) throw Error ( 'missing context.payload.base.ref' ) ;
75
- await exec ( `git reset --hard ${ baseRef } ` ) ;
76
- }
77
- catch ( e ) {
78
- await exec ( `git reset --hard ${ pr . base . sha } ` ) ;
79
- }
80
- endGroup ( ) ;
81
-
82
- startGroup ( `[base] Build using '${ buildScript } '` ) ;
83
- await exec ( buildScript ) ;
84
- endGroup ( ) ;
85
-
86
- startGroup ( `[base] Running benchmark` ) ;
87
- const oldBenchmarks = await Promise . all ( [ runBenchmark ( ) , runBenchmark ( ) ] ) . then ( averageBenchmarks ) ;
88
- endGroup ( ) ;
89
-
90
- const diff = toDiff ( oldBenchmarks , newBenchmarks ) ;
91
-
92
- const markdownDiff = diffTable ( diff , {
93
- collapseUnchanged : true ,
94
- omitUnchanged : false ,
95
- showTotal : true ,
96
- minimumChangeThreshold : parseInt ( getInput ( 'minimum-change-threshold' ) , 10 )
97
- } ) ;
98
-
99
- let outputRawMarkdown = false ;
100
-
101
- const commentInfo = {
102
- ...context . repo ,
103
- issue_number : pull_number
104
- } ;
105
-
106
- const comment = {
107
- ...commentInfo ,
108
- body : markdownDiff + '\n\n<a href="https://github.com/j-f1/performance-action"><sub>performance-action</sub></a>'
109
- } ;
110
-
111
- if ( toBool ( getInput ( 'use-check' ) ) ) {
112
- if ( token ) {
113
- const finish = await createCheck ( octokit , context ) ;
114
- await finish ( {
115
- conclusion : 'success' ,
116
- output : {
117
- title : `Compressed Size Action` ,
118
- summary : markdownDiff
119
- }
120
- } ) ;
121
- }
122
- else {
123
- outputRawMarkdown = true ;
124
- }
125
- }
126
- else {
127
- startGroup ( `Updating stats PR comment` ) ;
128
- let commentId ;
129
- try {
130
- const comments = ( await octokit . issues . listComments ( commentInfo ) ) . data ;
131
- for ( let i = comments . length ; i -- ; ) {
132
- const c = comments [ i ] ;
133
- if ( c . user . type === 'Bot' && / < s u b > [ \s \n ] * p e r f o r m a n c e - a c t i o n / . test ( c . body ) ) {
134
- commentId = c . id ;
135
- break ;
136
- }
137
- }
138
- }
139
- catch ( e ) {
140
- console . log ( 'Error checking for previous comments: ' + e . message ) ;
141
- }
142
-
143
- if ( commentId ) {
144
- console . log ( `Updating previous comment #${ commentId } ` )
145
- try {
146
- await octokit . issues . updateComment ( {
147
- ...context . repo ,
148
- comment_id : commentId ,
149
- body : comment . body
150
- } ) ;
151
- }
152
- catch ( e ) {
153
- console . log ( 'Error editing previous comment: ' + e . message ) ;
154
- commentId = null ;
155
- }
156
- }
157
-
158
- // no previous or edit failed
159
- if ( ! commentId ) {
160
- console . log ( 'Creating new comment' ) ;
161
- try {
162
- await octokit . issues . createComment ( comment ) ;
163
- } catch ( e ) {
164
- console . log ( `Error creating comment: ${ e . message } ` ) ;
165
- console . log ( `Submitting a PR review comment instead...` ) ;
166
- try {
167
- const issue = context . issue || pr ;
168
- await octokit . pulls . createReview ( {
169
- owner : issue . owner ,
170
- repo : issue . repo ,
171
- pull_number : issue . number ,
172
- event : 'COMMENT' ,
173
- body : comment . body
174
- } ) ;
175
- } catch ( e ) {
176
- console . log ( 'Error creating PR review.' ) ;
177
- outputRawMarkdown = true ;
178
- }
179
- }
180
- }
181
- endGroup ( ) ;
182
- }
183
-
184
- if ( outputRawMarkdown ) {
185
- console . log ( `
48
+ const { number : pull_number } = context . issue ;
49
+
50
+ const pr = context . payload . pull_request ;
51
+ try {
52
+ debug ( "pr" + JSON . stringify ( pr , null , 2 ) ) ;
53
+ } catch ( e ) { }
54
+ if ( ! pr ) {
55
+ throw Error (
56
+ 'Could not retrieve PR information. Only "pull_request" triggered workflows are currently supported.'
57
+ ) ;
58
+ }
59
+
60
+ console . log (
61
+ `PR #${ pull_number } is targetted at ${ pr . base . ref } (${ pr . base . sha } )`
62
+ ) ;
63
+
64
+ const buildScript = getInput ( "build-script" ) ;
65
+ startGroup ( `[current] Build using '${ buildScript } '` ) ;
66
+ await exec ( buildScript ) ;
67
+ endGroup ( ) ;
68
+
69
+ startGroup ( `[current] Running benchmark` ) ;
70
+ const newBenchmarks = await runBenchmarks ( ) ;
71
+ endGroup ( ) ;
72
+
73
+ startGroup ( `[base] Checkout target branch` ) ;
74
+ let baseRef ;
75
+ try {
76
+ baseRef = context . payload . base . ref ;
77
+ if ( ! baseRef )
78
+ throw Error ( "missing context.payload.pull_request.base.ref" ) ;
79
+ await exec (
80
+ `git fetch -n origin ${ context . payload . pull_request . base . ref } `
81
+ ) ;
82
+ console . log ( "successfully fetched base.ref" ) ;
83
+ } catch ( e ) {
84
+ console . log ( "fetching base.ref failed" , e . message ) ;
85
+ try {
86
+ await exec ( `git fetch -n origin ${ pr . base . sha } ` ) ;
87
+ console . log ( "successfully fetched base.sha" ) ;
88
+ } catch ( e ) {
89
+ console . log ( "fetching base.sha failed" , e . message ) ;
90
+ try {
91
+ await exec ( `git fetch -n` ) ;
92
+ } catch ( e ) {
93
+ console . log ( "fetch failed" , e . message ) ;
94
+ }
95
+ }
96
+ }
97
+
98
+ console . log ( "checking out and building base commit" ) ;
99
+ try {
100
+ if ( ! baseRef ) throw Error ( "missing context.payload.base.ref" ) ;
101
+ await exec ( `git reset --hard ${ baseRef } ` ) ;
102
+ } catch ( e ) {
103
+ await exec ( `git reset --hard ${ pr . base . sha } ` ) ;
104
+ }
105
+ endGroup ( ) ;
106
+
107
+ startGroup ( `[base] Build using '${ buildScript } '` ) ;
108
+ await exec ( buildScript ) ;
109
+ endGroup ( ) ;
110
+
111
+ startGroup ( `[base] Running benchmark` ) ;
112
+ const oldBenchmarks = await runBenchmarks ( ) ;
113
+ endGroup ( ) ;
114
+
115
+ const diff = toDiff ( oldBenchmarks , newBenchmarks ) ;
116
+
117
+ const markdownDiff = diffTable ( diff , {
118
+ collapseUnchanged : true ,
119
+ omitUnchanged : false ,
120
+ showTotal : true ,
121
+ minimumChangeThreshold : parseInt (
122
+ getInput ( "minimum-change-threshold" ) ,
123
+ 10
124
+ ) ,
125
+ } ) ;
126
+
127
+ let outputRawMarkdown = false ;
128
+
129
+ const commentInfo = {
130
+ ...context . repo ,
131
+ issue_number : pull_number ,
132
+ } ;
133
+
134
+ const comment = {
135
+ ...commentInfo ,
136
+ body :
137
+ markdownDiff +
138
+ '\n\n<a href="https://github.com/j-f1/performance-action"><sub>performance-action</sub></a>' ,
139
+ } ;
140
+
141
+ if ( toBool ( getInput ( "use-check" ) ) ) {
142
+ if ( token ) {
143
+ const finish = await createCheck ( octokit , context ) ;
144
+ await finish ( {
145
+ conclusion : "success" ,
146
+ output : {
147
+ title : `Compressed Size Action` ,
148
+ summary : markdownDiff ,
149
+ } ,
150
+ } ) ;
151
+ } else {
152
+ outputRawMarkdown = true ;
153
+ }
154
+ } else {
155
+ startGroup ( `Updating stats PR comment` ) ;
156
+ let commentId ;
157
+ try {
158
+ const comments = ( await octokit . issues . listComments ( commentInfo ) )
159
+ . data ;
160
+ for ( let i = comments . length ; i -- ; ) {
161
+ const c = comments [ i ] ;
162
+ if (
163
+ c . user . type === "Bot" &&
164
+ / < s u b > [ \s \n ] * p e r f o r m a n c e - a c t i o n / . test ( c . body )
165
+ ) {
166
+ commentId = c . id ;
167
+ break ;
168
+ }
169
+ }
170
+ } catch ( e ) {
171
+ console . log ( "Error checking for previous comments: " + e . message ) ;
172
+ }
173
+
174
+ if ( commentId ) {
175
+ console . log ( `Updating previous comment #${ commentId } ` ) ;
176
+ try {
177
+ await octokit . issues . updateComment ( {
178
+ ...context . repo ,
179
+ comment_id : commentId ,
180
+ body : comment . body ,
181
+ } ) ;
182
+ } catch ( e ) {
183
+ console . log ( "Error editing previous comment: " + e . message ) ;
184
+ commentId = null ;
185
+ }
186
+ }
187
+
188
+ // no previous or edit failed
189
+ if ( ! commentId ) {
190
+ console . log ( "Creating new comment" ) ;
191
+ try {
192
+ await octokit . issues . createComment ( comment ) ;
193
+ } catch ( e ) {
194
+ console . log ( `Error creating comment: ${ e . message } ` ) ;
195
+ console . log ( `Submitting a PR review comment instead...` ) ;
196
+ try {
197
+ const issue = context . issue || pr ;
198
+ await octokit . pulls . createReview ( {
199
+ owner : issue . owner ,
200
+ repo : issue . repo ,
201
+ pull_number : issue . number ,
202
+ event : "COMMENT" ,
203
+ body : comment . body ,
204
+ } ) ;
205
+ } catch ( e ) {
206
+ console . log ( "Error creating PR review." ) ;
207
+ outputRawMarkdown = true ;
208
+ }
209
+ }
210
+ }
211
+ endGroup ( ) ;
212
+ }
213
+
214
+ if ( outputRawMarkdown ) {
215
+ console . log (
216
+ `
186
217
Error: performance-action was unable to comment on your PR.
187
218
This can happen for PR's originating from a fork without write permissions.
188
219
You can copy the size table directly into a comment using the markdown below:
189
220
\n\n${ comment . body } \n\n
190
- ` . replace ( / ^ ( \t | ) + / gm, '' ) ) ;
191
- }
221
+ ` . replace ( / ^ ( \t | ) + / gm, "" )
222
+ ) ;
223
+ }
192
224
193
- console . log ( ' All done!' ) ;
225
+ console . log ( " All done!" ) ;
194
226
}
195
227
196
-
197
228
// create a check and return a function that updates (completes) it
198
229
async function createCheck ( octokit , context ) {
199
- const check = await octokit . checks . create ( {
200
- ...context . repo ,
201
- name : ' Compressed Size' ,
202
- head_sha : context . payload . pull_request . head . sha ,
203
- status : ' in_progress' ,
204
- } ) ;
205
-
206
- return async details => {
207
- await octokit . checks . update ( {
208
- ...context . repo ,
209
- check_run_id : check . data . id ,
210
- completed_at : new Date ( ) . toISOString ( ) ,
211
- status : ' completed' ,
212
- ...details
213
- } ) ;
214
- } ;
230
+ const check = await octokit . checks . create ( {
231
+ ...context . repo ,
232
+ name : " Compressed Size" ,
233
+ head_sha : context . payload . pull_request . head . sha ,
234
+ status : " in_progress" ,
235
+ } ) ;
236
+
237
+ return async ( details ) => {
238
+ await octokit . checks . update ( {
239
+ ...context . repo ,
240
+ check_run_id : check . data . id ,
241
+ completed_at : new Date ( ) . toISOString ( ) ,
242
+ status : " completed" ,
243
+ ...details ,
244
+ } ) ;
245
+ } ;
215
246
}
216
247
217
248
( async ( ) => {
218
- try {
219
- const token = getInput ( ' repo-token' , { required : true } ) ;
220
- const octokit = new GitHub ( token ) ;
221
- await run ( octokit , context , token ) ;
222
- } catch ( e ) {
223
- setFailed ( e . message ) ;
224
- }
249
+ try {
250
+ const token = getInput ( " repo-token" , { required : true } ) ;
251
+ const octokit = new GitHub ( token ) ;
252
+ await run ( octokit , context , token ) ;
253
+ } catch ( e ) {
254
+ setFailed ( e . message ) ;
255
+ }
225
256
} ) ( ) ;
0 commit comments