-
Notifications
You must be signed in to change notification settings - Fork 201
172 lines (144 loc) · 6.48 KB
/
Copy pathbundle-size.yml
File metadata and controls
172 lines (144 loc) · 6.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
name: Bundle Size Tracking
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
bundle-size:
runs-on: ubuntu-latest
env:
EXPO_PUBLIC_API_BASE_URL: https://api.teachlink.com
EXPO_PUBLIC_SOCKET_URL: wss://api.teachlink.com
EXPO_PUBLIC_APP_ENV: production
EXPO_PUBLIC_ENABLE_PUSH_NOTIFICATIONS: true
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- name: Install dependencies
run: npm install
- name: Build web bundle with stats
run: npx expo export --platform web --output-dir ./dist --stats-output ./dist/stats.json
- name: Upload bundle stats artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: bundle-stats-${{ github.sha }}
path: ./dist/stats.json
retention-days: 7
- name: Store bundle size history
if: github.ref == 'refs/heads/main'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
const { Octokit } = require("@octokit/rest");
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
const owner = context.repo.owner;
const repo = context.repo.repo;
const historyFile = 'bundle-size-history.json';
let history = [];
try {
const { data: artifact } = await octokit.actions.listArtifactsForRepo({
owner,
repo,
name: 'bundle-size-history',
}).then(res => res.data.artifacts[0]);
if (artifact) {
const download = await octokit.actions.downloadArtifact({
owner,
repo,
artifact_id: artifact.id,
archive_format: 'zip',
});
const AdmZip = require('adm-zip');
const zip = new AdmZip(Buffer.from(download.data));
history = JSON.parse(zip.readAsText(historyFile));
}
} catch (error) {
console.log('No existing history artifact found, creating a new one.');
}
const stats = JSON.parse(fs.readFileSync('./dist/stats.json', 'utf8'));
const totalSize = stats.assets.reduce((sum, a) => sum + a.size, 0);
history.push({
sha: context.sha,
date: new Date().toISOString(),
totalSize,
assets: stats.assets.map(a => ({ name: a.name, size: a.size })),
});
fs.writeFileSync(historyFile, JSON.stringify(history, null, 2));
- name: Upload bundle size history
if: github.ref == 'refs/heads/main'
uses: actions/upload-artifact@v4
with:
name: bundle-size-history
path: bundle-size-history.json
retention-days: 90
- name: Download base branch bundle size
if: github.event_name == 'pull_request'
uses: actions/download-artifact@v4
with:
name: bundle-stats-${{ github.event.pull_request.base.sha }}
path: ./base-bundle
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.pull_request.base.repo.id }}-${{ github.event.pull_request.base.sha }}
- name: Compare bundle sizes and comment
if: github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const path = require('path');
function parseStats(filePath) {
if (!fs.existsSync(filePath)) return null;
const stats = JSON.parse(fs.readFileSync(filePath, 'utf8'));
const mainBundle = stats.assets.find(a => a.name === 'main.js');
return {
totalSize: stats.assets.reduce((sum, a) => sum + a.size, 0),
mainBundleSize: mainBundle ? mainBundle.size : 0,
assets: stats.assets,
};
}
const baseStats = parseStats('./base-bundle/stats.json');
const headStats = parseStats('./dist/stats.json');
if (!headStats) {
console.log('Could not find head bundle stats. Skipping comparison.');
return;
}
let body = `## 📦 Bundle Size Report\n\n`;
body += `| Asset | Size (KB) |\n`;
body += `|---|---|\n`;
headStats.assets.forEach(asset => {
body += `| ${asset.name} | ${(asset.size / 1024).toFixed(2)} |\n`;
});
body += `| **Total** | **${(headStats.totalSize / 1024).toFixed(2)}** |\n`;
if (baseStats) {
const totalDiff = headStats.totalSize - baseStats.totalSize;
const mainDiff = headStats.mainBundleSize - baseStats.mainBundleSize;
const totalDiffPercent = (totalDiff / baseStats.totalSize * 100).toFixed(2);
const mainDiffPercent = (mainDiff / baseStats.mainBundleSize * 100).toFixed(2);
const emoji = totalDiff > 0 ? '📈' : '📉';
body += `\n### ${emoji} Comparison with base branch\n\n`;
body += `| Asset | Base (KB) | Head (KB) | Diff (KB) | Diff (%) |\n`;
body += `|---|---|---|---|---|\n`;
body += `| main.js | ${(baseStats.mainBundleSize / 1024).toFixed(2)} | ${(headStats.mainBundleSize / 1024).toFixed(2)} | ${(mainDiff / 1024).toFixed(2)} | ${mainDiffPercent}% |\n`;
body += `| **Total** | **${(baseStats.totalSize / 1024).toFixed(2)}** | **${(headStats.totalSize / 1024).toFixed(2)}** | **${(totalDiff / 1024).toFixed(2)}** | **${totalDiffPercent}%** |\n`;
if (Math.abs(mainDiff) > 50 * 1024) {
core.setFailed(`Main bundle size changed by more than 50KB.`);
body += `\n\n**Error:** Main bundle size changed by more than 50KB.`;
}
if (Math.abs(totalDiff) > 100 * 1024) {
core.setFailed(`Total bundle size changed by more than 100KB.`);
body += `\n\n**Error:** Total bundle size changed by more than 100KB.`;
}
}
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});