From 0aaaa05662bcd7307b86de62b4e6c7b8aa2c467b Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 21:25:08 +0500 Subject: [PATCH 1/9] Add PR workflow for bundle size comparison --- .github/scripts/compare-packages-size.js | 61 ++++++++++++++++++++ .github/workflows/pr-diff-size.yml | 71 ++++++++++++++++++++++++ .github/workflows/test.yml | 11 +++- 3 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 .github/scripts/compare-packages-size.js create mode 100644 .github/workflows/pr-diff-size.yml diff --git a/.github/scripts/compare-packages-size.js b/.github/scripts/compare-packages-size.js new file mode 100644 index 0000000..9852d5e --- /dev/null +++ b/.github/scripts/compare-packages-size.js @@ -0,0 +1,61 @@ +import path from "node:path"; +import { execSync as exec } from "node:child_process"; +import { statSync as stat, existsSync as exists } from "node:fs"; +import { globSync as glob } from "glob"; + +function size(file) { + return exists(file) ? stat(file).size : null; +} + +function format(bytes) { + if (bytes == null) { + return "—"; + } + + return bytes >= 1024 + ? `${(bytes / 1024).toFixed(2)} KB` + : `${bytes} B`; +} + +function delta(a, b) { + if (a == null || b == null) { + return null; + } + return a - b; +} + +function icon(d) { + if (d == null) { + return "—"; + } + + if (d > 0) return "⬆️"; + if (d < 0) return "⬇️"; + return "➡️"; +} + +const pr_files = glob("dist/**/*.min.js"); +const pr_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)])); + +exec("git checkout origin/main", { stdio: "ignore" }); +exec("npm ci", { stdio: "inherit" }); +exec("npm run build", { stdio: "inherit" }); + +const main_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)])); + +exec("git checkout -", { stdio: "ignore" }); + +let md = ` +### 📦 Bundle size comparison + +| Файл | main | PR | Δ | +|------|------|----|---| +`; + +for (const file of pr_files) { + const d = delta(pr_sizes[file], main_sizes[file]); + + md += `| \`${path.basename(file)}\` | ${format(main_sizes[file])} | ${format(pr_sizes[file])} | ${icon(d)} ${format(d)} |\n`; +} + +console.log(md); diff --git a/.github/workflows/pr-diff-size.yml b/.github/workflows/pr-diff-size.yml new file mode 100644 index 0000000..cbf256e --- /dev/null +++ b/.github/workflows/pr-diff-size.yml @@ -0,0 +1,71 @@ +name: Packages size analysis + +on: + workflow_run: + workflows: ['Build & Test'] + types: [completed] + +permissions: + contents: read + pull-requests: write + actions: read + +jobs: + analyze: + if: > + github.repository == 'rameel/ramstack.alpinegear.js' + && github.event.workflow_run.conclusion == 'success' + && github.event.workflow_run.event == 'pull_request' + + runs-on: ubuntu-latest + + steps: + - name: Checkout PR head + uses: actions/checkout@v4 + with: + ref: ${{ github.event.workflow_run.head_sha }} + fetch-depth: 0 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: '24' + registry-url: 'https://registry.npmjs.org' + + - name: Run size comparison + run: | + node .github/workflows/scripts/compare-packages-size.js > comment.md + + - name: Comment PR + uses: actions/github-script@v7 + 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 { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr_number + }); + + const marker = "### 📦 Bundle size comparison"; + const existing_comment = comments.find(c => c.body.includes(marker)); + + if (existing_comment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing_comment.id, + body: body + }); + } + else { + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: body + }) + } diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 20ae205..52f2f39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,8 +30,8 @@ jobs: - name: Install Dependencies run: npm ci - - name: Build (Debug version) - run: npm run build:debug + - name: Build + run: npm run build - name: "Test: Alpine.js plugins (playwright)" run: npm run test:playwright @@ -40,3 +40,10 @@ jobs: - name: "Test: Alpine.js plugins (vitest)" run: npm run test:vitest + + - name: Upload dist artifact + uses: actions/upload-artifact@v4 + with: + name: dist + path: dist/ + retention-days: 1 From 71a18213aed931577bb9ed33487fd86ed40462a6 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 21:44:12 +0500 Subject: [PATCH 2/9] Disable git tag resolution in test workflow --- .github/scripts/compare-packages-size.js | 2 +- .github/workflows/test.yml | 2 ++ gulpfile.js | 3 ++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/scripts/compare-packages-size.js b/.github/scripts/compare-packages-size.js index 9852d5e..b01a40d 100644 --- a/.github/scripts/compare-packages-size.js +++ b/.github/scripts/compare-packages-size.js @@ -48,7 +48,7 @@ exec("git checkout -", { stdio: "ignore" }); let md = ` ### 📦 Bundle size comparison -| Файл | main | PR | Δ | +| Name | main | PR | Δ | |------|------|----|---| `; diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 52f2f39..4ee4396 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,8 @@ jobs: - name: Build run: npm run build + env: + SKIP_GIT_TAG_RESOLUTION: true - name: "Test: Alpine.js plugins (playwright)" run: npm run test:playwright diff --git a/gulpfile.js b/gulpfile.js index bb8c1a5..97429c6 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -9,13 +9,14 @@ import { rimraf } from "rimraf"; import { rollup } from "rollup"; const is_production = process.env.NODE_ENV === "production"; +const skip_git_tag_resolution = process.env.SKIP_GIT_TAG_RESOLUTION === "true"; const task_delete = create_task("delete -> delete build folders", () => { return rimraf(["dist", "coverage", "docs/public/js"]); }); const task_update_packages = create_task("update -> update version", async done => { - if (is_production) { + if (is_production && !skip_git_tag_resolution) { const current_version = await obtain_version_from_tag(); const update_version = data => { From 36310357d54cc2ab1d89e65ceb24e72a64e65852 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 21:58:20 +0500 Subject: [PATCH 3/9] Add diagnostic workflow --- .github/workflows/diagnostic.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .github/workflows/diagnostic.yml diff --git a/.github/workflows/diagnostic.yml b/.github/workflows/diagnostic.yml new file mode 100644 index 0000000..364ff10 --- /dev/null +++ b/.github/workflows/diagnostic.yml @@ -0,0 +1,14 @@ +on: + workflow_run: + workflows: ["Build & Test"] + types: [completed] + +jobs: + debug: + runs-on: ubuntu-latest + steps: + - run: | + echo "Workflow name: ${{ github.event.workflow_run.name }}" + echo "Conclusion: ${{ github.event.workflow_run.conclusion }}" + echo "Event: ${{ github.event.workflow_run.event }}" + echo "PRs: ${{ github.event.workflow_run.pull_requests }}" From a4f9f73ac08342d6ab68078821ce63e498233cd7 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 22:36:50 +0500 Subject: [PATCH 4/9] Update workflows --- .github/scripts/compare-packages-size.js | 2 -- .github/workflows/diagnostic.yml | 14 ----------- .github/workflows/pr-diff-size.yml | 31 +++++++++++++----------- .github/workflows/test.yml | 13 ++-------- 4 files changed, 19 insertions(+), 41 deletions(-) delete mode 100644 .github/workflows/diagnostic.yml diff --git a/.github/scripts/compare-packages-size.js b/.github/scripts/compare-packages-size.js index b01a40d..8afbf13 100644 --- a/.github/scripts/compare-packages-size.js +++ b/.github/scripts/compare-packages-size.js @@ -43,8 +43,6 @@ exec("npm run build", { stdio: "inherit" }); const main_sizes = Object.fromEntries(pr_files.map(f => [f, size(f)])); -exec("git checkout -", { stdio: "ignore" }); - let md = ` ### 📦 Bundle size comparison diff --git a/.github/workflows/diagnostic.yml b/.github/workflows/diagnostic.yml deleted file mode 100644 index 364ff10..0000000 --- a/.github/workflows/diagnostic.yml +++ /dev/null @@ -1,14 +0,0 @@ -on: - workflow_run: - workflows: ["Build & Test"] - types: [completed] - -jobs: - debug: - runs-on: ubuntu-latest - steps: - - run: | - echo "Workflow name: ${{ github.event.workflow_run.name }}" - echo "Conclusion: ${{ github.event.workflow_run.conclusion }}" - echo "Event: ${{ github.event.workflow_run.event }}" - echo "PRs: ${{ github.event.workflow_run.pull_requests }}" diff --git a/.github/workflows/pr-diff-size.yml b/.github/workflows/pr-diff-size.yml index cbf256e..c2c6a18 100644 --- a/.github/workflows/pr-diff-size.yml +++ b/.github/workflows/pr-diff-size.yml @@ -1,9 +1,9 @@ name: Packages size analysis on: - workflow_run: - workflows: ['Build & Test'] - types: [completed] + pull_request: + branches: [main] + types: [opened, synchronize, reopened, ready_for_review] permissions: contents: read @@ -12,26 +12,29 @@ permissions: jobs: analyze: - if: > - github.repository == 'rameel/ramstack.alpinegear.js' - && github.event.workflow_run.conclusion == 'success' - && github.event.workflow_run.event == 'pull_request' + if: github.repository == 'rameel/ramstack.alpinegear.js' runs-on: ubuntu-latest steps: - - name: Checkout PR head - uses: actions/checkout@v4 - with: - ref: ${{ github.event.workflow_run.head_sha }} - fetch-depth: 0 - - - name: Setup Node + - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '24' registry-url: 'https://registry.npmjs.org' + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Dependencies + run: npm ci + + - name: Build + run: npm run build + env: + NODE_ENV: production + SKIP_GIT_TAG_RESOLUTION: true + - name: Run size comparison run: | node .github/workflows/scripts/compare-packages-size.js > comment.md diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4ee4396..20ae205 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,10 +30,8 @@ jobs: - name: Install Dependencies run: npm ci - - name: Build - run: npm run build - env: - SKIP_GIT_TAG_RESOLUTION: true + - name: Build (Debug version) + run: npm run build:debug - name: "Test: Alpine.js plugins (playwright)" run: npm run test:playwright @@ -42,10 +40,3 @@ jobs: - name: "Test: Alpine.js plugins (vitest)" run: npm run test:vitest - - - name: Upload dist artifact - uses: actions/upload-artifact@v4 - with: - name: dist - path: dist/ - retention-days: 1 From ddf4f3ff34c6565529481a3e4a83bf56e98e5af6 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 22:42:29 +0500 Subject: [PATCH 5/9] Correct script path --- .github/workflows/pr-diff-size.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-diff-size.yml b/.github/workflows/pr-diff-size.yml index c2c6a18..a9b9c07 100644 --- a/.github/workflows/pr-diff-size.yml +++ b/.github/workflows/pr-diff-size.yml @@ -37,7 +37,7 @@ jobs: - name: Run size comparison run: | - node .github/workflows/scripts/compare-packages-size.js > comment.md + node .github/scripts/compare-packages-size.js > comment.md - name: Comment PR uses: actions/github-script@v7 From d67515891344ee32c59b725850fff52f35630b86 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 22:47:41 +0500 Subject: [PATCH 6/9] Explicitly fetch main branch --- .github/scripts/compare-packages-size.js | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/scripts/compare-packages-size.js b/.github/scripts/compare-packages-size.js index 8afbf13..fdba418 100644 --- a/.github/scripts/compare-packages-size.js +++ b/.github/scripts/compare-packages-size.js @@ -37,6 +37,7 @@ function icon(d) { 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", { stdio: "inherit" }); exec("npm run build", { stdio: "inherit" }); From ceaf0ae4e6e282fc6b1c104d7267456beff56ea6 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 22:51:14 +0500 Subject: [PATCH 7/9] Pass env flags --- .github/workflows/pr-diff-size.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/pr-diff-size.yml b/.github/workflows/pr-diff-size.yml index a9b9c07..fe8040d 100644 --- a/.github/workflows/pr-diff-size.yml +++ b/.github/workflows/pr-diff-size.yml @@ -38,6 +38,9 @@ jobs: - name: Run size comparison run: | node .github/scripts/compare-packages-size.js > comment.md + env: + NODE_ENV: production + SKIP_GIT_TAG_RESOLUTION: true - name: Comment PR uses: actions/github-script@v7 From bdf5d844a9156885ecf2bd3a90d5509f07929945 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 22:59:11 +0500 Subject: [PATCH 8/9] Run bundle size comparison via npm script --- .github/workflows/pr-diff-size.yml | 3 +-- package.json | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-diff-size.yml b/.github/workflows/pr-diff-size.yml index fe8040d..691562d 100644 --- a/.github/workflows/pr-diff-size.yml +++ b/.github/workflows/pr-diff-size.yml @@ -36,8 +36,7 @@ jobs: SKIP_GIT_TAG_RESOLUTION: true - name: Run size comparison - run: | - node .github/scripts/compare-packages-size.js > comment.md + run: npm run size-diff-report > comment.md env: NODE_ENV: production SKIP_GIT_TAG_RESOLUTION: true diff --git a/package.json b/package.json index 33e7095..a18dfaa 100644 --- a/package.json +++ b/package.json @@ -25,6 +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", "test": "gulp build && vitest run && playwright test", "test:playwright": "playwright test", "test:vitest": "vitest run" From 71c69f81cb50805de158144c7b0c86954231cab7 Mon Sep 17 00:00:00 2001 From: rameel Date: Wed, 7 Jan 2026 23:09:45 +0500 Subject: [PATCH 9/9] Install dev dependencies for production build --- .github/scripts/compare-packages-size.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/scripts/compare-packages-size.js b/.github/scripts/compare-packages-size.js index fdba418..172b39e 100644 --- a/.github/scripts/compare-packages-size.js +++ b/.github/scripts/compare-packages-size.js @@ -39,7 +39,7 @@ 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", { stdio: "inherit" }); +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)]));