Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 56 additions & 25 deletions .github/scripts/compare-packages-size.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import path from "node:path";
import { execSync as exec } from "node:child_process";
import { statSync as stat, existsSync as exists } from "node:fs";
import { statSync as stat, existsSync as exists, writeFileSync as write_file } from "node:fs";
import { globSync as glob } from "glob";

const MAIN_WORKTREE = ".worktrees/main";

function size(file) {
return exists(file) ? stat(file).size : null;
}
Expand All @@ -17,44 +19,73 @@ function format(bytes) {
: `${bytes} B`;
}

function delta(a, b) {
if (a == null || b == null) {
function delta(pr, main) {
if (pr == null || main == null) {
return null;
}
return a - b;
return pr - main;
}

function icon(d) {
if (d == null) {
function icon(delta) {
if (delta == null) {
return "—";
}

if (d > 0) return "⬆️";
if (d < 0) return "⬇️";
return "➡️";
if (delta > 0) return "🔴";
if (delta < 0) return "🟢";
return "";
}

const pr_files = glob("dist/**/*.min.js");
const pr_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)]));

exec("git fetch origin main", { stdio: "inherit" });
exec("git checkout origin/main", { stdio: "ignore" });
exec("npm ci --include=dev", { stdio: "inherit" });
exec("npm run build", { stdio: "inherit" });

const main_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)]));
function has_local_origin_main() {
try {
exec('git show-ref --verify --quiet refs/remotes/origin/main', { stdio: ["pipe", "pipe", "pipe"] });
return true;
}
catch {
return false;
}
}

let md = `
function generate_report(files, pr, main) {
let md = `
### 📦 Bundle size comparison

| Name | main | PR | Δ |
|------|------|----|---|
| Name | main | PR | Δ | Delta |
|------|-----:|---:|---|-------:|
`;

for (const file of pr_files) {
const d = delta(pr_sizes[file], main_sizes[file]);
for (const file of files) {
const d = delta(pr[file], main[file]);

md += `| ${path.basename(file)} | ${format(main[file])} | ${format(pr[file])} | ${icon(d)} | ${format(d)} |\n`;
}

md += `| \`${path.basename(file)}\` | ${format(main_sizes[file])} | ${format(pr_sizes[file])} | ${icon(d)} ${format(d)} |\n`;
console.log(md);
process.env.SIZE_REPORT_OUTPUT && write_file(process.env.SIZE_REPORT_OUTPUT, md.trim());
}

console.log(md);
try {
//
// PR build
//
exec("npm run build", { stdio: "inherit" });

const pr_files = glob("dist/**/*.min.js");
const pr_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)]));

//
// Main build
//
has_local_origin_main() || exec("git fetch origin main", { stdio: "inherit" });
exec(`git worktree add ${MAIN_WORKTREE} origin/main`, { stdio: "ignore" });
exec("npm ci --include=dev", { cwd: MAIN_WORKTREE, stdio: "inherit" });
exec("npm run build", { cwd: MAIN_WORKTREE, stdio: "inherit" });

const main_sizes = Object.fromEntries(
pr_files.map(f => [f, size(path.join(MAIN_WORKTREE, f))]));

generate_report(pr_files, pr_sizes, main_sizes);
}
finally {
exec(`git worktree remove ${MAIN_WORKTREE}`, { stdio: "inherit" });
}
15 changes: 6 additions & 9 deletions .github/workflows/pr-diff-size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,13 @@ jobs:
uses: actions/checkout@v4

- name: Install Dependencies
run: npm ci
run: npm ci --include=dev

- name: Build
run: npm run build
env:
NODE_ENV: production
SKIP_GIT_TAG_RESOLUTION: true
- name: Prepate report path
run: echo "SIZE_REPORT_OUTPUT=$RUNNER_TEMP/comment-${{ github.event.pull_request.number }}.md" >> $GITHUB_ENV

- name: Run size comparison
run: npm run size-diff-report > comment.md
run: npm run size-report
env:
NODE_ENV: production
SKIP_GIT_TAG_RESOLUTION: true
Expand All @@ -46,8 +43,8 @@ jobs:
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('./comment.md', 'utf8');
const pr_number = context.payload.workflow_run.pull_requests[0].number;
const body = fs.readFileSync(process.env.SIZE_REPORT_OUTPUT, 'utf8');
const pr_number = context.issue.number;

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"scripts": {
"build": "cross-env NODE_ENV=production gulp build",
"build:debug": "gulp build",
"size-diff-report": "node .github/scripts/compare-packages-size.js",
"size-report": "cross-env NODE_ENV=production SKIP_GIT_TAG_RESOLUTION=true node .github/scripts/compare-packages-size.js",
"test": "gulp build && vitest run && playwright test",
"test:playwright": "playwright test",
"test:vitest": "vitest run"
Expand Down