Run bundlesize tests on every commit

It was added in 7340485014
but for some reason never enabled.

This was supposed to be protecting us from performance regressions
by monitoring the size of modules in the repo. It appears to be
broken both locally and on Jenkins when run on the due to some changes
in Phabricator.

Since then we've added bundle size tests to Vector using a different
more foolproof method. I think that method is more preferable as it
also provides coverage for JS and icons so the
associated script is copied over and used in Minerva
and activated on all commits.

Bug: T259080
Change-Id: I9ba2dcc060ec09d91814c947d5be3f71b055a66e
This commit is contained in:
jdlrobson 2020-07-23 11:19:45 -07:00 committed by Jdlrobson
parent 6f1fb87414
commit 7408d87465
5 changed files with 113 additions and 53 deletions

View file

@ -20,7 +20,8 @@ module.exports = function ( grunt ) {
'!docs/**',
'!libs/**',
'!node_modules/**',
'!vendor/**'
'!vendor/**',
'!tests/resource-loader-bundlesize.js'
]
},
stylelint: {

42
bundlesize.config.json Normal file
View file

@ -0,0 +1,42 @@
[
{
"resourceModule": "skins.minerva.base.styles",
"maxSize": "3.4KB"
},
{
"resourceModule": "skins.minerva.content.styles",
"maxSize": "3.1KB"
},
{
"resourceModule": "skins.minerva.content.styles.images",
"maxSize": "0.5KB"
},
{
"resourceModule": "mediawiki.hlist",
"maxSize": "0.5KB"
},
{
"resourceModule": "mediawiki.ui.icon",
"maxSize": "0.4KB"
},
{
"resourceModule": "mediawiki.ui.button",
"maxSize": "1.1KB"
},
{
"resourceModule": "skins.minerva.icons.wikimedia",
"maxSize": "0.7KB"
},
{
"resourceModule": "skins.minerva.mainMenu.icons",
"maxSize": "0.4KB"
},
{
"resourceModule": "skins.minerva.mainMenu.styles",
"maxSize": "1.2KB"
},
{
"resourceModule": "skins.minerva.scripts",
"maxSize": "11.9KB"
}
]

View file

@ -1,31 +0,0 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
function setUp() {
mkdir -p tmp .resolve-less-imports/mediawiki.ui
}
function tearDown() {
rm -r tmp .resolve-less-imports
}
trap tearDown EXIT
setUp
curl "https://phabricator.wikimedia.org/source/mediawiki/browse/master/resources/src/mediawiki.less/mediawiki.mixins.less?view=raw" -o .resolve-less-imports/mediawiki.mixins.less -L
curl "https://phabricator.wikimedia.org/source/mediawiki/browse/master/resources/src/mediawiki.less/mediawiki.ui/variables.less?view=raw" -o .resolve-less-imports/mediawiki.ui/variables.less -L
curl "https://phabricator.wikimedia.org/source/mediawiki/browse/master/resources/src/mediawiki.less/mediawiki.mixins.rotation.less?view=raw" -o .resolve-less-imports/mediawiki.mixins.rotation.less -L
curl "https://phabricator.wikimedia.org/source/mediawiki/browse/master/resources/src/mediawiki.less/mediawiki.mixins.animation.less?view=raw" -o .resolve-less-imports/mediawiki.mixins.animation.less -L
# Append compatibility with wgMinervaApplyKnownTemplateHacks.
echo "@wgMinervaApplyKnownTemplateHacks: 1;" >> .resolve-less-imports/mediawiki.ui/variables.less
# Build the render blocking bundles for testing
npx lessc resources/skins.minerva.base.styles/skin.less tmp/skins.minerva.base.styles.css --include-path=".resolve-less-imports"
npx lessc resources/skins.minerva.content.styles/index.less tmp/skins.minerva.content.styles.css --include-path=".resolve-less-imports"
npx lessc resources/skins.minerva.amc.styles/index.less tmp/skins.minerva.amc.styles.css --include-path=".resolve-less-imports"
npx lessc resources/skins.minerva.mainMenu.styles/index.less tmp/skins.minerva.mainMenu.styles.css --include-path=".resolve-less-imports"
npx bundlesize

View file

@ -6,10 +6,10 @@
"build-storybook": "npm run storybook:setup && build-storybook -o docs/",
"test": "grunt test && npm run doc && dev-scripts/svg_check.sh",
"doc": "jsdoc -c jsdoc.json",
"test:bundle": "./dev-scripts/bundlesize.sh",
"test:size": "node ./tests/resource-loader-bundlesize.js",
"selenium-test-cucumber": "wdio tests/selenium/wdio.conf.cucumber.js",
"selenium-daily": "MW_SERVER=https://en.m.wikipedia.beta.wmflabs.org npm run selenium-test",
"selenium-test": "wdio tests/selenium/wdio.conf.js"
"selenium-test": "npm -s run test:size && wdio tests/selenium/wdio.conf.js"
},
"dependencies": {},
"devDependencies": {
@ -40,23 +40,5 @@
"svgo": "1.3.2",
"wdio-mediawiki": "1.0.0",
"webdriverio": "6.1.25"
},
"bundlesize": [
{
"path": "tmp/skins.minerva.content.styles.css",
"maxSize": "5.3KB"
},
{
"path": "tmp/skins.minerva.base.styles.css",
"maxSize": "4.3KB"
},
{
"path": "tmp/skins.minerva.amc.styles.css",
"maxSize": "1.4KB"
},
{
"path": "tmp/skins.minerva.mainMenu.styles.css",
"maxSize": "2.0KB"
}
]
}
}

