Merge pull request #5235 from mermaid-js/sizeDiff
Calculate package size diff on PRs
This commit is contained in:
commit
821076ba9c
|
@ -15,6 +15,7 @@ on:
|
|||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
env:
|
||||
# For PRs and MergeQueues, the target commit is used, and for push events, github.event.previous is used.
|
||||
|
@ -48,11 +49,26 @@ jobs:
|
|||
with:
|
||||
ref: ${{ env.targetHash }}
|
||||
|
||||
- name: Install dependencies
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
# just perform install
|
||||
runTests: false
|
||||
|
||||
- name: Build
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' && github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
pnpm run build:viz
|
||||
mkdir -p cypress/snapshots/stats/base
|
||||
mv stats cypress/snapshots/stats/base
|
||||
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
uses: cypress-io/github-action@v6
|
||||
id: cypress-snapshot-gen
|
||||
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
|
||||
with:
|
||||
install: false
|
||||
start: pnpm run dev
|
||||
wait-on: 'http://localhost:9000'
|
||||
browser: chrome
|
||||
|
@ -86,15 +102,42 @@ jobs:
|
|||
path: ./cypress/snapshots
|
||||
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
|
||||
|
||||
- name: Install dependencies
|
||||
uses: cypress-io/github-action@v6
|
||||
with:
|
||||
runTests: false
|
||||
|
||||
- name: Build
|
||||
id: size
|
||||
if: ${{ github.event_name == 'pull_request' && matrix.containers == 1 }}
|
||||
run: |
|
||||
pnpm run build:viz
|
||||
mv stats cypress/snapshots/stats/head
|
||||
{
|
||||
echo 'size_diff<<EOF'
|
||||
npx tsx scripts/size.ts
|
||||
echo EOF
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
|
||||
# Size diff only needs to be posted from one job, on PRs.
|
||||
- name: Comment PR size difference
|
||||
if: ${{ github.event_name == 'pull_request' && matrix.containers == 1 }}
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
message: |
|
||||
${{ steps.size.outputs.size_diff }}
|
||||
comment_tag: size-diff
|
||||
|
||||
# Install NPM dependencies, cache them correctly
|
||||
# and run all Cypress tests
|
||||
- name: Cypress run
|
||||
uses: cypress-io/github-action@v4
|
||||
uses: cypress-io/github-action@v6
|
||||
id: cypress
|
||||
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
|
||||
# Otherwise (e.g. if running from fork), we run on a single container only
|
||||
if: ${{ ( env.CYPRESS_RECORD_KEY != '' ) || ( matrix.containers == 1 ) }}
|
||||
with:
|
||||
install: false
|
||||
start: pnpm run dev:coverage
|
||||
wait-on: 'http://localhost:9000'
|
||||
browser: chrome
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
"jsdom": "^22.0.0",
|
||||
"langium-cli": "3.0.1",
|
||||
"lint-staged": "^13.2.1",
|
||||
"markdown-table": "^3.0.3",
|
||||
"nyc": "^15.1.0",
|
||||
"path-browserify": "^1.0.1",
|
||||
"pnpm": "^8.6.8",
|
||||
|
|
|
@ -163,6 +163,9 @@ importers:
|
|||
lint-staged:
|
||||
specifier: ^13.2.1
|
||||
version: 13.3.0
|
||||
markdown-table:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
nyc:
|
||||
specifier: ^15.1.0
|
||||
version: 15.1.0
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/* eslint-disable no-console */
|
||||
import type { Metafile } from 'esbuild';
|
||||
import { readFile } from 'fs/promises';
|
||||
import { globby } from 'globby';
|
||||
import { markdownTable } from 'markdown-table';
|
||||
export const getSizes = (metafile: Metafile) => {
|
||||
const { outputs } = metafile;
|
||||
const sizes = Object.keys(outputs)
|
||||
.filter((key) => key.endsWith('js') && !key.includes('chunk'))
|
||||
.map((key) => {
|
||||
const { bytes } = outputs[key];
|
||||
return [key.replace('dist/', ''), bytes];
|
||||
});
|
||||
return sizes;
|
||||
};
|
||||
|
||||
const readStats = async (path: string): Promise<Record<string, number>> => {
|
||||
const files = await globby(path);
|
||||
const contents = await Promise.all(files.map((file) => readFile(file, 'utf-8')));
|
||||
const sizes = contents.flatMap((content) => getSizes(JSON.parse(content)));
|
||||
return Object.fromEntries(sizes);
|
||||
};
|
||||
|
||||
const formatBytes = (bytes: number): string => {
|
||||
if (bytes == 0) {
|
||||
return '0 Bytes';
|
||||
}
|
||||
const base = 1024;
|
||||
const decimals = 2;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(base));
|
||||
return parseFloat((bytes / Math.pow(base, i)).toFixed(decimals)) + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
const formatSize = (bytes: number): string => {
|
||||
const formatted = formatBytes(bytes);
|
||||
if (formatted.includes('Bytes')) {
|
||||
return formatted;
|
||||
}
|
||||
return `${formatBytes(bytes)} (${bytes} Bytes)`;
|
||||
};
|
||||
|
||||
const percentageDifference = (oldValue: number, newValue: number): string => {
|
||||
const difference = Math.abs(newValue - oldValue);
|
||||
const avg = (newValue + oldValue) / 2;
|
||||
const percentage = (difference / avg) * 100;
|
||||
const roundedPercentage = percentage.toFixed(2); // Round to two decimal places
|
||||
if (roundedPercentage === '0.00') {
|
||||
return '0.00%';
|
||||
}
|
||||
const sign = newValue > oldValue ? '+' : '-';
|
||||
return `${sign}${roundedPercentage}%`;
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const oldStats = await readStats('./cypress/snapshots/stats/base/**/*.json');
|
||||
const newStats = await readStats('./cypress/snapshots/stats/head/**/*.json');
|
||||
const diff = Object.entries(newStats)
|
||||
.filter(([, value]) => value > 2048)
|
||||
.map(([key, value]) => {
|
||||
const oldValue = oldStats[key];
|
||||
const delta = value - oldValue;
|
||||
const output = [
|
||||
key,
|
||||
formatSize(oldValue),
|
||||
formatSize(value),
|
||||
formatSize(delta),
|
||||
percentageDifference(oldValue, value),
|
||||
];
|
||||
return output;
|
||||
})
|
||||
.filter(([, , , delta]) => delta !== '0 Bytes');
|
||||
if (diff.length === 0) {
|
||||
console.log('No changes in bundle sizes');
|
||||
return;
|
||||
}
|
||||
console.log(
|
||||
markdownTable([['File', 'Previous Size', 'New Size', 'Difference', '% Change'], ...diff])
|
||||
);
|
||||
};
|
||||
|
||||
void main().catch((e) => console.error(e));
|
Loading…
Reference in New Issue