Skip to content

Commit debd056

Browse files
authored
Merge 768ac9f into afaf982
2 parents afaf982 + 768ac9f commit debd056

File tree

4 files changed

+197
-15
lines changed

4 files changed

+197
-15
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: Health Metrics
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
binary-size-test:
7+
name: Binary Size
8+
runs-on: ubuntu-latest
9+
env:
10+
METRICS_SERVICE_URL: ${{ secrets.METRICS_SERVICE_URL }}
11+
GITHUB_PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
12+
GITHUB_PULL_REQUEST_BASE_SHA: ${{ github.event.pull_request.base.sha }}
13+
steps:
14+
- uses: actions/checkout@v2
15+
- uses: actions/setup-node@v1
16+
with:
17+
node-version: 10.x
18+
- uses: GoogleCloudPlatform/github-actions/setup-gcloud@master
19+
with:
20+
service_account_key: ${{ secrets.GCP_SA_KEY }}
21+
- run: cp config/ci.config.json config/project.json
22+
- run: yarn install
23+
- run: yarn build
24+
25+
- name: Run health-metrics/binary-size test
26+
run: yarn size-report
27+
28+
# TODO(yifany): Enable startup times testing on CI.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@
3636
"docgen:node": "node scripts/docgen/generate-docs.js --api node",
3737
"docgen": "yarn docgen:js; yarn docgen:node",
3838
"prettier": "prettier --config .prettierrc --write '**/*.{ts,js}'",
39-
"lint": "lerna run --scope @firebase/* --scope rxfire lint"
39+
"lint": "lerna run --scope @firebase/* --scope rxfire lint",
40+
"size-report": "node scripts/report_binary_size.js"
4041
},
4142
"repository": {
4243
"type": "git",
@@ -120,7 +121,8 @@
120121
"watch": "1.0.2",
121122
"webpack": "4.42.0",
122123
"yargs": "15.3.1",
123-
"lodash": "4.17.15"
124+
"lodash": "4.17.15",
125+
"terser": "4.6.7"
124126
},
125127
"husky": {
126128
"hooks": {

scripts/report_binary_size.js

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
const { resolve } = require('path');
2+
const fs = require('fs');
3+
const { execSync } = require('child_process');
4+
const https = require('https');
5+
const terser = require('terser');
6+
7+
const repoRoot = resolve(__dirname, '..');
8+
9+
const runId = process.env.GITHUB_RUN_ID || 'local-run-id';
10+
11+
const METRICS_SERVICE_URL = process.env.METRICS_SERVICE_URL;
12+
13+
// CDN scripts
14+
function generateReportForCDNScripts() {
15+
const reports = [];
16+
const firebaseRoot = resolve(__dirname, '../packages/firebase');
17+
const pkgJson = require(`${firebaseRoot}/package.json`);
18+
19+
const special_files = [
20+
'firebase-performance-standalone.es2017.js',
21+
'firebase-performance-standalone.js',
22+
'firebase.js'
23+
];
24+
25+
const files = [
26+
...special_files.map(file => `${firebaseRoot}/${file}`),
27+
...pkgJson.components.map(component => `${firebaseRoot}/firebase-${component}.js`)
28+
];
29+
30+
for (const file of files) {
31+
const { size } = fs.statSync(file);
32+
const fileName = file.split('/').slice(-1)[0];
33+
reports.push(makeReportObject('firebase', fileName, size));
34+
}
35+
36+
return reports;
37+
}
38+
39+
// NPM packages
40+
function generateReportForNPMPackages() {
41+
const reports = [];
42+
const fields = [
43+
'main',
44+
'module',
45+
'esm2017',
46+
'browser',
47+
'react-native',
48+
'lite',
49+
'lite-esm2017'
50+
];
51+
52+
const packageInfo = JSON.parse(
53+
execSync('npx lerna ls --json --scope @firebase/*', { cwd: repoRoot }).toString()
54+
);
55+
56+
for (const package of packageInfo) {
57+
const packageJson = require(`${package.location}/package.json`);
58+
59+
for (const field of fields) {
60+
if (packageJson[field]) {
61+
const filePath = `${package.location}/${packageJson[field]}`;
62+
63+
const rawCode = fs.readFileSync(filePath, 'utf-8');
64+
65+
// remove comments and whitespaces, then get size
66+
const { code } = terser.minify(rawCode, {
67+
output: {
68+
comments: false
69+
},
70+
mangle: false,
71+
compress: false
72+
});
73+
74+
const size = Buffer.byteLength(code, 'utf-8')
75+
reports.push(makeReportObject(packageJson.name, field, size));
76+
}
77+
}
78+
}
79+
80+
return reports;
81+
}
82+
83+
function makeReportObject(sdk, type, value) {
84+
return {
85+
sdk,
86+
type,
87+
value
88+
};
89+
}
90+
91+
function generateSizeReport() {
92+
const reports = [
93+
...generateReportForCDNScripts(),
94+
...generateReportForNPMPackages()
95+
];
96+
97+
for (const r of reports) {
98+
console.log(r.sdk, r.type, r.value);
99+
}
100+
101+
console.log(`Github Action URL: https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${runId}`);
102+
103+
return {
104+
log: `https://github.com/${process.env.GITHUB_REPOSITORY}/actions/runs/${runId}`,
105+
metric: "BinarySize",
106+
results: reports
107+
};
108+
}
109+
110+
function constructRequestPath() {
111+
const repo = process.env.GITHUB_REPOSITORY;
112+
const commit = process.env.GITHUB_SHA;
113+
let path = `/repos/${repo}/commits/${commit}/reports`;
114+
if (process.env.GITHUB_EVENT_NAME === 'pull_request') {
115+
const pullRequestNumber = process.env.GITHUB_PULL_REQUEST_NUMBER;
116+
const pullRequestBaseSha = process.env.GITHUB_PULL_REQUEST_BASE_SHA;
117+
path += `?pull_request=${pullRequestNumber}&base_commit=${pullRequestBaseSha}`;
118+
}
119+
return path;
120+
}
121+
122+
function constructRequestOptions(path) {
123+
const accessToken = execSync('gcloud auth print-identity-token', { encoding: 'utf8' }).trim();
124+
return {
125+
path: path,
126+
method: 'POST',
127+
headers: {
128+
'Authorization': `Bearer ${accessToken}`,
129+
'Content-Type': 'application/json'
130+
}
131+
};
132+
}
133+
134+
function upload(report) {
135+
if (!process.env.GITHUB_ACTIONS) {
136+
console.log('Metrics upload is only enabled on CI.');
137+
return;
138+
}
139+
140+
const path = constructRequestPath();
141+
const options = constructRequestOptions(path);
142+
143+
console.log(`${report.metric} report:`, report);
144+
console.log(`Posting to metrics service endpoint: ${path} ...`);
145+
146+
const request = https.request(METRICS_SERVICE_URL, options, response => {
147+
response.setEncoding('utf8');
148+
console.log(`Response status code: ${response.statusCode}`);
149+
response.on('data', console.log);
150+
response.on('end', () => {
151+
if (response.statusCode !== 202) {
152+
process.exit(1);
153+
}
154+
})
155+
});
156+
request.write(JSON.stringify(report));
157+
request.end();
158+
}
159+
160+
const report = generateSizeReport();
161+
upload(report);

yarn.lock

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13986,19 +13986,10 @@ terser-webpack-plugin@^1.4.3:
1398613986
webpack-sources "^1.4.0"
1398713987
worker-farm "^1.7.0"
1398813988

13989-
terser@^4.1.2:
13990-
version "4.3.8"
13991-
resolved "https://registry.npmjs.org/terser/-/terser-4.3.8.tgz#707f05f3f4c1c70c840e626addfdb1c158a17136"
13992-
integrity sha512-otmIRlRVmLChAWsnSFNO0Bfk6YySuBp6G9qrHiJwlLDd4mxe2ta4sjI7TzIR+W1nBMjilzrMcPOz9pSusgx3hQ==
13993-
dependencies:
13994-
commander "^2.20.0"
13995-
source-map "~0.6.1"
13996-
source-map-support "~0.5.12"
13997-
13998-
terser@^4.6.2:
13999-
version "4.6.6"
14000-
resolved "https://registry.npmjs.org/terser/-/terser-4.6.6.tgz#da2382e6cafbdf86205e82fb9a115bd664d54863"
14001-
integrity sha512-4lYPyeNmstjIIESr/ysHg2vUPRGf2tzF9z2yYwnowXVuVzLEamPN1Gfrz7f8I9uEPuHcbFlW4PLIAsJoxXyJ1g==
13989+
[email protected], terser@^4.1.2, terser@^4.6.2:
13990+
version "4.6.7"
13991+
resolved "https://registry.npmjs.org/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72"
13992+
integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==
1400213993
dependencies:
1400313994
commander "^2.20.0"
1400413995
source-map "~0.6.1"

0 commit comments

Comments
 (0)