View file

@ -0,0 +1,66 @@
/**
* ResourceLoader module bandwidth test
*
* Fetches a series of ResourceLoader modules from a ResourceLoader URI and
* pipes their content into a bundlesize command which validates their bytesize
* against a configuration in in ../bundlesize.config.json.
*/
const
MW_SERVER = process.env.MW_SERVER || 'http://127.0.0.1:8080',
MW_SCRIPT_PATH = process.env.MW_SCRIPT_PATH || '/w',
childProcess = require( 'child_process' ),
fetch = require( 'node-fetch' ).default,
bundles = require( '../bundlesize.config.json' ),
// eslint-disable-next-line es/no-object-assign
bundlesizeEnv = Object.assign( {}, process.env );
/**
* Create a ResourceLoader URL based on $MW_SERVER and $MW_SCRIPT_PATH
*
* @param {string} rlModuleName
* @return {string}
*/
function createRLUrl( rlModuleName ) {
return `${MW_SERVER}${MW_SCRIPT_PATH}/load.php?lang=en&modules=${rlModuleName}`;
}
/**
* Remove the "CI" environment variable so that it is not passed to
* the bundlesize command, resulting in an unnecessary "Github token not found"
* warning. Note: assigning to null or undefined doesn't work because Node casts
* environment variable values to strings.
*/
delete bundlesizeEnv.CI;
/**
* Fetch each ResourceLoader module defined in the bundlesize config
* and pipe it's content into a bundlesize command.
* The bundlesize stdout and stderr are passed to the parent process,
* so any error in bundlesize will trigger a non-zero exit status for this script.
*/
bundles.forEach( async ( rlModule ) => {
const rlModuleResponse = await fetch( createRLUrl( rlModule.resourceModule ) ),
rlModuleContent = await rlModuleResponse.text();
// Execute the bundlesize command.
const cmd = childProcess.spawn(
'node_modules/.bin/bundlesize-pipe',
[ '--name', rlModule.resourceModule, '--max-size', rlModule.maxSize ],
{
// Stdin is writable stream, stdout and stderr are passed to the parent process.
stdio: [ 'pipe', 'inherit', 'inherit' ],
env: bundlesizeEnv
}
);
cmd.stdin.write( rlModuleContent );
cmd.stdin.end();
cmd.on( 'exit', ( code ) => {
if ( code !== 0 ) {
process.exitCode = code || 1; // prevent assigning falsy values.
}
} );
} );