Skip to content

Commit

Permalink
Merge pull request #82 from exoego/filter
Browse files Browse the repository at this point in the history
feat: add `include_size_comparison` option
  • Loading branch information
exoego authored Aug 14, 2024
2 parents 80ee5f9 + 84c18c9 commit aedfbb8
Show file tree
Hide file tree
Showing 8 changed files with 141 additions and 67 deletions.
23 changes: 11 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ jobs:
metafiles: "out/meta.json"
```
### GitHub Action setup for public repositories
If your repository is public and you want to run this action on PRs from forks, you may need to use `pull_request_target` event.
Expand Down Expand Up @@ -154,17 +153,17 @@ Please check the above setup example to use this action with `pull_request_targe

## Action inputs

| Name | Default | Description |
|---------------------------|---------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `metafiles` | - | A required comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]). Glob (`dist/**/meta.json`) is supported. |
| `name` | ${{ github.event.<br>repository.name }} | The name of your project. This will be used in the comment header. |
| `analyze_directory` | `.analyzer` | A path to working directory where bundle analysis are stored. |
| `include_extensions` | `.js,.cjs,.mjs` | A comma-separated list of file extension to be included in the analysis table. |
| `percent_extra_attention` | `20` | If an out file size has increased more than this percent, display a "‼️" to draw extra attention to the change. |
| `show_details` | `true` | If `true`, a collapsed "details" section is rendered. It explains the details of the numbers provided and icons. |
| `show_no_change` | `true` | If `true`, all bundles are shown in the analysis regardless of size change. If `false`, only bundles with size changes are shown. |
| `show_total_changes` | `false` | If `true`, the cumulative number of changes in bundle sizes is rendered. |
| `top_n_largest_paths` | `20` | The number of largest paths (e.g.) `node_modules/foo`) to be collected. If 0 or lower, skipped. |
| Name | Default | Description |
|---------------------------|---------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| `metafiles` | - | A required comma-separated list of paths to [esbuild's meta file]([https://esbuild.github.io/api/#metafile]). Glob (`dist/**/meta.json`) is supported. |
| `name` | ${{ github.event.<br>repository.name }} | The name of your project. This will be used in the comment header. |
| `analyze_directory` | `.analyzer` | A path to working directory where bundle analysis are stored. |
| `include_extensions` | `.js,.cjs,.mjs` | A comma-separated list of file extension to be included in the analysis table. |
| `percent_extra_attention` | `20` | If an out file size has increased more than this percent, display a "‼️" to draw extra attention to the change. |
| `include_size_comparison` | `added, deleted, increased, decreased, no-change` | A comma-separated list of size comparison items to be displayed.<br>Available filter are `total`, `added`, `deleted`, `increased`, `decreased` and `no-change`.<br>If you are not interested in some of them, you can remove them from the list. |
| `show_details` | `true` | If `true`, a collapsed "details" section is rendered. It explains the details of the numbers provided and icons. |
| `show_no_change` | `true` | [DEPRECATED] Use the `include_size_comparison` list to show/hide `no-change`.<br>If `true`, all bundles are shown in the analysis regardless of size change. If `false`, only bundles with size changes are shown. |
| `top_n_largest_paths` | `20` | The number of largest paths (e.g.) `node_modules/foo`) to be collected. If 0 or lower, skipped. |

## Action outputs

