How preactjs/compressed-size-action works
1. This repository is a single-purpose GitHub Action: it measures compressed bundle-size changes in a pull request and posts the results back to the PR as a comment. The architecture is centered around one action runtime, not a long-running service.
2. The main entrypoint is the JavaScript action at the repo root (index.js / action.yml), which delegates into the implementation under src/. The action is packaged as a Node-based GitHub Action rather than a container action or compiled binary.
3. The core orchestration lives in src/index.js. From the README, its job is to:
- install dependencies using the detected package manager/lockfile or a user-supplied install command,
- build the current PR checkout,
- compare against the target/base ref build,
- compute compressed sizes,
- format the comparison into a PR comment or console output.
4. The data flow is intentionally local and ephemeral. The action checks out code in the GitHub Actions runner, builds two states of the repository (PR head and base/target ref), compares their generated artifacts, and never uploads bundle data to an external service. The only persisted output is the PR comment in GitHub.
5. File discovery and comparison rules are configurable. The README indicates the action scans for build artifacts using glob patterns, defaults to JavaScript bundles under any dist/ directory, and filters out source maps and node_modules. This makes file selection a distinct subsystem from the build logic.
6. Compression and thresholding are part of the comparison engine. The action can compare raw, gzip, or brotli sizes, or disable compression entirely, and it can ignore tiny deltas below a configurable minimum-change threshold. That means the “change” calculation is separate from the “find files” and “build files” steps.
7. Filenames are normalized before comparison, especially for hashed assets. A strip-hash setting rewrites generated filenames so the same logical bundle can be matched across builds even when content hashes differ. This is important for accurate diffing across release-style outputs.
8. Commenting is a separate output boundary from analysis. The action uses a GitHub comment keyed to the PR, and can optionally partition multiple reports with comment-key so multiple bundle sets do not overwrite each other. If the PR comes from a fork, it falls back to printing the would-be comment to stdout because of GitHub permission limits.
9. The build/install lifecycle is configurable to fit different repository layouts. The action supports custom install scripts, custom build scripts, and an optional clean step between the base build and PR build. That clean step exists specifically to reset state that npm ci && npm run build does not naturally restore in some monorepo or nested-install setups.
10. The helper module at src/utils.js likely contains the reusable pieces for file matching, hash stripping, compression/sizing, sorting, and formatting. The presence of tests/utils.spec.js and its snapshot file suggests these utilities are deterministic and heavily snapshot-tested, which is consistent with a formatting-heavy CLI/action.
11. The top-level tests/ directory is focused on unit-level behavior rather than end-to-end GitHub Actions execution. Snapshot tests indicate the repo validates the generated comparison output and helper transformations, which is a good hint that the user-visible PR comment format is part of the public contract.
12. CI is simple and repository-local: .github/workflows/ci.yml runs the test suite for the action package. There are no signs of supporting backend services, queues, databases, or separate frontend/backend subsystems—just the action runtime, its utilities, and tests.
Main entry points: src/index.js Orchestrator · utils.js Helpers · utils.spec.js Utility tests · index.js Action entry
Components 18
Action runtime
GitHub Action entrypoints and execution flow
- Action entry · GitHub Action entrypoint wiring into the implementation
index.js - Action config · Action metadata and inputs definition
action.yml - Package metadata · Dependencies, scripts, and package settings for the action
package.json
Comparison engine
Build, discover, compare, and format bundle-size results
- Orchestrator · Main action runtime that coordinates install, build, compare, and reporting
src/index.js - Helpers · Reusable file matching, normalization, sizing, and formatting helpers
src/utils.js - Install step · Detects or runs package installation before builds
- Build step · Builds the base ref and pull request checkout
- Artifact scan · Finds generated bundle artifacts with glob-based rules and filters
- Name normalize · Strips hashes and aligns filenames across builds
- Size compare · Computes raw, gzip, brotli, or uncompressed size deltas
- Delta filter · Suppresses tiny changes below the minimum-change threshold
- Comment format · Renders the comparison for PR comment or console output
- PR comment · Writes the report back to the pull request as a comment
- Stdout fallback · Prints the would-be comment when GitHub permissions block commenting
- Clean step · Optional reset between base and PR builds for tricky repo layouts
Verification
Tests and CI coverage for deterministic helpers and output
- Utility tests · Snapshot-driven tests for helper behavior and output stability
tests/utils.spec.js - Snapshots · Expected snapshots for helper and formatting transformations
tests/__snapshots__/utils.spec.js.snap - CI workflow · Repository workflow that runs the test suite
.github/workflows/ci.yml
Connections 19
- Action entry → Orchestrator: loads · Root entry delegates to the implementation
- Action config → Orchestrator: configures · Action inputs and runtime wiring feed the orchestrator
- Package metadata → Orchestrator: depends on · Package scripts and dependencies support the action runtime
- Orchestrator → Install step: installs · Prepares repository dependencies before building
- Orchestrator → Build step: builds · Runs the base and PR builds
- Build step → Clean step: optionally resets · Can clean state between the two build phases
- Build step → Artifact scan: emits artifacts · Build outputs are scanned after generation
- Helpers → Artifact scan: matches files · Helper logic provides glob and filtering behavior
- Artifact scan → Name normalize: normalizes names · Matched files are aligned across build states
- Name normalize → Size compare: pairs artifacts · Normalized filenames feed comparison
- Size compare → Delta filter: filters deltas · Tiny size changes are suppressed when configured
- Delta filter → Comment format: summarizes · Filtered results are converted into a report
- Comment format → PR comment: posts · Primary output is a PR comment
- Comment format → Stdout fallback: falls back to · When commenting is unavailable, print the report
- Orchestrator → Comment format: formats · Orchestrator sends comparison data to the formatter
- Helpers → Size compare: sizes · Helpers provide compression and size calculation routines
- Utility tests → Helpers: covers · Tests exercise the utility module
- Utility tests → Snapshots: snapshots · Snapshot assertions lock formatting and transforms
- CI workflow → Utility tests: runs · CI executes the unit test suite