-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
- Loading branch information
There are no files selected for viewing
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 }}' |
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); | ||
}, | ||
}; |
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); | ||
}, | ||
}; |
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]; | ||
}; |
This file was deleted.