Skip to content

Commit

Permalink
Merge pull request #21 from dstaley/threshold-and-tests
Browse files Browse the repository at this point in the history
Add utility tests and minimumChangeThreshold option
  • Loading branch information
developit authored Jun 13, 2020
2 parents c2a3b60 + 6cbb899 commit beb53b9
Show file tree
Hide file tree
Showing 10 changed files with 6,655 additions and 426 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,13 @@ In the example below, a filename `foo.abcde.chunk.js` will be converted to `foo.
```yaml
strip-hash: "\\.(\\w{5})\\.chunk\\.js$"
```

### Increasing the required threshold

By default, a file that's been changed by a single byte will be reported as changed. If you'd prefer to require a certain minimum threshold for a file to be changed, you can specify `minimum-change-threshold` in bytes:

```yaml
minimum-change-threshold: 100
```

In the above example, a file with a delta of less than 100 bytes will be reported as unchanged.
111 changes: 111 additions & 0 deletions __snapshots__/utils.spec.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`diffTable 1`] = `
"**Size Change:** +9 B (0%)
**Total Size:** 4.8 kB
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`one.js\` | 5 kB | +2.5 kB (50%) | 🆘 |
| \`two.js\` | -5 kB | -2.5 kB (50%) | 🆘 |
| \`four.js\` | 4.5 kB | +9 B (0%) | |
<details><summary>ℹ️ <strong>View Unchanged</strong></summary>
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`three.js\` | 300 B | 0 B | |
</details>
"
`;

exports[`diffTable 2`] = `
"| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`one.js\` | 5 kB | +2.5 kB (50%) | 🆘 |
| \`two.js\` | -5 kB | -2.5 kB (50%) | 🆘 |
| \`four.js\` | 4.5 kB | +9 B (0%) | |
<details><summary>ℹ️ <strong>View Unchanged</strong></summary>
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`three.js\` | 300 B | 0 B | |
</details>
"
`;

exports[`diffTable 3`] = `
"**Size Change:** +9 B (0%)
**Total Size:** 4.8 kB
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`one.js\` | 5 kB | +2.5 kB (50%) | 🆘 |
| \`two.js\` | -5 kB | -2.5 kB (50%) | 🆘 |
| \`three.js\` | 300 B | 0 B | |
| \`four.js\` | 4.5 kB | +9 B (0%) | |
"
`;

exports[`diffTable 4`] = `
"**Size Change:** +9 B (0%)
**Total Size:** 4.8 kB
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`one.js\` | 5 kB | +2.5 kB (50%) | 🆘 |
| \`two.js\` | -5 kB | -2.5 kB (50%) | 🆘 |
| \`four.js\` | 4.5 kB | +9 B (0%) | |
"
`;

exports[`diffTable 5`] = `
"**Size Change:** +9 B (0%)
**Total Size:** 4.8 kB
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`one.js\` | 5 kB | +2.5 kB (50%) | 🆘 |
| \`two.js\` | -5 kB | -2.5 kB (50%) | 🆘 |
<details><summary>ℹ️ <strong>View Unchanged</strong></summary>
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`three.js\` | 300 B | 0 B | |
| \`four.js\` | 4.5 kB | +9 B (0%) | |
</details>
"
`;

exports[`diffTable 6`] = `
"**Size Change:** 0 B
**Total Size:** 300 B
<details><summary>ℹ️ <strong>View Unchanged</strong></summary>
| Filename | Size | Change | |
|:--- |:---:|:---:|:---:|
| \`three.js\` | 300 B | 0 B | |
</details>
"
`;
115 changes: 3 additions & 112 deletions action.js
Original file line number Diff line number Diff line change
@@ -1,40 +1,9 @@
import path from 'path';
import fs from 'fs';
import { getInput, setFailed, startGroup, endGroup, debug } from '@actions/core';
import { GitHub, context } from '@actions/github';
import { exec } from '@actions/exec';
import SizePlugin from 'size-plugin-core';
import prettyBytes from 'pretty-bytes';


async function fileExists(filename) {
try {
await fs.promises.access(filename, fs.constants.F_OK);
return true;
} catch (e) {}
return false;
}

