danny-andrews / thresh Goto Github PK
View Code? Open in Web Editor NEWA CircleCI Plugin for posting bundle diffs to your GitHub PRs.
A CircleCI Plugin for posting bundle diffs to your GitHub PRs.
Maybe you just want to generate the bundle diff for viewing in CircleCI.
Currently, you webpack usage is assumed since we transform the stats we're given based on the output of webpack-stats-plugin.
Three ways of gathering asset stats, ordered from least to most flexible:
Let's go with option 3 as it provides the best support for the largest number of bundlers.
--stats-filepath
option will be renamed to --manifest-filepath
fs.stat
getFileStatsFromManifest
readAssetStat
- Takes a path and returns file statsreadStats
-> readManifest
ErrorReadingAssetStatErr
- Wraps original fs.stat
errorOne side-effect of this change is that we are no longer dealing with bundles, but assets. So we should rename variables across the repo to reflect this.
bundlesize | buildsize | thresh | |
---|---|---|---|
Handles Fingerprinting? | Y | Y | Y |
Posts PR Status Filesize Diffs? | Y | Y | Y |
Relies on 3rd-party service? | Y | Y | N |
CIs Supported | Travis CI, CircleCI, Wercker, and Drone | Circle CI | Circle CI, easy to add more |
Configuration | Expose GitHub access token to environment | None | Expose GitHub/CircleCI access token to environment |
Link | https://github.com/siddharthkp/bundlesize | https://buildsize.org/ | https://github.com/danny-andrews/thresh |
The effects this plugin has can be batched into groups:
1
Read stats file
Post pending PR status
Make artifact directory
Retrieve base bundle sizes
2
Write bundle sizes
Write bundle diff
Post final PR status
(3)
Post error PR status
Error status is separate from failed: https://developer.github.com/v3/repos/statuses/.
const firstItem = response.data[0];
firstItem.status === 'success' ? firstItem.build_num : firstItem.previous_successful_build.build_num
[ {
"previous_successful_build" : {
"build_num" : 1177,
"status" : "success",
"build_time_millis" : 1356552
},
"status" : "running",
"build_num" : 1182
}, {
"previous_successful_build" : {
"build_num" : 1161,
"status" : "success",
"build_time_millis" : 1415599
},
"status" : "success",
"build_num" : 1177
} ]
It'd be nice to be able to check your bundle sizes locally, so you don't have to wait for the build to run (and potentially fail) for you to know if you're good to go. This might just be another CI adapter.
This would skip all GitHub status posting (obviously) and would just output diffs to the console.
Travis, Jenkins, etc.
Only incompatibility I've found thus far is the removal of the CIRCLE_ARTIFACTS
environment variable. https://circleci.com/docs/2.0/env-vars/
Maybe post "passed" status when diff'ing can't be completed.
Right now we only log status text. We should parse the response body and log that as well.
Regession
Configuring everything via CLI options is tedious (especially with complex options like failure-thresholds). We should use a dotfile. Maybe a good time to try out TOML.
If there's no open PR, then we can do diffing, so we should post a status with just the original sizes.
This should cause threshold failures to fail the build instead of submitting a failed PR status.
In monorepos, you may run this command for multiple projects in a single build. We should add an option to configure the project-name (e.g. --project-name
). This will be used when creating the bundle size artifacts and when posting the PR status, as a way of differentiating between stats of different projects.
In monorepos, it's customary to only rebuild the project whose files have changed (or its dependencies). Because of this, a given build may not have all the bundle size info of every project. For this reason, we need to keep a running bundle size artifact. We can do this by adding another level to the JSON payload and merging the generated payload with that of the previous build.
This is going to require some thought. As far as I can tell, we need to do a (possibly) three-way merge. First, with the asset-stats.json for the previous build. Secondly, with the existing asset-stats.json (if any) which will contain asset stats for any projects which have completed before the current one. The problem with this is that these could be run in parallel which could lead to race conditions reading the asset-stats.json file.
Example of asset-stats.json for monorepos:
{
"app1": {
"app.js": {
"size": 408489,
"path": "dist/app.js"
}
},
"app2": {
"app.js": {
"size": 32432321,
"path": "dist/app.js"
},
"vendor.js": {
"size": 35242,
"path": "dist/vendor.js"
}
}
}
If thresholds are not met, fail build.
How it looks currently:
vendor.js: 2.28 MB (+91KB, +4.06%);
app.js: 402.51 KB (-61B, -0.01%);
app.css: 52.08 KB (+0B, +0.00%);
manifest.js: 1.43 KB (+0B, +0.00%)
How I want it to look:
vendor.js: 2.28MB (+91KB, +4.06%)
app.js: 402.51KB (-61B, -0.01%)
app.css: 52.08KB (No Change)
manifest.js: 1.43KB (No Change)
Dependent on #72.
CIRCLE_COMPARE_URL
https://circleci.com/docs/2.0/env-vars/Maybe you changed the output name of an asset from app.js to myapp.js. We should write a helpful info message but not error out.
Oftentimes you will always want to compare against a particular branch for diffs. This would prevent an extra request from being made to get the base branch. This also allows diffs to be calculated even when an open PR is not found.
Note: make sure you note the compare branch in the diff message.
When the script is first run, make a request to GitHub with a pending status.
We should allow people to configure this script to fail based on stats of a particular asset. For example, maybe you want to fail a build if your vendor.js
asset is larger than 500kB.
You should be able to configure this like so: --failure-thresholds='{"vendor.js": {"maxSize": 500000}}'
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.