@@ -78,55 +78,270 @@ jobs:
7878 cd ../../../
7979 ls -la *.zip
8080
81- - name : Compare Build Sizes
81+ - name : Extract and Compare Files
8282 run : |
83- echo "## 📦 Build Size Comparison" >> $GITHUB_STEP_SUMMARY
84- echo "" >> $GITHUB_STEP_SUMMARY
85-
86- # Check if files exist
87- if [ ! -f "current-build.zip" ]; then
88- echo "❌ **Error**: current-build.zip not found" >> $GITHUB_STEP_SUMMARY
89- exit 1
90- fi
91-
92- if [ ! -f "base-build.zip" ]; then
93- echo "❌ **Error**: base-build.zip not found" >> $GITHUB_STEP_SUMMARY
94- exit 1
95- fi
96-
97- # Get file sizes
98- CURRENT_SIZE=$(du -h current-build.zip | cut -f1)
99- BASE_SIZE=$(du -h base-build.zip | cut -f1)
100-
101- # Get exact byte sizes for calculation
102- CURRENT_BYTES=$(stat -c%s current-build.zip)
103- BASE_BYTES=$(stat -c%s base-build.zip)
104-
105- # Calculate difference
106- DIFF_BYTES=$((CURRENT_BYTES - BASE_BYTES))
107- DIFF_PERCENT=$((DIFF_BYTES * 100 / BASE_BYTES))
108-
109- echo "| Build | Size |" >> $GITHUB_STEP_SUMMARY
110- echo "|-------|------|" >> $GITHUB_STEP_SUMMARY
111- echo "| **Current PR** | **$CURRENT_SIZE** |" >> $GITHUB_STEP_SUMMARY
112- echo "| Base Branch | $BASE_SIZE |" >> $GITHUB_STEP_SUMMARY
113- echo "" >> $GITHUB_STEP_SUMMARY
114-
115- if [ $DIFF_BYTES -gt 0 ]; then
116- echo "📈 **Size increased by** $(numfmt --to=iec $DIFF_BYTES) (+$DIFF_PERCENT%)" >> $GITHUB_STEP_SUMMARY
117- elif [ $DIFF_BYTES -lt 0 ]; then
118- echo "📉 **Size decreased by** $(numfmt --to=iec $((DIFF_BYTES * -1))) (-$((DIFF_PERCENT * -1))%)" >> $GITHUB_STEP_SUMMARY
119- else
120- echo "✅ **No size change**" >> $GITHUB_STEP_SUMMARY
121- fi
122-
123- echo "" >> $GITHUB_STEP_SUMMARY
124- echo "### 📁 Build Contents" >> $GITHUB_STEP_SUMMARY
125- echo "" >> $GITHUB_STEP_SUMMARY
126- echo "**Current PR build contents:**" >> $GITHUB_STEP_SUMMARY
127- echo '```' >> $GITHUB_STEP_SUMMARY
128- unzip -l current-build.zip | head -20 >> $GITHUB_STEP_SUMMARY
129- echo '```' >> $GITHUB_STEP_SUMMARY
83+ # Extract both zip files
84+ mkdir -p current-files base-files
85+ unzip -q current-build.zip -d current-files/
86+ unzip -q base-build.zip -d base-files/
87+
88+ # Create comparison script
89+ cat > compare_files.py << 'EOF'
90+ import os
91+ import json
92+ from pathlib import Path
93+
94+ def get_file_size(filepath):
95+ if os.path.exists(filepath):
96+ return os.path.getsize(filepath)
97+ return 0
98+
99+ def format_bytes(bytes):
100+ for unit in ['B', 'KB', 'MB', 'GB']:
101+ if bytes < 1024.0:
102+ return f"{bytes:.1f}{unit}"
103+ bytes /= 1024.0
104+ return f"{bytes:.1f}TB"
105+
106+ def compare_directories(current_dir, base_dir):
107+ current_path = Path(current_dir)
108+ base_path = Path(base_dir)
109+
110+ all_files = set()
111+
112+ # Get all files from both directories
113+ for file_path in current_path.rglob('*'):
114+ if file_path.is_file():
115+ rel_path = file_path.relative_to(current_path)
116+ all_files.add(str(rel_path))
117+
118+ for file_path in base_path.rglob('*'):
119+ if file_path.is_file():
120+ rel_path = file_path.relative_to(base_path)
121+ all_files.add(str(rel_path))
122+
123+ changes = []
124+ total_current = 0
125+ total_base = 0
126+
127+ for file_path in sorted(all_files):
128+ current_file = current_path / file_path
129+ base_file = base_path / file_path
130+
131+ current_size = get_file_size(current_file)
132+ base_size = get_file_size(base_file)
133+
134+ total_current += current_size
135+ total_base += base_size
136+
137+ if current_size != base_size:
138+ diff = current_size - base_size
139+ if base_size > 0:
140+ percent = (diff / base_size) * 100
141+ else:
142+ percent = 100 if current_size > 0 else 0
143+
144+ status = "🆕" if base_size == 0 else "❌" if current_size == 0 else "📝"
145+
146+ changes.append({
147+ 'file': file_path,
148+ 'current_size': current_size,
149+ 'base_size': base_size,
150+ 'diff': diff,
151+ 'percent': percent,
152+ 'status': status
153+ })
154+
155+ return changes, total_current, total_base
156+
157+ # Compare files
158+ changes, total_current, total_base = compare_directories('current-files', 'base-files')
159+
160+ # Create summary
161+ total_diff = total_current - total_base
162+ total_percent = (total_diff / total_base * 100) if total_base > 0 else 0
163+
164+ # Flag large changes (>10% or >100KB)
165+ flagged_changes = [c for c in changes if abs(c['percent']) > 10 or abs(c['diff']) > 102400]
166+
167+ # Generate report
168+ report = {
169+ 'total_current': total_current,
170+ 'total_base': total_base,
171+ 'total_diff': total_diff,
172+ 'total_percent': total_percent,
173+ 'changes': changes,
174+ 'flagged_changes': flagged_changes
175+ }
176+
177+ with open('comparison_report.json', 'w') as f:
178+ json.dump(report, f, indent=2)
179+
180+ # Print summary to console
181+ print(f"Total size change: {format_bytes(total_diff)} ({total_percent:+.1f}%)")
182+ print(f"Files changed: {len(changes)}")
183+ print(f"Flagged changes: {len(flagged_changes)}")
184+ EOF
185+
186+ python3 compare_files.py
187+
188+ - name : Generate PR Comment
189+ id : pr_comment
190+ run : |
191+ # Read the comparison report
192+ python3 -c "
193+ import json
194+ with open('comparison_report.json', 'r') as f:
195+ report = json.load(f)
196+
197+ def format_bytes(bytes):
198+ for unit in ['B', 'KB', 'MB', 'GB']:
199+ if bytes < 1024.0:
200+ return f'{bytes:.1f}{unit}'
201+ bytes /= 1024.0
202+ return f'{bytes:.1f}TB'
203+
204+ # Generate comment
205+ comment = '## 📦 Build Size Comparison\n\n'
206+
207+ # Overall summary
208+ total_current = report['total_current']
209+ total_base = report['total_base']
210+ total_diff = report['total_diff']
211+ total_percent = report['total_percent']
212+
213+ comment += '| Build | Size |\n'
214+ comment += '|-------|------|\n'
215+ comment += f'| **Current PR** | **{format_bytes(total_current)}** |\n'
216+ comment += f'| Base Branch | {format_bytes(total_base)} |\n\n'
217+
218+ if total_diff > 0:
219+ comment += f'📈 **Total size increased by** {format_bytes(total_diff)} (+{total_percent:.1f}%)\n\n'
220+ elif total_diff < 0:
221+ comment += f'📉 **Total size decreased by** {format_bytes(abs(total_diff))} ({total_percent:.1f}%)\n\n'
222+ else:
223+ comment += '✅ **No total size change**\n\n'
224+
225+ # File changes summary
226+ changes = report['changes']
227+ flagged = report['flagged_changes']
228+
229+ comment += f'**Files changed:** {len(changes)}\n'
230+ comment += f'**Large changes flagged:** {len(flagged)}\n\n'
231+
232+ if flagged:
233+ comment += '## ⚠️ Large Changes (Requires Review)\n\n'
234+ comment += '| File | Current | Base | Change | % | Status |\n'
235+ comment += '|------|---------|------|--------|---|--------|\n'
236+
237+ for change in flagged:
238+ status_icon = change['status']
239+ file_name = change['file']
240+ current_size = format_bytes(change['current_size'])
241+ base_size = format_bytes(change['base_size'])
242+ diff_size = format_bytes(abs(change['diff']))
243+ percent = change['percent']
244+
245+ if change['diff'] > 0:
246+ change_str = f'+{diff_size}'
247+ elif change['diff'] < 0:
248+ change_str = f'-{diff_size}'
249+ else:
250+ change_str = '0B'
251+
252+ comment += f'| `{file_name}` | {current_size} | {base_size} | {change_str} | {percent:+.1f}% | {status_icon} |\n'
253+
254+ comment += '\n'
255+
256+ # All changes table (if not too many)
257+ if len(changes) <= 50:
258+ comment += '## 📋 All File Changes\n\n'
259+ comment += '| File | Current | Base | Change | % | Status |\n'
260+ comment += '|------|---------|------|--------|---|--------|\n'
261+
262+ for change in changes:
263+ status_icon = change['status']
264+ file_name = change['file']
265+ current_size = format_bytes(change['current_size'])
266+ base_size = format_bytes(change['base_size'])
267+ diff_size = format_bytes(abs(change['diff']))
268+ percent = change['percent']
269+
270+ if change['diff'] > 0:
271+ change_str = f'+{diff_size}'
272+ elif change['diff'] < 0:
273+ change_str = f'-{diff_size}'
274+ else:
275+ change_str = '0B'
276+
277+ comment += f'| `{file_name}` | {current_size} | {base_size} | {change_str} | {percent:+.1f}% | {status_icon} |\n'
278+ else:
279+ comment += f'## 📋 File Changes (showing first 50 of {len(changes)})\n\n'
280+ comment += '| File | Current | Base | Change | % | Status |\n'
281+ comment += '|------|---------|------|--------|---|--------|\n'
282+
283+ for change in changes[:50]:
284+ status_icon = change['status']
285+ file_name = change['file']
286+ current_size = format_bytes(change['current_size'])
287+ base_size = format_bytes(change['base_size'])
288+ diff_size = format_bytes(abs(change['diff']))
289+ percent = change['percent']
290+
291+ if change['diff'] > 0:
292+ change_str = f'+{diff_size}'
293+ elif change['diff'] < 0:
294+ change_str = f'-{diff_size}'
295+ else:
296+ change_str = '0B'
297+
298+ comment += f'| `{file_name}` | {current_size} | {base_size} | {change_str} | {percent:+.1f}% | {status_icon} |\n'
299+
300+ # Save comment to file
301+ with open('pr_comment.md', 'w') as f:
302+ f.write(comment)
303+
304+ print('PR comment generated')
305+ "
306+
307+ - name : Post/Update PR Comment
308+ uses : actions/github-script@v7
309+ with :
310+ script : |
311+ const fs = require('fs');
312+ const comment = fs.readFileSync('pr_comment.md', 'utf8');
313+
314+ // Find existing comment
315+ const { data: comments } = await github.rest.issues.listComments({
316+ owner: context.repo.owner,
317+ repo: context.repo.repo,
318+ issue_number: context.issue.number,
319+ });
320+
321+ const existingComment = comments.find(comment =>
322+ comment.user.type === 'Bot' &&
323+ comment.body.includes('📦 Build Size Comparison')
324+ );
325+
326+ if (existingComment) {
327+ // Update existing comment
328+ await github.rest.issues.updateComment({
329+ owner: context.repo.owner,
330+ repo: context.repo.repo,
331+ comment_id: existingComment.id,
332+ body: comment
333+ });
334+ console.log('Updated existing PR comment');
335+ } else {
336+ // Create new comment
337+ await github.rest.issues.createComment({
338+ owner: context.repo.owner,
339+ repo: context.repo.repo,
340+ issue_number: context.issue.number,
341+ body: comment
342+ });
343+ console.log('Created new PR comment');
344+ }
130345
131346 - name : Upload Build Artifacts
132347 uses : actions/upload-artifact@v4
0 commit comments