Skip to content

Commit

Permalink
test: bundle.test
Browse files Browse the repository at this point in the history
  • Loading branch information
evgeniysemin committed Dec 1, 2023
1 parent 76f0eeb commit 7b55f76
Show file tree
Hide file tree
Showing 8 changed files with 431 additions and 540 deletions.
90 changes: 90 additions & 0 deletions .github/workflows/custom-action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: 'Custom action'

on:
push:
branches:
- '*'
- '!master'

jobs:
composite:
name: 'composite'
runs-on: ubuntu-latest
steps:
- name: Setup NodeJS v18.12.0
uses: actions/setup-node@v4
with:
node-version: '18.12.0'

- name: Checkout master
uses: actions/checkout@v3
with:
ref: 'master'
path: master
token: ${{ secrets.GITHUB_TOKEN }}

- name: Get master bundle report
uses: actions/github-script@v7
id: get-master-bundle-report
with:
script: |
const path = require('path');
const fs = require('fs');
try {
const bundleReportPath = path.resolve(process.env.GITHUB_WORKSPACE, 'master', 'bundle-report.json');
return JSON.parse(fs.readFileSync(bundleReportPath));
} catch (_) {
return {};
}
- name: Checkout develop
uses: actions/checkout@v3

- name: Build bundle
run: npm ci && npm run build

- name: Check bundle
uses: actions/github-script@v7
with:
script: |
const checkBundle = require('./bundle.test.js');
console.log('##branchDir:', checkBundle({ baseDir: process.env.GITHUB_WORKSPACE }));
- name: Get develop bundle report
uses: actions/github-script@v7
id: get-develop-bundle-report
with:
script: |
const { createReportObj } = require('./bundle.reportObj.js');
const res = createReportObj({
baseDir: process.env.GITHUB_WORKSPACE,
bundlesDirsNames: ['dist', 'esm', 'umd'],
});
console.log('##res', res);
return res;
- name: Get develop bundle report
uses: actions/github-script@v7
id: bundle-report
with:
result-encoding: string
script: |
const { createReportMd } = require('./bundle.reportMd.js');
const res = createReportMd({
reportPrev: ${{ fromJson(steps.get-master-bundle-report.outputs.result) }},
reportNext: ${{ fromJson(steps.get-develop-bundle-report.outputs.result) }},
});
console.log('##res', res);
return res;
- name: Print result
run: echo '${{ steps.bundle-report.outputs.result }}'
171 changes: 171 additions & 0 deletions bundle.reportMd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
const stub = {
prev: {
'dist/assistant-hash1.js': 531222,
'dist/createAssistantDevOrigin.js': 192052,
'dist/index.js': 61234,
'esm/assistant-hash1.js': 237461,
'esm/assistant.js': 1234,
'esm/common-hash1.js': 6287,
'esm/createAssistant.js': 24867,
'esm/createAssistantDev.js': 374,
'esm/createAssistantDevOrigin.js': 221926,
'esm/index.js': 1057,
'esm/mock.js': 5420,
'esm/record-hash1.js': 63740,
'assistant.development.min.js': 213696,
'assistant.production.min.js': 52853
},
next: {
'dist/assistant-hash1.js': 431222,
'dist/createAssistantDevOrigin.js': 122052,
'dist/index.js': 69234,
'esm/assistant-hash1.js': 137461,
'esm/assistant.js': 123,
'esm/createAssistant.js': 24867,
'esm/createAssistantDev.js': 374,
'esm/createAssistantDevOrigin.js': 121926,
'esm/index.js': 1017,
'esm/mock.js': 5420,
'esm/record-hash1.js': 63740,
'esm/sdk-hash1.js': 261496,
'assistant.production.min.js': 12853
},
};

const colsIds = {
fileName: 0,
prevSize: 1,
nextSize: 2,
diffAbs: 3,
diffPer: 4,
};

const colsTitles = [
['File name', 'Prev size', 'Next size', 'Diff (abs)', 'Diff (%)'],
[':---', ':---:', ':---:', ':---:', ':---:'],
];

const createValuesRows = (prevSizes, nextSizes) => {
const valuesRows = [];
const filesNames = [...new Set([...Object.keys(prevSizes), ...Object.keys(nextSizes)])];

filesNames.forEach((fileName) => {
const fileResult = [];
const prevSize = prevSizes[fileName] || 0;
const nextSize = nextSizes[fileName] || 0;
const diffAbs = (nextSizes[fileName] || 0) - prevSize;

fileResult[colsIds.fileName] = fileName;
fileResult[colsIds.prevSize] = prevSize;
fileResult[colsIds.nextSize] = nextSize;
fileResult[colsIds.diffAbs] = diffAbs;
fileResult[colsIds.diffPer] = 0;

try {
fileResult[colsIds.diffPer] = prevSize === nextSize ? 0 : Math.round((diffAbs || prevSize) / ((prevSize || diffAbs) / 100));
} catch {}

// @ts-ignore
valuesRows.push(fileResult);
});

return valuesRows;
};

const getTotalRow = (valuesRows) => {
const total = [];

total[colsIds.fileName] = '**Total**';
total[colsIds.prevSize] = valuesRows.reduce((acc, row) => acc + row[colsIds.prevSize], 0);
total[colsIds.nextSize] = valuesRows.reduce((acc, row) => acc + row[colsIds.nextSize], 0);
total[colsIds.diffAbs] = valuesRows.reduce((acc, row) => acc + row[colsIds.diffAbs], 0);
total[colsIds.diffPer] = valuesRows.reduce((acc, row) => acc + row[colsIds.diffPer], 0);

return total;
}