function stripHash(regex) {
if (regex) {
console.log(`Striping hash from build chunks using '${regex}' pattern.`);
return function(fileName) {
return fileName.replace(new RegExp(regex), (str, ...hashes) => {
hashes = hashes.slice(0, -2).filter(c => c != null);
if (hashes.length) {
for (let i=0; i<hashes.length; i++) {
const hash = hashes[i] || '';
str = str.replace(hash, hash.replace(/./g, '*'));
}
return str;
}
return '';
});
}
}

return undefined;
}
import { fileExists, diffTable, toBool, stripHash } from './utils';


async function run(octokit, context, token) {
Expand Down Expand Up @@ -137,7 +106,8 @@ async function run(octokit, context, token) {
const markdownDiff = diffTable(diff, {
collapseUnchanged: toBool(getInput('collapse-unchanged')),
omitUnchanged: toBool(getInput('omit-unchanged')),
showTotal: toBool(getInput('show-total'))
showTotal: toBool(getInput('show-total')),
minimumChangeThreshold: parseInt(getInput('minimum-change-threshold'), 10)
});

let outputRawMarkdown = false;
Expand Down Expand Up @@ -258,85 +228,6 @@ async function createCheck(octokit, context) {
};
}


function diffTable(files, { showTotal, collapseUnchanged, omitUnchanged }) {
let out = `| Filename | Size | Change | |\n`;
out += `|:--- |:---:|:---:|:---:|\n`;

let outUnchanged = out;

let totalSize = 0;
let totalDelta = 0;
let unchanged = 0;
let changed = 0;
for (const file of files) {
const { filename, size, delta } = file;
totalSize += size;
totalDelta += delta;

const difference = (delta / size * 100) | 0;
let deltaText = getDeltaText(delta, difference);
let icon = iconForDifference(difference);
const s = `| \`${filename}\` | ${prettyBytes(size)} | ${deltaText} | ${icon} |\n`;
const isUnchanged = Math.abs(delta) < 1;

if (isUnchanged && omitUnchanged) continue;

if (isUnchanged && collapseUnchanged) {
unchanged++;
outUnchanged += s;
}
else {
changed++;
out += s;
}
}

// no changes, don't show an empty table
if (!changed) {
out = '';
}

if (unchanged) {
out += `\n<details><summary>ℹ️ <strong>View Unchanged</strong></summary>\n\n${outUnchanged}\n\n</details>\n\n`;
}

if (showTotal) {
const totalDifference = (totalDelta / totalSize * 100) | 0;
let totalDeltaText = getDeltaText(totalDelta, totalDifference);
let totalIcon = iconForDifference(totalDifference);
out = `**Total Size:** ${prettyBytes(totalSize)}\n\n${out}`;
out = `**Size Change:** ${totalDeltaText} ${totalIcon}\n\n${out}`;
}

return out;
}

function getDeltaText(delta, difference) {
let deltaText = (delta > 0 ? '+' : '') + prettyBytes(delta);
if (delta && Math.abs(delta) > 1) {
deltaText += ` (${Math.abs(difference)}%)`;
}
return deltaText;
}

function iconForDifference(difference) {
let icon = '';
if (difference >= 50) icon = '🆘';
else if (difference >= 20) icon = '🚨';
else if (difference >= 10) icon = '⚠️';
else if (difference >= 5) icon = '🔍';
else if (difference <= -50) icon = '🏆';
else if (difference <= -20) icon = '🎉';
else if (difference <= -10) icon = '👏';
else if (difference <= -5) icon = '✅';
return icon;
}

function toBool(v) {
return /^(1|true|yes)$/.test(v);
}

(async () => {
try {
const token = getInput('repo-token', { required: true });
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ inputs:
description: 'A regular expression to remove hashes from filenames. Submatches are turned into asterisks if present, otherwise the whole match is removed.'
use-check:
description: 'Report status as a CI Check instead of using a comment [experimental]'
minimum-change-threshold:
description: 'Consider files with changes below this threshold as unchanged. Specified in bytes.'
default: 1
pattern:
description: 'minimatch pattern of files to track'
default: '**/dist/**/*.js'
Expand Down
12 changes: 12 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
]
]
};
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
testEnvironment: 'node'
};
Loading

0 comments on commit beb53b9

Please sign in to comment.