Skip to content

Commit a41d909

Browse files
authored
chore: bundle analyzer cleanup (#1776)
1 parent d80c0cf commit a41d909

File tree

3 files changed

+57
-106
lines changed

3 files changed

+57
-106
lines changed

.github/workflows/bundle-analysis.yml

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
bundle-analysis:
1616
name: Bundle Size Analysis
1717
runs-on: ubuntu-latest
18-
if: github.event.pull_request.draft == false
1918

2019
permissions:
2120
contents: read
@@ -37,46 +36,52 @@ jobs:
3736
- name: Build packages
3837
run: pnpm build:packages
3938

40-
- name: Run bundle analysis
39+
- name: Run bundle analysis on PR
4140
run: pnpm bundle:analyze
4241

43-
- name: Save PR bundle report
42+
- name: Create temp directory and save PR bundle report
4443
run: |
45-
mkdir -p ./bundle-analysis-temp
46-
cp ./bundle-analyzer/bundle-reports/latest.json ./bundle-analysis-temp/pr-report.json
44+
mkdir -p /tmp/bundle-analysis
45+
cp ./bundle-analyzer/bundle-reports/latest.json /tmp/bundle-analysis/pr-current.json
4746
4847
- name: Checkout target branch
4948
run: |
5049
git fetch origin ${{ github.base_ref }}
5150
git checkout origin/${{ github.base_ref }}
5251
53-
- name: Install dependencies (target branch)
54-
run: pnpm install --frozen-lockfile
55-
56-
- name: Build packages (target branch)
57-
run: pnpm build:packages
52+
- name: Get target branch bundle report
53+
id: check-target-bundle
54+
run: |
55+
if git cat-file -e HEAD:bundle-analyzer/bundle-reports/latest.json 2>/dev/null; then
56+
echo "exists=true" >> $GITHUB_OUTPUT
57+
git show HEAD:bundle-analyzer/bundle-reports/latest.json > /tmp/bundle-analysis/target-baseline.json
58+
else
59+
echo "exists=false" >> $GITHUB_OUTPUT
60+
fi
5861
59-
- name: Run bundle analysis (target branch)
60-
run: pnpm bundle:analyze
61-
continue-on-error: true
62+
- name: Checkout PR branch
63+
run: git checkout ${{ github.head_ref }}
6264

63-
- name: Save target branch bundle report
65+
- name: Generate target baseline if missing
66+
if: steps.check-target-bundle.outputs.exists == 'false'
6467
run: |
68+
git checkout origin/${{ github.base_ref }}
69+
pnpm install --frozen-lockfile
70+
pnpm build:packages
71+
pnpm bundle:analyze || echo "Bundle analysis failed"
6572
if [ -f "./bundle-analyzer/bundle-reports/latest.json" ]; then
66-
cp ./bundle-analyzer/bundle-reports/latest.json ./bundle-analysis-temp/target-report.json
73+
cp ./bundle-analyzer/bundle-reports/latest.json /tmp/bundle-analysis/target-baseline.json
6774
else
68-
echo '{"timestamp":"","results":[]}' > ./bundle-analysis-temp/target-report.json
75+
echo '{"timestamp":"","results":[]}' > /tmp/bundle-analysis/target-baseline.json
6976
fi
70-
71-
- name: Checkout PR again
72-
run: git checkout ${{ github.head_ref }}
77+
git checkout ${{ github.head_ref }}
7378
7479
- name: Generate bundle comparison comment
7580
id: bundle-comment
7681
run: |
7782
node ./bundle-analyzer/generate-pr-comment.js \
78-
./bundle-analysis-temp/pr-report.json \
79-
./bundle-analysis-temp/target-report.json
83+
/tmp/bundle-analysis/pr-current.json \
84+
/tmp/bundle-analysis/target-baseline.json
8085
8186
- name: Find existing comment
8287
uses: peter-evans/find-comment@a723a15ad60cf9419c01a6b8c9548ddd15e79531
@@ -91,5 +96,5 @@ jobs:
9196
with:
9297
comment-id: ${{ steps.existing-comment.outputs.comment-id }}
9398
issue-number: ${{ github.event.pull_request.number }}
94-
body-path: ./bundle-analysis-temp/comment.md
99+
body-path: /tmp/bundle-analysis/comment.md
95100
edit-mode: replace

.github/workflows/update-bundle-baseline.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ on:
44
push:
55
branches:
66
- main
7+
paths:
8+
- bundle-analyzer/**
9+
- packages/bits-ui/**
10+
711
concurrency:
812
group: ${{ github.workflow }}-${{ github.ref }}
913
cancel-in-progress: true
@@ -55,8 +59,21 @@ jobs:
5559
echo "No changes to latest.json - skipping PR"
5660
echo "changed=false" >> $GITHUB_OUTPUT
5761
else
58-
echo "latest.json changed - creating/updating PR"
59-
echo "changed=true" >> $GITHUB_OUTPUT
62+
# Check if only timestamp changed
63+
OLD_FILE=$(git show HEAD:bundle-analyzer/bundle-reports/latest.json)
64+
NEW_FILE=$(cat ./bundle-analyzer/bundle-reports/latest.json)
65+
66+
# Remove timestamp fields and compare
67+
OLD_NO_TIMESTAMP=$(echo "$OLD_FILE" | jq 'del(.timestamp)')
68+
NEW_NO_TIMESTAMP=$(echo "$NEW_FILE" | jq 'del(.timestamp)')
69+
70+
if [ "$OLD_NO_TIMESTAMP" = "$NEW_NO_TIMESTAMP" ]; then
71+
echo "Only timestamp changed - skipping PR"
72+
echo "changed=false" >> $GITHUB_OUTPUT
73+
else
74+
echo "Bundle data changed - creating/updating PR"
75+
echo "changed=true" >> $GITHUB_OUTPUT
76+
fi
6077
fi
6178
else
6279
# File doesn't exist in git yet (first time) - create PR

bundle-analyzer/generate-pr-comment.js

Lines changed: 11 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,22 +33,13 @@ function formatBytes(bytes) {
3333
return (bytes / 1024).toFixed(2);
3434
}
3535

36-
function formatPercent(percent) {
37-
if (!isFinite(percent)) return "0.0";
38-
return Math.abs(percent).toFixed(1);
39-
}
40-
4136
function formatDiff(diff, showSign = true) {
4237
const sign = showSign && diff > 0 ? "+" : "";
4338
return `${sign}${formatBytes(diff)}`;
4439
}
4540

4641
function getStatusIcon(status, sizeDiff) {
4742
switch (status) {
48-
case "added":
49-
return "✨";
50-
case "removed":
51-
return "❌";
5243
case "changed":
5344
return sizeDiff > 0 ? "📈" : sizeDiff < 0 ? "📉" : "➡️";
5445
case "unchanged":
@@ -71,33 +62,7 @@ function analyzeBundleChanges(prReport, targetReport) {
7162
const prResult = prMap.get(component);
7263
const targetResult = targetMap.get(component);
7364

74-
if (!prResult && targetResult) {
75-
changes.push({
76-
component,
77-
status: "removed",
78-
sizeDiff: -targetResult.size,
79-
gzipSizeDiff: -targetResult.gzipSize,
80-
sizePercent: -100,
81-
gzipSizePercent: -100,
82-
currentSize: 0,
83-
currentGzipSize: 0,
84-
targetSize: targetResult.size,
85-
targetGzipSize: targetResult.gzipSize,
86-
});
87-
} else if (prResult && !targetResult) {
88-
changes.push({
89-
component,
90-
status: "added",
91-
sizeDiff: prResult.size,
92-
gzipSizeDiff: prResult.gzipSize,
93-
sizePercent: Infinity,
94-
gzipSizePercent: Infinity,
95-
currentSize: prResult.size,
96-
currentGzipSize: prResult.gzipSize,
97-
targetSize: 0,
98-
targetGzipSize: 0,
99-
});
100-
} else if (prResult && targetResult) {
65+
if (prResult && targetResult) {
10166
const sizeDiff = prResult.size - targetResult.size;
10267
const gzipSizeDiff = prResult.gzipSize - targetResult.gzipSize;
10368
const sizePercent = targetResult.size > 0 ? (sizeDiff / targetResult.size) * 100 : 0;
@@ -136,12 +101,12 @@ function generateComment(changes, hasBaseline = true) {
136101

137102
if (changes.length > 0) {
138103
comment += "### 📊 Current Component Sizes\n\n";
139-
comment += "| Component | Size | Gzipped |\n";
140-
comment += "|-----------|------|----------|\n";
104+
comment += "| Component | Size |\n";
105+
comment += "|-----------|------|\n";
141106

142107
const sortedComponents = changes.sort((a, b) => a.component.localeCompare(b.component));
143108
for (const comp of sortedComponents) {
144-
comment += `| \`${comp.component}\` | ${formatBytes(comp.currentSize)} KB | ${formatBytes(comp.currentGzipSize)} KB |\n`;
109+
comment += `| \`${comp.component}\` | ${formatBytes(comp.currentSize)} KB <sub>gzipped: (${formatBytes(comp.currentGzipSize)} KB)</sub> |\n`;
145110
}
146111
comment += "\n";
147112
}
@@ -154,59 +119,23 @@ function generateComment(changes, hasBaseline = true) {
154119
return comment;
155120
}
156121

157-
// Summary stats
158-
const totalSizeDiff = changedComponents.reduce((sum, c) => sum + c.sizeDiff, 0);
159-
const totalGzipDiff = changedComponents.reduce((sum, c) => sum + c.gzipSizeDiff, 0);
160-
161-
const summaryIcon = totalSizeDiff > 0 ? "📈" : totalSizeDiff < 0 ? "📉" : "➡️";
162-
comment += `### ${summaryIcon} Summary\n\n`;
163-
comment += `**Total bundle size change**: ${formatDiff(totalSizeDiff)} KB (${formatDiff(totalGzipDiff)} KB gzipped)\n\n`;
164-
165-
// Group changes by status
166-
const addedComponents = changedComponents.filter((c) => c.status === "added");
167-
const removedComponents = changedComponents.filter((c) => c.status === "removed");
168122
const modifiedComponents = changedComponents.filter((c) => c.status === "changed");
169123

170-
if (addedComponents.length > 0) {
171-
comment += "### ✨ New Components\n\n";
172-
comment += "| Component | Size | Gzipped |\n";
173-
comment += "|-----------|------|----------|\n";
174-
for (const comp of addedComponents) {
175-
comment += `| \`${comp.component}\` | +${formatBytes(comp.currentSize)} KB | +${formatBytes(comp.currentGzipSize)} KB |\n`;
176-
}
177-
comment += "\n";
178-
}
179-
180-
if (removedComponents.length > 0) {
181-
comment += "### ❌ Removed Components\n\n";
182-
comment += "| Component | Size | Gzipped |\n";
183-
comment += "|-----------|------|----------|\n";
184-
for (const comp of removedComponents) {
185-
comment += `| \`${comp.component}\` | -${formatBytes(comp.targetSize)} KB | -${formatBytes(comp.targetGzipSize)} KB |\n`;
186-
}
187-
comment += "\n";
188-
}
189-
190124
if (modifiedComponents.length > 0) {
191125
comment += "### 📊 Modified Components\n\n";
192-
comment += "| Component | Size Change | Gzipped Change | % Change |\n";
193-
comment += "|-----------|-------------|----------------|----------|\n";
126+
comment += "| Component | Current | New | Change |\n";
127+
comment += "|-----------|---------|-----|--------|\n";
194128

195129
for (const comp of modifiedComponents) {
196130
const icon = getStatusIcon(comp.status, comp.sizeDiff);
197-
const sizeChange = `${formatDiff(comp.sizeDiff)} KB`;
198-
const gzipChange = `${formatDiff(comp.gzipSizeDiff)} KB`;
199-
const percentChange =
200-
comp.sizeDiff !== 0
201-
? `${comp.sizeDiff > 0 ? "+" : ""}${formatPercent(comp.sizePercent)}%`
202-
: "0.0%";
203-
204-
comment += `| ${icon} \`${comp.component}\` | ${sizeChange} | ${gzipChange} | ${percentChange} |\n`;
131+
const currentSize = `${formatBytes(comp.targetSize)} KB <sub>gzipped: (${formatBytes(comp.targetGzipSize)} KB)</sub>`;
132+
const newSize = `${formatBytes(comp.currentSize)} KB <sub>gzipped: (${formatBytes(comp.currentGzipSize)} KB)</sub>`;
133+
const sizeChange = `${formatDiff(comp.sizeDiff)} KB <sub>gzipped: (${formatDiff(comp.gzipSizeDiff)} KB)</sub>`;
134+
comment += `| ${icon} \`${comp.component}\` | ${currentSize} | ${newSize} | ${sizeChange} |\n`;
205135
}
206136
comment += "\n";
207137
}
208138

209-
// Add helpful context
210139
comment += "---\n\n";
211140
comment += "<details>\n";
212141
comment += "<summary>📋 Understanding Bundle Analysis</summary>\n\n";
@@ -260,7 +189,7 @@ function main() {
260189

261190
const comment = generateComment(changes, hasBaseline);
262191

263-
writeFileSync("./bundle-analysis-temp/comment.md", comment);
192+
writeFileSync("/tmp/bundle-analysis/comment.md", comment);
264193

265194
console.log("✅ Bundle analysis comment generated successfully");
266195
if (hasBaseline) {

0 commit comments

Comments
 (0)