const createMdTableByGroups = (valuesRowsGroups = {}, unit = 'KB') => {
const absNames = ['prevSize', 'nextSize', 'diffAbs'];
const perNames = ['diffPer'];

const rows = Object.entries(valuesRowsGroups).reduce((acc, [groupTitle, rows]) => {
if (acc.length) {
acc.push([]);
}

acc.push([`📁 **\`${groupTitle}\`**`]);

const parcedRows = rows.map((rowOriginal) => {
const row = [...rowOriginal];

absNames.map((absName) => {
if (unit === 'KB') {
row[colsIds[absName]] = `${(row[colsIds[absName]] / 1024).toFixed(2)} KB`;

if (absName === 'diffAbs') {
row[colsIds[absName]] = `**${row[colsIds[absName]]}**`;
}
}
});

perNames.map((perName) => {
row[colsIds[perName]] = `${row[colsIds[perName]]} %`;
});

return row;
});

acc = [...acc, ...parcedRows];

return acc;
}, []);

return [...colsTitles, ...rows].map((line) => `|${line.join('|')}|`).join('\n');
};

const createValuesRowsGroups = (prevSizes, nextSizes) => {
const paths = [...new Set([...Object.keys(prevSizes), ...Object.keys(nextSizes)])];

const entriesGroups = paths.reduce((acc, path) => {
const pathSplitted = path.split('/');
const hasDir = pathSplitted.length > 1;
const groupName = `${hasDir ? pathSplitted[0] : '.'}/`;
const fileName = hasDir ? path.slice(groupName.length) : path;

if (!acc[groupName]) {
acc[groupName] = {
prev: {},
next: {},
};
}

if (typeof prevSizes[path] === 'number') {
acc[groupName].prev[fileName] = prevSizes[path];
}

if (typeof nextSizes[path] === 'number') {
acc[groupName].next[fileName] = nextSizes[path];
}

return acc;
}, {});

return Object.entries(entriesGroups).reduce((acc, [groupName, { prev, next }]) => {
const valuesRows = createValuesRows(prev, next).sort((a, b) => {
return a[colsIds.fileName].localeCompare(b[colsIds.fileName]);
});
const total = getTotalRow(valuesRows);

acc[groupName] = [...valuesRows, total];

return acc;
}, {});
};

module.exports = {
createReportMd: ({ reportPrev = {}, reportNext = {} }) => {
const valuesRowsGroups = createValuesRowsGroups(reportPrev, reportNext);

return createMdTableByGroups(valuesRowsGroups);
},
};
67 changes: 67 additions & 0 deletions bundle.reportObj.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const path = require('path');
const fs = require('fs');

const getJsFilesNames = (baseDir, dirsNames = []) => {
return dirsNames.reduce((acc, dirName) => {
const folderFilesNames = fs.readdirSync(path.resolve(baseDir, dirName));

Check warning

Code scanning / Semgrep

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.

Check warning

Code scanning / Semgrep

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.

acc = [
...acc,
...folderFilesNames
.filter((fileName) => fileName.endsWith('.js'))
.map((fileName) => `${dirName}/${fileName}`),
];

return acc;
}, []);
};

const getFilesSizes = (baseDir, filesPaths) => {
return filesPaths.reduce((acc, filePath) => {
const fileStat = fs.statSync(path.resolve(baseDir, filePath));

Check warning

Code scanning / Semgrep

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.

Check warning

Code scanning / Semgrep

Semgrep Finding: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal Warning

Detected possible user input going into a path.join or path.resolve function. This could possibly lead to a path traversal vulnerability, where the attacker can access arbitrary files stored in the file system. Instead, be sure to sanitize or validate user input first.

acc[filePath] = fileStat.size;

return acc;
}, {});
};

const getNormalizedHashedNamesMap = (names, postfix = '') => {
const hashedNamesCount = {};

const hasHash = (str) => {
return /^(?=.*[a-zA-Z])(?=.*\d)[a-zA-Z0-9]+$/.test(str);
};

return names.reduce((acc, nameOriginal) => {
const splittedName = nameOriginal.slice(0, -postfix.length).split('-');

if (hasHash(splittedName.at(-1))) {
const name = splittedName.slice(0, -1).join('');

hashedNamesCount[name] = (hashedNamesCount[name] || 0) + 1;

acc[nameOriginal] = `${name}-hash${hashedNamesCount[name]}${postfix}`;
}

return acc;
}, {});
};

const normalizeObjectKeysByMap = (obj, normalizeMap) => {
return Object.entries(obj).reduce((acc, [key, value]) => {
acc[normalizeMap[key] || key] = value;

return acc;
}, {});
};

module.exports = {
createReportObj: ({ baseDir = __dirname, bundlesDirsNames = [] }) => {
const filesPaths = getJsFilesNames(baseDir, bundlesDirsNames);
const normalizeHashedFilesPathsMap = getNormalizedHashedNamesMap(filesPaths, '.js');
const filesSizesOriginal = getFilesSizes(baseDir, filesPaths);

return normalizeObjectKeysByMap(filesSizesOriginal, normalizeHashedFilesPathsMap);
},
};
8 changes: 8 additions & 0 deletions bundle.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const fs = require('fs');

module.exports = ({ baseDir }) => {
const dirs = fs.readdirSync(baseDir, { withFileTypes: true }).filter(d => d.isDirectory()).map(d => d.name);
const files = fs.readdirSync(baseDir);

return [...dirs, ...files];
};
12 changes: 0 additions & 12 deletions bundle_reports/umd.json

This file was deleted.

Loading

0 comments on commit 7b55f76

Please sign in to comment.