Expand Down
9 changes: 7 additions & 2 deletions __tests__/no-base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ describe("examples w/o base analysis", () => {
analyzerDirectory: ".analyzer",
percentExtraAttention: 20,
includeExtensions: [".js", ".mjs", ".cjs"],
includeSizeComparison: new Set([
"added",
"deleted",
"increased",
"decreased",
"no-change",
]),
metafiles: ["out/**/meta.json"],
name: "test",
showDetails: false,
showNoChange: true,
topNLargestPaths: 10,
showTotalChanges: false,
};

beforeEach(() => {
Expand Down
22 changes: 17 additions & 5 deletions __tests__/with-base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { execSync } from "node:child_process";
import path from "node:path";

import { run } from "../src/index";
import type { Input } from "../src/types";
import type { Input, SizeComparisonFilter } from "../src/types";
import {
getExampleDirectories,
readAnalysisComment,
Expand All @@ -26,16 +26,28 @@ describe("examples w/ base analysis", () => {
: ["out/meta.json"];

const isEven = index % 2 === 0;

const includeSizeComparison = new Set<SizeComparisonFilter>([
"total",
"added",
"deleted",
"increased",
"decreased",
"no-change",
]);
if (!isEven) {
includeSizeComparison.delete("total");
includeSizeComparison.delete("no-change");
}
const input: Input = {
analyzerDirectory: ".analyzer",
percentExtraAttention: 20,
includeExtensions: [".js", ".mjs", ".cjs"],
metafiles,
name: "test",
showDetails: false,
showNoChange: isEven,
topNLargestPaths: 10,
showTotalChanges: isEven,
includeSizeComparison,
};

beforeEach(() => {
Expand All @@ -60,10 +72,10 @@ describe("examples w/ base analysis", () => {
expect(comment).toMatch(/✅ {2}-\d+/);
expect(comment).toMatch(/✅ {2}No change/i);
if (isEven) {
expect(comment).not.toMatch(/\d bundles with no change are hidden./i);
expect(comment).not.toMatch(/\d bundles are hidden./i);
expect(comment).toMatch(/\(Total\) \| - \|.+⚠️/i);
} else {
expect(comment).toMatch(/\d bundles with no change are hidden./i);
expect(comment).toMatch(/\d bundles are hidden./i);
expect(comment).not.toMatch(/\(Total\) \| - \|.+⚠️/i);
}
expect(comment).toMatch(/🆕 Added/i);
Expand Down
10 changes: 7 additions & 3 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,13 @@ inputs:
description: |
If an out file size has increased more than this percent, display a "‼️" to draw attention
to the change.
show_total_changes:
include_size_comparison:
required: false
default: "false"
default: "added, deleted, increased, decreased, no-change"
description: |
If `true`, the cumulative number of changes in bundle sizes is rendered.
A comma-separated list of size comparison items to be displayed.
Available filter are `total`, `added`, `deleted`, `increased`, `decreased` and `no-change`.
If you are not interested in some of them, you can remove them from the list.
show_details:
required: false
default: "true"
Expand All @@ -62,6 +64,8 @@ inputs:
show_no_change:
required: false
default: "true"
deprecationMessage: |
Use the `include_size_comparison` list to show/hide `no-change`.
description: |
If `true`, all bundles are shown in the analysis regardless of size change. If `false`, only bundles with size changes are shown.
top_n_largest_paths:
Expand Down
30 changes: 15 additions & 15 deletions dist/index.mjs

Large diffs are not rendered by default.

67 changes: 43 additions & 24 deletions src/compare.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ import * as console from "node:console";
import fs from "node:fs";
import path from "node:path";
import { findMetafiles } from "./report";
import type { CompareResult, Input, Report, TreeMapNode } from "./types";
import type {
CompareResult,
Input,
Report,
SizeComparisonFilter,
TreeMapNode,
} from "./types";
import { loadAnalysisJson, loadMetaFile } from "./utils";

export function compare(input: Input): void {
Expand Down Expand Up @@ -63,19 +69,23 @@ This analysis was generated by [esbuild-bundle-analyzer](https://github.com/exoe
...currentStats,
baseBytes: baseStats.bytes,
tree,
remark: Math.sign(diff) ? "increased" : "decreased",
remark:
diff === 0 ? "no-change" : Math.sign(diff) ? "increased" : "decreased",
};
});
console.log("Comparison done.", comparison);

if (hasAnyChange) {
output += markdownTable(
comparison,
input.includeSizeComparison,
input.percentExtraAttention,
);
output += hiddenTable(
comparison,
input.includeSizeComparison,
input.percentExtraAttention,
input.showTotalChanges,
input.showNoChange,
);
output += noChangesTable(comparison, input.showNoChange);
output += fileSizeTable(comparison, input.topNLargestPaths);
output += detail(input);
} else {
Expand Down Expand Up @@ -205,6 +215,7 @@ function buildFileTree(input: Input) {
}

const spacer = " ";

function filesize(bytes: number): string {
const sign = bytes < 0 ? "-" : "";
const n = Math.abs(bytes);
Expand All @@ -228,9 +239,8 @@ const shouldShowBundle = (d: CompareResult, showNoChange: boolean) =>

function markdownTable(
data: Array<CompareResult>,
sizeComparisonFilters: Set<SizeComparisonFilter>,
redThreshold: number,
showTotalChanges: boolean,
showNoChange: boolean,
): string {
const totalRow = data.reduce(
(acc, d) => {
Expand All @@ -252,9 +262,13 @@ function markdownTable(
);
totalRow.remark =
totalRow.bytes > totalRow.baseBytes ? "increased" : "decreased";
const totalRows: Array<CompareResult> = showTotalChanges ? [totalRow] : [];
const totalRows: Array<CompareResult> = sizeComparisonFilters.has("total")
? [totalRow]
: [];

const individualRows = data.filter((d) => shouldShowBundle(d, showNoChange));
const individualRows = data.filter((d) =>
shouldShowBundle(d, sizeComparisonFilters.has(d.remark)),
);
const rows = [...totalRows, ...individualRows]
.map((d) => {
return `${d.metafile} | ${d.outfile} | ${renderSize(d)} | ${renderNote(
Expand All @@ -270,24 +284,28 @@ Meta File | Out File | Size (raw) | Note
${rows}`;
}

function noChangesTable(
function hiddenTable(
data: Array<CompareResult>,
showNoChange: boolean,
includeSizeComparison: Set<SizeComparisonFilter>,
redThreshold: number,
): string {
const noChangeBundles = data.filter(
(d) => !shouldShowBundle(d, showNoChange),
const hiddenBundles = data.filter(
(d) => !includeSizeComparison.has(d.remark),
);
const rows = noChangeBundles
const rows = hiddenBundles
.map((d) => {
return `${d.metafile} | ${d.outfile} | ${renderSize(d)} | ✅ No change\n`;
return `${d.metafile} | ${d.outfile} | ${renderSize(d)} | ${renderNote(
d,
redThreshold,
)}\n`;
})
.join("");
if (noChangeBundles.length === 0) {
if (hiddenBundles.length === 0) {
return "";
}
return `
<details>
<summary>${noChangeBundles.length} bundles with no change are hidden.</summary>
<summary>${hiddenBundles.length} bundles are hidden since not listed in include_size_comparison.</summary>
Meta File | Out File | Size (raw) | Note
----------|----------|-----------:|------
Expand Down Expand Up @@ -384,6 +402,7 @@ function renderBar(percent: number, bytes: number): string {
// Block progression is 1/8 = 0.125
const blocks = ["", "▏", "▎", "▍", "▌", "▋", "▊", "▉", "█"];
const progression = 1 / (blocks.length - 1);

function progress(value: number, length = 25, vmin = 0.0, vmax = 1.0) {
const v = value * length;
const integerPart = Math.floor(v);
Expand All @@ -405,14 +424,14 @@ function renderNote(d: CompareResult, redThreshold: number): string {
if (d.remark === "added") {
return "🆕 Added";
}
const diff = d.bytes - d.baseBytes;
if (diff !== 0) {
const percentChange = (diff / d.baseBytes) * 100;
return `${renderStatusIndicator(percentChange, redThreshold)}${filesize(
diff,
)} (${sign(percentChange)}${percentChange.toFixed(1)}%)`;
if (d.remark === "no-change") {
return "✅ No change";
}
return "✅ No change";
const diff = d.bytes - d.baseBytes;
const percentChange = (diff / d.baseBytes) * 100;
return `${renderStatusIndicator(percentChange, redThreshold)}${filesize(
diff,
)} (${sign(percentChange)}${percentChange.toFixed(1)}%)`;
}

function sign(num: number): string {
Expand Down
40 changes: 37 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import console from "node:console";
import { pathToFileURL } from "node:url";
import { compare } from "./compare";
import { report } from "./report";
import type { Input } from "./types";
import type { Input, SizeComparisonFilter } from "./types";
import { getBooleanInput, getNumberInput, getSingleInput } from "./utils";

function getInput(): Input {
Expand All @@ -13,15 +14,48 @@ function getInput(): Input {
if (!name) {
throw new Error("name is not specified");
}
const filters = new Set<SizeComparisonFilter>(
(
getSingleInput("include_size_comparison") ||
"added, deleted, increased, decreased, no-change"
)
.split(",")
.map((s) => {
switch (s.trim()) {
case "added":
case "deleted":
case "increased":
case "decreased":
case "total":
case "no-change":
return s.trim() as SizeComparisonFilter;
default:
throw new Error(`Unknown size comparison filter: ${s}`);
}
}),
);
const rawShowNoChange = getSingleInput("show_no_change");
if (rawShowNoChange !== "") {
if (getBooleanInput("show_no_change", "true")) {
filters.delete("no-change");
console.log(
"`show_no_change: true` is deprecated. Instead, remove `no-change` from the `include_size_comparison` list.",
);
} else {
filters.add("no-change");
console.log(
"`show_no_change: false` is deprecated. Instead, add `no-change` to the `include_size_comparison` list.",
);
}
}
return {
percentExtraAttention: getNumberInput("percent_extra_attention", 20),
showDetails: getBooleanInput("show_details", "true"),
showNoChange: getBooleanInput("show_no_change", "true"),
showTotalChanges: getBooleanInput("show_total_changes", "false"),
topNLargestPaths: getNumberInput("top_n_largest_paths", 20),
includeExtensions: (
getSingleInput("include_extensions") || ".js,.mjs,.cjs"
).split(","),
includeSizeComparison: filters,
name,
analyzerDirectory: getSingleInput("analyze_directory") || ".analyzer",
metafiles: rawMetafiles.split(","),
Expand Down
7 changes: 4 additions & 3 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ export interface CompareResult {
outfile: string;
bytes: number;
baseBytes: number;
remark: "added" | "deleted" | "increased" | "decreased";
remark: "added" | "deleted" | "increased" | "decreased" | "no-change";
tree: TreeMapNode | undefined;
}

export type SizeComparisonFilter = CompareResult["remark"] | "total";

export interface Input {
name: string;
metafiles: Array<string>;
includeExtensions: Array<string>;
includeSizeComparison: Set<SizeComparisonFilter>;
topNLargestPaths: number;
analyzerDirectory: string;
percentExtraAttention: number;
showDetails: boolean;
showNoChange: boolean;
showTotalChanges: boolean;
}

export interface TreeMapNode {
Expand Down

0 comments on commit aedfbb8

Please sign in to comment.