Skip to content

Commit 8bcbdd1

Browse files
committed
Add update status and approve PR functions
Fix convert goldens to data
1 parent 8d074a5 commit 8bcbdd1

File tree

14 files changed

+433
-253
lines changed

14 files changed

+433
-253
lines changed

functions/data.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import * as firebaseAdmin from 'firebase-admin';
2+
import {verifySecureTokenAndExecute} from './jwt_util';
3+
4+
/**
5+
* Handle data written to temporary folder. Validate the JWT and move the data out of
6+
* temporary folder if the token is valid.
7+
* Move the data to 'screenshot/reports/$prNumber/$path
8+
*/
9+
export function verifyJWTAndUpdateData(event: any, path: string) {
10+
// Only edit data when it is first created. Exit when the data is deleted.
11+
if (event.data.previous.exists() || !event.data.exists()) {
12+
return;
13+
}
14+
15+
let prNumber = event.params.prNumber;
16+
let data = event.data.val();
17+
18+
return verifySecureTokenAndExecute(event).then(() => {
19+
return firebaseAdmin.database().ref().child('screenshot/reports')
20+
.child(prNumber).child(path).set(data);
21+
});
22+
};

functions/data_image.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as firebaseFunctions from 'firebase-functions';
2+
import {writeFileSync} from 'fs';
3+
import {verifySecureTokenAndExecute} from './jwt_util';
4+
5+
const gcs = require('@google-cloud/storage')();
6+
7+
/** The storage bucket to store the images. The bucket is also used by Firebase Storage. */
8+
const bucket = gcs.bucket(firebaseFunctions.config().firebase.storageBucket);
9+
10+
/**
11+
* Convert data to images. Image data posted to database will be saved as png files
12+
* and upload to screenshot/$prNumber/dataType/$filename
13+
*/
14+
export function convertTestImageDataToFiles(event: any) {
15+
// Only edit data when it is first created. Exit when the data is deleted.
16+
if (event.data.previous.exists() || !event.data.exists()) {
17+
return;
18+
}
19+
20+
let dataType = event.params.dataType;
21+
let prNumber = event.params.prNumber;
22+
let data = event.data.val();
23+
let saveFilename = `${event.params.filename}.screenshot.png`;
24+
25+
if (dataType != 'diff' && dataType != 'test') {
26+
return;
27+
}
28+
29+
return verifySecureTokenAndExecute(event).then(() => {
30+
let tempPath = `/tmp/${dataType}-${saveFilename}`;
31+
let filePath = `screenshots/${prNumber}/${dataType}/${saveFilename}`;
32+
let binaryData = new Buffer(data, 'base64').toString('binary');
33+
writeFileSync(tempPath, binaryData, 'binary');
34+
return bucket.upload(tempPath, {destination: filePath});
35+
});
36+
};

functions/github.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import * as firebaseAdmin from 'firebase-admin';
2+
import * as firebaseFunctions from 'firebase-functions';
3+
import {setGithubStatus} from './util/github';
4+
5+
/** Github status update token */
6+
const token = firebaseFunctions.config().secret.github;
7+
8+
/** The repo slug. This is used to validate the JWT is sent from correct repo. */
9+
const repoSlug = firebaseFunctions.config().repo.slug;
10+
11+
/** Domain to view the screenshots */
12+
const authDomain = firebaseFunctions.config().firebase.authDomain;
13+
14+
/** The same of this screenshot testing tool */
15+
const toolName = firebaseFunctions.config().tool.name;
16+
17+
export function updateGithubStatus(event: firebaseFunctions.Event<any>) {
18+
if (!event.data.exists() || typeof event.data.val() != 'boolean') {
19+
return;
20+
}
21+
let result = event.data.val() == true;
22+
let prNumber = event.params.prNumber;
23+
return event.data.ref.parent.child('sha').once('value').then((sha: firebaseAdmin.database.DataSnapshot) => {
24+
return setGithubStatus(sha.val(),
25+
result,
26+
toolName,
27+
`${toolName} ${result ? 'passed' : 'failed'}`,
28+
`http://${authDomain}/${prNumber}`,
29+
repoSlug,
30+
token);
31+
});
32+
}

functions/image_data.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import * as firebaseFunctions from 'firebase-functions';
2+
import * as firebaseAdmin from 'firebase-admin';
3+
import * as path from 'path';
4+
5+
const gcs = require('@google-cloud/storage')();
6+
7+
const FIREBASE_DATA_GOLDENS = 'screenshot/goldens';
8+
9+
/** The storage bucket to store the images. The bucket is also used by Firebase Storage. */
10+
const bucket = gcs.bucket(firebaseFunctions.config().firebase.storageBucket);
11+
12+
13+
/**
14+
* Read golden files under /goldens/ and store the image data to
15+
* database /screenshot/goldens/$filename
16+
*/
17+
export function convertGoldenImagesToData(name: string, resourceState: string, fileBucket: any) {
18+
// The name should always look like "goldens/xxx.png"
19+
let parsedPath = path.parse(name);
20+
21+
// Get the file name.
22+
if (parsedPath.root != '' || parsedPath.dir != 'goldens' || parsedPath.ext != '.png') {
23+
return;
24+
}
25+
let filenameKey = path.basename(parsedPath.name, '.screenshot');
26+
let databaseRef = firebaseAdmin.database().ref(FIREBASE_DATA_GOLDENS).child(filenameKey);
27+
28+
// When a gold image is deleted, also delete the corresponding record in the firebase database.
29+
if (resourceState === 'not_exists') {
30+
return databaseRef.set(null);
31+
}
32+
33+
let bucket = gcs.bucket(fileBucket);
34+
35+
// Download file from bucket.
36+
return bucket.file(name).download()
37+
.then((data: any) => {
38+
return databaseRef.set(data);
39+
}).catch((error: any) => console.error(`${filenameKey} ${error}`));
40+
};

functions/index.js

Lines changed: 0 additions & 190 deletions
This file was deleted.

0 commit comments

Comments
 (0)