From 3e08ad165f988103b0e669025426de69085d9e1c Mon Sep 17 00:00:00 2001 From: chh-ay <80159858+chh-ay@users.noreply.github.com> Date: Thu, 23 Jul 2026 17:12:10 +0000 Subject: [PATCH 1/2] chore: record v0.3.1 package sizes --- .../docs/guides/performance-resources.md | 44 +++++++++++ scripts/size-history.json | 79 +++++++++++++++++++ 2 files changed, 123 insertions(+) diff --git a/docs/src/content/docs/guides/performance-resources.md b/docs/src/content/docs/guides/performance-resources.md index 7fca316..5760d98 100644 --- a/docs/src/content/docs/guides/performance-resources.md +++ b/docs/src/content/docs/guides/performance-resources.md @@ -961,6 +961,50 @@ bun run --filter @sheetwrite/bench bench:formula

Registry measurements for every published release. Each delta is measured against the release immediately before it.

+v0.3.0v0.3.1 + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PackageTarballInstalled
@sheetwrite/wasm287.6 KiB0 B+0.0%795.6 KiB0 B+0.0%
@sheetwrite/core517.4 KiB+11 B+0.0%2.71 MiB+24 B+0.0%
@sheetwrite/xlsx85.5 KiB0 B+0.0%429.6 KiB0 B+0.0%
@sheetwrite/react9.2 KiB0 B+0.0%31.9 KiB0 B+0.0%
@sheetwrite/vue10.1 KiB0 B+0.0%35.7 KiB0 B+0.0%
@sheetwrite/svelte6.2 KiB0 B+0.0%18.5 KiB0 B+0.0%
+
+
+
+ v0.2.0v0.3.0 diff --git a/scripts/size-history.json b/scripts/size-history.json index d125620..cc17e1a 100644 --- a/scripts/size-history.json +++ b/scripts/size-history.json @@ -237,6 +237,85 @@ "unit": "count" } } + }, + { + "version": "0.3.1", + "capturedAt": "2026-07-23T17:11:35.485Z", + "source": "npm registry published artifacts", + "metrics": { + "package.@sheetwrite/wasm.tarballBytes": { + "actual": 294455, + "unit": "bytes" + }, + "package.@sheetwrite/wasm.unpackedBytes": { + "actual": 814645, + "unit": "bytes" + }, + "package.@sheetwrite/wasm.fileCount": { + "actual": 12, + "unit": "count" + }, + "package.@sheetwrite/core.tarballBytes": { + "actual": 529843, + "unit": "bytes" + }, + "package.@sheetwrite/core.unpackedBytes": { + "actual": 2846784, + "unit": "bytes" + }, + "package.@sheetwrite/core.fileCount": { + "actual": 335, + "unit": "count" + }, + "package.@sheetwrite/xlsx.tarballBytes": { + "actual": 87523, + "unit": "bytes" + }, + "package.@sheetwrite/xlsx.unpackedBytes": { + "actual": 439871, + "unit": "bytes" + }, + "package.@sheetwrite/xlsx.fileCount": { + "actual": 59, + "unit": "count" + }, + "package.@sheetwrite/react.tarballBytes": { + "actual": 9398, + "unit": "bytes" + }, + "package.@sheetwrite/react.unpackedBytes": { + "actual": 32679, + "unit": "bytes" + }, + "package.@sheetwrite/react.fileCount": { + "actual": 8, + "unit": "count" + }, + "package.@sheetwrite/vue.tarballBytes": { + "actual": 10354, + "unit": "bytes" + }, + "package.@sheetwrite/vue.unpackedBytes": { + "actual": 36578, + "unit": "bytes" + }, + "package.@sheetwrite/vue.fileCount": { + "actual": 8, + "unit": "count" + }, + "package.@sheetwrite/svelte.tarballBytes": { + "actual": 6354, + "unit": "bytes" + }, + "package.@sheetwrite/svelte.unpackedBytes": { + "actual": 18919, + "unit": "bytes" + }, + "package.@sheetwrite/svelte.fileCount": { + "actual": 10, + "unit": "count" + } + } } ] } From dd9fe8d0b8baba8b3c1eebbd628ef5fed4b4eddc Mon Sep 17 00:00:00 2001 From: chh-ay Date: Fri, 24 Jul 2026 00:23:28 +0700 Subject: [PATCH 2/2] fix(ci): validate generated size history branches --- .changeset/size-history-ci-policy.md | 2 + scripts/changeset-ci.ts | 55 ++++++++++++++++++++++++++++ scripts/workspace-tooling.test.ts | 41 ++++++++++++++++++++- 3 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 .changeset/size-history-ci-policy.md diff --git a/.changeset/size-history-ci-policy.md b/.changeset/size-history-ci-policy.md new file mode 100644 index 0000000..a845151 --- /dev/null +++ b/.changeset/size-history-ci-policy.md @@ -0,0 +1,2 @@ +--- +--- diff --git a/scripts/changeset-ci.ts b/scripts/changeset-ci.ts index c07f3be..886f16a 100644 --- a/scripts/changeset-ci.ts +++ b/scripts/changeset-ci.ts @@ -4,10 +4,52 @@ import { PUBLISHABLE_PACKAGE_ORDER } from "./workspace-tooling.js"; const STABLE_VERSION = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/; const REPOSITORY_ROOT = resolve(import.meta.dir, ".."); +const PACKAGE_SIZE_HISTORY_PREFIX = "automation/package-size-history-"; +const REQUIRED_PACKAGE_SIZE_HISTORY_FILES = new Set([ + "docs/src/content/docs/guides/performance-resources.md", + "scripts/size-history.json", +]); +const ALLOWED_PACKAGE_SIZE_HISTORY_FILES = new Set([ + ...REQUIRED_PACKAGE_SIZE_HISTORY_FILES, + "docs/src/generated/docs-contract.json", +]); export function releaseVersionFromHeadRef(headRef: string | undefined): string | undefined { return headRef !== undefined && STABLE_VERSION.test(headRef) ? headRef : undefined; } +export function packageSizeHistoryVersionFromHeadRef( + headRef: string | undefined, +): string | undefined { + if (headRef === undefined || !headRef.startsWith(PACKAGE_SIZE_HISTORY_PREFIX)) return undefined; + const version = headRef.slice(PACKAGE_SIZE_HISTORY_PREFIX.length); + return STABLE_VERSION.test(version) ? version : undefined; +} +export function isGeneratedPackageSizeHistoryChange(paths: readonly string[]): boolean { + const uniquePaths = new Set(paths); + return ( + uniquePaths.size === paths.length && + [...REQUIRED_PACKAGE_SIZE_HISTORY_FILES].every((path) => uniquePaths.has(path)) && + paths.every((path) => ALLOWED_PACKAGE_SIZE_HISTORY_FILES.has(path)) + ); +} + +async function changedFilesSinceDevelop(): Promise { + const child = Bun.spawn(["git", "diff", "--name-only", "origin/develop...HEAD"], { + cwd: REPOSITORY_ROOT, + stdout: "pipe", + stderr: "pipe", + }); + const [stdout, stderr, exitCode] = await Promise.all([ + new Response(child.stdout).text(), + new Response(child.stderr).text(), + child.exited, + ]); + if (exitCode !== 0) throw new Error(`Unable to inspect package size history diff: ${stderr}`); + return stdout + .split("\n") + .map((path) => path.trim()) + .filter((path) => path.length > 0); +} export function validateReleasePackageVersions(version: string, root = REPOSITORY_ROOT): void { for (const name of PUBLISHABLE_PACKAGE_ORDER) { @@ -30,6 +72,19 @@ async function main(): Promise { console.log(`Release package versions match branch ${releaseVersion}`); return; } + const packageSizeHistoryVersion = packageSizeHistoryVersionFromHeadRef( + process.env.GITHUB_HEAD_REF, + ); + if (packageSizeHistoryVersion !== undefined) { + validateReleasePackageVersions(packageSizeHistoryVersion); + if (isGeneratedPackageSizeHistoryChange(await changedFilesSinceDevelop())) { + console.log(`Package size history versions match branch ${packageSizeHistoryVersion}`); + return; + } + console.log( + "Package size history branch contains non-generated changes; requiring a changeset", + ); + } const child = Bun.spawn(["bun", "run", "changeset:status", "--", "--since=origin/develop"], { cwd: REPOSITORY_ROOT, stdin: "inherit", diff --git a/scripts/workspace-tooling.test.ts b/scripts/workspace-tooling.test.ts index 612001e..7a18baa 100644 --- a/scripts/workspace-tooling.test.ts +++ b/scripts/workspace-tooling.test.ts @@ -2,7 +2,12 @@ import { afterEach, describe, expect, it } from "bun:test"; import { mkdir, mkdtemp, readFile, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join, resolve } from "node:path"; -import { releaseVersionFromHeadRef, validateReleasePackageVersions } from "./changeset-ci.js"; +import { + isGeneratedPackageSizeHistoryChange, + packageSizeHistoryVersionFromHeadRef, + releaseVersionFromHeadRef, + validateReleasePackageVersions, +} from "./changeset-ci.js"; import { assertUniqueOrderedNodes, PACKAGE_BUILD_NODES, @@ -246,6 +251,40 @@ describe("changeset workspace contract", () => { it("runs the release-aware Changesets status command", () => { expect(releaseVersionFromHeadRef("0.3.1")).toBe("0.3.1"); expect(releaseVersionFromHeadRef("feature/docs")).toBeUndefined(); + expect(packageSizeHistoryVersionFromHeadRef("automation/package-size-history-0.3.1")).toBe( + "0.3.1", + ); + expect(packageSizeHistoryVersionFromHeadRef("automation/package-size-history-next")).toBe( + undefined, + ); + expect( + isGeneratedPackageSizeHistoryChange([ + "docs/src/content/docs/guides/performance-resources.md", + "scripts/size-history.json", + ]), + ).toBeTrue(); + expect( + isGeneratedPackageSizeHistoryChange([ + "docs/src/content/docs/guides/performance-resources.md", + "docs/src/generated/docs-contract.json", + "scripts/size-history.json", + ]), + ).toBeTrue(); + expect( + isGeneratedPackageSizeHistoryChange([ + "docs/src/content/docs/guides/performance-resources.md", + "scripts/changeset-ci.ts", + "scripts/size-history.json", + ]), + ).toBeFalse(); + expect(isGeneratedPackageSizeHistoryChange(["scripts/size-history.json"])).toBeFalse(); + expect( + isGeneratedPackageSizeHistoryChange([ + "docs/src/content/docs/guides/performance-resources.md", + "scripts/size-history.json", + "scripts/size-history.json", + ]), + ).toBeFalse(); expect(() => validateReleasePackageVersions("0.3.1")).not.toThrow(); expect(() => validateReleasePackageVersions("0.3.2")).toThrow( "Release branch 0.3.2 requires @sheetwrite/wasm@0.3.2",