@@ -5,125 +5,115 @@ const gcs = require('@google-cloud/storage')();
55const admin = require ( 'firebase-admin' ) ;
66const jwt = require ( 'jsonwebtoken' ) ;
77const fs = require ( 'fs' ) ;
8+
89admin . initializeApp ( functions . config ( ) . firebase ) ;
910
1011const dataTypes = [ 'filenames' , 'commit' , 'result' , 'results' , 'sha' , 'travis' ] ;
1112const repoSlug = functions . config ( ) . repo . slug ;
1213const secret = functions . config ( ) . secret . key ;
1314const bucket = gcs . bucket ( functions . config ( ) . firebase . storageBucket ) ;
1415
16+ /** Copy valid data from /temp/screenshot/reports/$prNumber/$secureToken/ to /screenshot/reports/$prNumber */
1517exports . copyData = functions . database . ref ( '/temp/screenshot/reports/{prNumber}/{token1}/{token2}/{token3}/{dataType}' )
1618 . onWrite ( event => {
17- // Only edit data when it is first created.
18- if ( event . data . previous . exists ( ) ) {
19- return ;
20- }
21- // Exit when the data is deleted.
22- if ( ! event . data . exists ( ) ) {
23- return ;
24- }
25-
26- const dataType = event . params . dataType ;
27- const prNumber = event . params . prNumber ;
28- const secureToken = `${ event . params . token1 } .${ event . params . token2 } .${ event . params . token3 } ` ;
29- const original = event . data . val ( ) ;
30-
31- if ( ! dataTypes . includes ( dataType ) ) {
32- console . log ( `Invalid data ${ dataType } ` ) ;
33- return ;
34- }
35-
36- return validateSecureToken ( secureToken , prNumber ) . then ( ( payload ) => {
37- console . log ( `Log ${ original } to screenshot/reports/${ prNumber } /filenames` ) ;
38- return admin . database ( ) . ref ( ) . child ( 'screenshot/reports' ) . child ( prNumber ) . child ( dataType ) . set ( original ) . then ( ( ) => {
19+ // Only edit data when it is first created. Exit when the data is deleted.
20+ if ( event . data . previous . exists ( ) || ! event . data . exists ( ) ) {
21+ return ;
22+ }
23+
24+ const dataType = event . params . dataType ;
25+ const prNumber = event . params . prNumber ;
26+ const secureToken = `${ event . params . token1 } .${ event . params . token2 } .${ event . params . token3 } ` ;
27+ const original = event . data . val ( ) ;
28+
29+ if ( ! dataTypes . includes ( dataType ) ) {
30+ return ;
31+ }
32+
33+ return validateSecureToken ( secureToken , prNumber ) . then ( ( payload ) => {
34+ return admin . database ( ) . ref ( ) . child ( 'screenshot/reports' ) . child ( prNumber ) . child ( dataType ) . set ( original ) . then ( ( ) => {
3935 return event . data . ref . parent . set ( null ) ;
40- } ) ;
41- } ) . catch ( ( error ) => {
42- console . log ( `Invalid secure token ${ secureToken } ${ error } ` ) ;
43- return event . data . ref . parent . set ( null ) ;
44- } )
45-
36+ } ) ;
37+ } ) . catch ( ( error ) => {
38+ console . log ( `Invalid secure token ${ secureToken } ${ error } ` ) ;
39+ return event . data . ref . parent . set ( null ) ;
4640 } ) ;
41+ } ) ;
4742
43+ /** Copy valid data from database /temp/screenshot/images/$prNumber/$secureToken/ to storage /screenshots/$prNumber */
4844exports . copyImage = functions . database . ref ( '/temp/screenshot/images/{prNumber}/{token1}/{token2}/{token3}/{dataType}/{filename}' )
4945 . onWrite ( event => {
50- // Only edit data when it is first created.
51- if ( event . data . previous . exists ( ) ) {
52- return ;
53- }
54- // Exit when the data is deleted.
55- if ( ! event . data . exists ( ) ) {
56- return ;
57- }
58-
59- const dataType = event . params . dataType ;
60- const prNumber = event . params . prNumber ;
61- const secureToken = `${ event . params . token1 } .${ event . params . token2 } .${ event . params . token3 } ` ;
62- const saveFilename = `${ event . params . filename } .screenshot.png` ;
63-
64- if ( dataType != 'diff' && dataType != 'test' ) {
65- return ;
66- }
67-
68- return validateSecureToken ( secureToken , prNumber ) . then ( ( payload ) => {
46+ // Only edit data when it is first created. Exit when the data is deleted.
47+ if ( event . data . previous . exists ( ) || ! event . data . exists ( ) ) {
48+ return ;
49+ }
50+
51+ const dataType = event . params . dataType ;
52+ const prNumber = event . params . prNumber ;
53+ const secureToken = `${ event . params . token1 } .${ event . params . token2 } .${ event . params . token3 } ` ;
54+ const saveFilename = `${ event . params . filename } .screenshot.png` ;
55+
56+ if ( dataType != 'diff' && dataType != 'test' ) {
57+ return ;
58+ }
59+
60+ return validateSecureToken ( secureToken , prNumber ) . then ( ( payload ) => {
6961 const tempPath = `/tmp/${ dataType } -${ saveFilename } `
7062 const filePath = `screenshots/${ prNumber } /${ dataType } /${ saveFilename } ` ;
7163 const binaryData = new Buffer ( event . data . val ( ) , 'base64' ) . toString ( 'binary' ) ;
7264 fs . writeFile ( tempPath , binaryData , 'binary' ) ;
7365 return bucket . upload ( tempPath , {
74- destination : filePath
75- } ) . then ( ( ) => {
76- return event . data . ref . parent . set ( null ) ;
66+ destination : filePath
67+ } ) . then ( ( ) => {
68+ return event . data . ref . parent . set ( null ) ;
7769 } ) ;
78- } ) . catch ( ( error ) => {
79- console . log ( `Invalid secure token ${ secureToken } ${ error } ` ) ;
80- return event . data . ref . parent . set ( null ) ;
81- } ) ;
70+ } ) . catch ( ( error ) => {
71+ console . log ( `Invalid secure token ${ secureToken } ${ error } ` ) ;
72+ return event . data . ref . parent . set ( null ) ;
8273 } ) ;
74+ } ) ;
8375
76+ /**
77+ * Copy valid goldens from storage /goldens/ to database /screenshot/goldens/
78+ * so we can read the goldens without credentials
79+ */
8480exports . copyGoldens = functions . storage . bucket ( functions . config ( ) . firebase . storageBucket ) . object ( ) . onChange ( event => {
85- const object = event . data ;
86- const fileBucket = object . bucket ;
87- const filePath = object . name ;
88- const contentType = object . contentType ; // File content type.
89- const resourceState = object . resourceState ;
90-
91- // Get the file name.
92- const fileNames = filePath . split ( '/' ) ;
93- if ( fileNames . length != 2 && fileNames [ 0 ] != 'golds' ) {
94- return ;
95- }
96-
97- const filenameKey = fileNames [ 1 ] . replace ( '.screenshot.png' , '' ) ;
98- // Exit if this is a move or deletion event.
99- if ( resourceState === 'not_exists' ) {
100- console . log ( 'This is a deletion event.' ) ;
101- return admin . database ( ) . ref ( `screenshot/goldens/${ filenameKey } ` ) . set ( null ) ;
102- }
103-
104- // Download file from bucket.
105- const bucket = gcs . bucket ( fileBucket ) ;
106- const tempFilePath = `/tmp/${ fileNames [ 1 ] } ` ;
107- return bucket . file ( filePath ) . download ( {
108- destination : tempFilePath
109- } ) . then ( ( ) => {
110- const data = fs . readFileSync ( tempFilePath ) ;
111- return admin . database ( ) . ref ( `screenshot/goldens/${ filenameKey } ` ) . set ( data ) ;
112- } ) ;
81+ const filePath = event . data . name ;
82+
83+ // Get the file name.
84+ const fileNames = filePath . split ( '/' ) ;
85+ if ( fileNames . length != 2 && fileNames [ 0 ] != 'goldens' ) {
86+ return ;
87+ }
88+ const filenameKey = fileNames [ 1 ] . replace ( '.screenshot.png' , '' ) ;
89+
90+ if ( event . data . resourceState === 'not_exists' ) {
91+ return admin . database ( ) . ref ( `screenshot/goldens/${ filenameKey } ` ) . set ( null ) ;
92+ }
93+
94+ // Download file from bucket.
95+ const bucket = gcs . bucket ( event . data . bucket ) ;
96+ const tempFilePath = `/tmp/${ fileNames [ 1 ] } ` ;
97+ return bucket . file ( filePath ) . download ( {
98+ destination : tempFilePath
99+ } ) . then ( ( ) => {
100+ const data = fs . readFileSync ( tempFilePath ) ;
101+ return admin . database ( ) . ref ( `screenshot/goldens/${ filenameKey } ` ) . set ( data ) ;
102+ } ) ;
113103} ) ;
114104
115105function validateSecureToken ( token , prNumber ) {
116106 return new Promise ( ( resolve , reject ) => {
117- jwt . verify ( token , secret , { issuer : 'Travis CI, GmbH' } , ( err , payload ) => {
118- if ( err ) {
119- reject ( err . message || err ) ;
120- } else if ( payload . slug !== repoSlug ) {
121- reject ( `jwt slug invalid. expected: ${ repoSlug } ` ) ;
122- } else if ( payload [ 'pull-request' ] . toString ( ) !== prNumber ) {
123- reject ( `jwt pull-request invalid. expected: ${ prNumber } actual: ${ payload [ 'pull-request' ] } ` ) ;
124- } else {
125- resolve ( payload ) ;
126- }
127- } ) ;
107+ jwt . verify ( token , secret , { issuer : 'Travis CI, GmbH' } , ( err , payload ) => {
108+ if ( err ) {
109+ reject ( err . message || err ) ;
110+ } else if ( payload . slug !== repoSlug ) {
111+ reject ( `jwt slug invalid. expected: ${ repoSlug } ` ) ;
112+ } else if ( payload [ 'pull-request' ] . toString ( ) !== prNumber ) {
113+ reject ( `jwt pull-request invalid. expected: ${ prNumber } actual: ${ payload [ 'pull-request' ] } ` ) ;
114+ } else {
115+ resolve ( payload ) ;
116+ }
117+ } ) ;
128118 } ) ;
129119}
0 commit comments