From 8019a78d1b213d828bcfbcd54426d2726e43be27 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Wed, 15 Oct 2025 10:33:35 +0100 Subject: [PATCH 1/3] feat: allow reporting install size unconditionally --- README.md | 11 +++++++++++ build/main.js | 21 ++++++++++++++++----- src/checks/dependency-size.ts | 19 ++++++++++++++----- 3 files changed, 41 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 811222d..1059087 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,17 @@ See the [`recipes/`](./recipes/) directory for complete workflow examples: - [`basic.yml`](./recipes/basic.yml) - Basic dependency diff on pull requests - [`bundle-diff.yml`](./recipes/bundle-diff.yml) - Advanced workflow with package bundle size analysis +## Always Report Install Size + +If you'd like to always report install size, whether it reduces or increases, you can set the `size-threshold` input to `-1`. + +```yaml +- name: Create Diff + uses: e18e/action-dependency-diff@v1 + with: + size-threshold: '-1' +``` + ## Package Bundle Analysis In addition to analyzing dependency changes, this action can optionally compare the actual bundle sizes of your packages by examining `npm pack` outputs. This provides insights into the **bundle size** (what gets published) rather than just the **install size** (what gets installed with dependencies). diff --git a/build/main.js b/build/main.js index dad6dac..00f47eb 100644 --- a/build/main.js +++ b/build/main.js @@ -24967,14 +24967,25 @@ async function scanForDependencySize(messages, threshold, currentDeps, baseDeps, core5.info( `Total dependency size increase: ${sizeData ? formatBytes(sizeData.totalSize) : "unknown"}` ); - if (sizeData !== null && sizeData.totalSize >= threshold) { + const shouldShow = threshold === -1 || sizeData !== null && sizeData.totalSize >= threshold; + if (shouldShow && sizeData !== null) { const packageRows = Array.from(sizeData.packageSizes.entries()).sort(([, a], [, b]) => b - a).map(([pkg, size]) => `| ${pkg} | ${formatBytes(size)} |`).join("\n"); - messages.push( - `## \u26A0\uFE0F Large Dependency Size Increase + let alert = ""; + if (threshold !== -1 && sizeData.totalSize >= threshold) { + alert = `> [!WARNING] +> This PR adds ${formatBytes(sizeData.totalSize)} of new dependencies, which exceeds the threshold of ${formatBytes(threshold)}. + +`; + } else if (sizeData.totalSize < 0) { + alert = `> [!NOTE] +> :tada: This PR removes ${formatBytes(Math.abs(sizeData.totalSize))} of dependencies. -This PR adds ${formatBytes(sizeData.totalSize)} of new dependencies, which exceeds the threshold of ${formatBytes(threshold)}. +`; + } + messages.push( + `## \u{1F4CA} Dependency Size Changes -| \u{1F4E6} Package | \u{1F4CF} Size | +${alert}| \u{1F4E6} Package | \u{1F4CF} Size | | --- | --- | ${packageRows}` ); diff --git a/src/checks/dependency-size.ts b/src/checks/dependency-size.ts index 9f3cad9..53c1346 100644 --- a/src/checks/dependency-size.ts +++ b/src/checks/dependency-size.ts @@ -101,18 +101,27 @@ export async function scanForDependencySize( }` ); - if (sizeData !== null && sizeData.totalSize >= threshold) { + const shouldShow = + threshold === -1 || + (sizeData !== null && sizeData.totalSize >= threshold); + + if (shouldShow && sizeData !== null) { const packageRows = Array.from(sizeData.packageSizes.entries()) .sort(([, a], [, b]) => b - a) .map(([pkg, size]) => `| ${pkg} | ${formatBytes(size)} |`) .join('\n'); - messages.push( - `## ⚠️ Large Dependency Size Increase + let alert = ''; + if (threshold !== -1 && sizeData.totalSize >= threshold) { + alert = `> [!WARNING]\n> This PR adds ${formatBytes(sizeData.totalSize)} of new dependencies, which exceeds the threshold of ${formatBytes(threshold)}.\n\n`; + } else if (sizeData.totalSize < 0) { + alert = `> [!NOTE]\n> :tada: This PR removes ${formatBytes(Math.abs(sizeData.totalSize))} of dependencies.\n\n`; + } -This PR adds ${formatBytes(sizeData.totalSize)} of new dependencies, which exceeds the threshold of ${formatBytes(threshold)}. + messages.push( + `## 📊 Dependency Size Changes -| 📦 Package | 📏 Size | +${alert}| 📦 Package | 📏 Size | | --- | --- | ${packageRows}` ); From 929809f26f0b6a2df74a93c3fde99d8e087266db Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Wed, 15 Oct 2025 10:43:27 +0100 Subject: [PATCH 2/3] fix: account for removed unsupported optionals --- build/main.js | 57 ++++++++++++++++------------- src/checks/dependency-size.ts | 68 ++++++++++++++++++++--------------- src/main.ts | 3 +- 3 files changed, 74 insertions(+), 54 deletions(-) diff --git a/build/main.js b/build/main.js index 00f47eb..c2c63c6 100644 --- a/build/main.js +++ b/build/main.js @@ -24903,7 +24903,32 @@ function formatBytes(bytes) { } // src/checks/dependency-size.ts -async function scanForDependencySize(messages, threshold, currentDeps, baseDeps, currentLockFile) { +async function removeUnsupportedOptionalDependencies(lockFile, versionInfo) { + const allOptionalVersions = /* @__PURE__ */ new Map(); + for (const pkg of lockFile.packages) { + traverse(pkg, { + optionalDependency: (node) => { + const entry = allOptionalVersions.get(node.name) ?? /* @__PURE__ */ new Set(); + entry.add(node.version); + allOptionalVersions.set(node.name, entry); + } + }); + } + for (const [pkg, versions] of allOptionalVersions) { + for (const version of versions) { + const pkgMeta = await fetchPackageMetadata(pkg, version); + if (pkgMeta && !isSupportedArchitecture(pkgMeta, "linux", "x64", "glibc")) { + const newEntry = versionInfo.findIndex( + (v) => v.name === pkg && v.version === version + ); + if (newEntry !== -1) { + versionInfo.splice(newEntry, 1); + } + } + } + } +} +async function scanForDependencySize(messages, threshold, currentDeps, baseDeps, currentLockFile, baseLockFile) { const newVersions = []; const removedVersions = []; for (const [packageName, currentVersionSet] of currentDeps) { @@ -24930,29 +24955,10 @@ async function scanForDependencySize(messages, threshold, currentDeps, baseDeps, } } if (newVersions.length > 0) { - const allOptionalVersions = /* @__PURE__ */ new Map(); - for (const pkg of currentLockFile.packages) { - traverse(pkg, { - optionalDependency: (node) => { - const entry = allOptionalVersions.get(node.name) ?? /* @__PURE__ */ new Set(); - entry.add(node.version); - allOptionalVersions.set(node.name, entry); - } - }); - } - for (const [pkg, versions] of allOptionalVersions) { - for (const version of versions) { - const pkgMeta = await fetchPackageMetadata(pkg, version); - if (pkgMeta && !isSupportedArchitecture(pkgMeta, "linux", "x64", "glibc")) { - const entry = newVersions.findIndex( - (v) => v.name === pkg && v.version === version - ); - if (entry !== -1) { - newVersions.splice(entry, 1); - } - } - } - } + await removeUnsupportedOptionalDependencies(currentLockFile, newVersions); + } + if (removedVersions.length > 0) { + await removeUnsupportedOptionalDependencies(baseLockFile, removedVersions); } core5.info(`Found ${newVersions.length} new package versions`); core5.info(`Found ${removedVersions.length} removed package versions.`); @@ -25179,7 +25185,8 @@ async function run() { sizeThreshold, currentDeps, baseDeps, - parsedCurrentLock + parsedCurrentLock, + parsedBaseLock ); await scanForProvenance(messages, currentDeps, baseDeps); const basePackagesPattern = core7.getInput("base-packages"); diff --git a/src/checks/dependency-size.ts b/src/checks/dependency-size.ts index 53c1346..364896a 100644 --- a/src/checks/dependency-size.ts +++ b/src/checks/dependency-size.ts @@ -7,12 +7,47 @@ import { } from '../npm.js'; import {formatBytes} from '../common.js'; +async function removeUnsupportedOptionalDependencies( + lockFile: ParsedLockFile, + versionInfo: Array<{name: string; version: string; isNewPackage?: boolean}> +): Promise { + const allOptionalVersions = new Map>(); + + for (const pkg of lockFile.packages) { + traverse(pkg, { + optionalDependency: (node) => { + const entry = allOptionalVersions.get(node.name) ?? new Set(); + entry.add(node.version); + allOptionalVersions.set(node.name, entry); + } + }); + } + + for (const [pkg, versions] of allOptionalVersions) { + for (const version of versions) { + const pkgMeta = await fetchPackageMetadata(pkg, version); + if ( + pkgMeta && + !isSupportedArchitecture(pkgMeta, 'linux', 'x64', 'glibc') + ) { + const newEntry = versionInfo.findIndex( + (v) => v.name === pkg && v.version === version + ); + if (newEntry !== -1) { + versionInfo.splice(newEntry, 1); + } + } + } + } +} + export async function scanForDependencySize( messages: string[], threshold: number, currentDeps: Map>, baseDeps: Map>, - currentLockFile: ParsedLockFile + currentLockFile: ParsedLockFile, + baseLockFile: ParsedLockFile ): Promise { const newVersions: Array<{ name: string; @@ -52,34 +87,11 @@ export async function scanForDependencySize( } if (newVersions.length > 0) { - const allOptionalVersions = new Map>(); - - for (const pkg of currentLockFile.packages) { - traverse(pkg, { - optionalDependency: (node) => { - const entry = allOptionalVersions.get(node.name) ?? new Set(); - entry.add(node.version); - allOptionalVersions.set(node.name, entry); - } - }); - } + await removeUnsupportedOptionalDependencies(currentLockFile, newVersions); + } - for (const [pkg, versions] of allOptionalVersions) { - for (const version of versions) { - const pkgMeta = await fetchPackageMetadata(pkg, version); - if ( - pkgMeta && - !isSupportedArchitecture(pkgMeta, 'linux', 'x64', 'glibc') - ) { - const entry = newVersions.findIndex( - (v) => v.name === pkg && v.version === version - ); - if (entry !== -1) { - newVersions.splice(entry, 1); - } - } - } - } + if (removedVersions.length > 0) { + await removeUnsupportedOptionalDependencies(baseLockFile, removedVersions); } core.info(`Found ${newVersions.length} new package versions`); diff --git a/src/main.ts b/src/main.ts index 8d5db07..23084ce 100644 --- a/src/main.ts +++ b/src/main.ts @@ -135,7 +135,8 @@ async function run(): Promise { sizeThreshold, currentDeps, baseDeps, - parsedCurrentLock + parsedCurrentLock, + parsedBaseLock ); await scanForProvenance(messages, currentDeps, baseDeps); From 23adfc95e661b263f94788665fc16a8f0947dfd6 Mon Sep 17 00:00:00 2001 From: James Garbutt <43081j@users.noreply.github.com> Date: Wed, 15 Oct 2025 10:59:12 +0100 Subject: [PATCH 3/3] chore: add total message --- build/main.js | 4 +++- src/checks/dependency-size.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/build/main.js b/build/main.js index c2c63c6..f0d55a0 100644 --- a/build/main.js +++ b/build/main.js @@ -24993,7 +24993,9 @@ async function scanForDependencySize(messages, threshold, currentDeps, baseDeps, ${alert}| \u{1F4E6} Package | \u{1F4CF} Size | | --- | --- | -${packageRows}` +${packageRows} + +**Total size change:** ${formatBytes(sizeData.totalSize)}` ); } } catch (err) { diff --git a/src/checks/dependency-size.ts b/src/checks/dependency-size.ts index 364896a..903483a 100644 --- a/src/checks/dependency-size.ts +++ b/src/checks/dependency-size.ts @@ -135,7 +135,9 @@ export async function scanForDependencySize( ${alert}| 📦 Package | 📏 Size | | --- | --- | -${packageRows}` +${packageRows} + +**Total size change:** ${formatBytes(sizeData.totalSize)}` ); } } catch (err) {