From 49efc295c639840069791d8d1f47a24b5e8c7f34 Mon Sep 17 00:00:00 2001 From: rhysd Date: Sat, 7 Dec 2019 20:35:25 +0900 Subject: [PATCH] v1.6.1 --- package-lock.json | 50 +++++++++++++++++++-------------------- package.json | 10 ++++---- src/default_index_html.js | 20 ++++++++++++---- src/extract.js | 14 +++++------ src/git.js | 7 +++--- src/write.js | 50 +++++++++++++++++++++++---------------- 6 files changed, 85 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index ff935c780..a8e0580d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -256,9 +256,9 @@ } }, "@types/cheerio": { - "version": "0.22.14", - "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.14.tgz", - "integrity": "sha512-SVtcP2fvPYrebTwpyqxjxb7K5v3ZOAdH409yAEWFPpZThCSGa1K2IFfx6Rg6ttvThCBQXP4fU9WF94sqLoiQGg==", + "version": "0.22.15", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.15.tgz", + "integrity": "sha512-UGiiVtJK5niCqMKYmLEFz1Wl/3L5zF/u78lu8CwoUywWXRr9LDimeYuOzXVLXBMO758fcTdFtgjvqlztMH90MA==", "dev": true, "requires": { "@types/node": "*" @@ -369,12 +369,12 @@ } }, "@typescript-eslint/eslint-plugin": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.9.0.tgz", - "integrity": "sha512-98rfOt3NYn5Gr9wekTB8TexxN6oM8ZRvYuphPs1Atfsy419SDLYCaE30aJkRiiTCwGEY98vOhFsEVm7Zs4toQQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.10.0.tgz", + "integrity": "sha512-rT51fNLW0u3fnDGnAHVC5nu+Das+y2CpW10yqvf6/j5xbuUV3FxA3mBaIbM24CXODXjbgUznNb4Kg9XZOUxKAw==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "2.9.0", + "@typescript-eslint/experimental-utils": "2.10.0", "eslint-utils": "^1.4.3", "functional-red-black-tree": "^1.0.1", "regexpp": "^3.0.0", @@ -382,32 +382,32 @@ } }, "@typescript-eslint/experimental-utils": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.9.0.tgz", - "integrity": "sha512-0lOLFdpdJsCMqMSZT7l7W2ta0+GX8A3iefG3FovJjrX+QR8y6htFlFdU7aOVPL6pDvt6XcsOb8fxk5sq+girTw==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.10.0.tgz", + "integrity": "sha512-FZhWq6hWWZBP76aZ7bkrfzTMP31CCefVIImrwP3giPLcoXocmLTmr92NLZxuIcTL4GTEOE33jQMWy9PwelL+yQ==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/typescript-estree": "2.9.0", + "@typescript-eslint/typescript-estree": "2.10.0", "eslint-scope": "^5.0.0" } }, "@typescript-eslint/parser": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.9.0.tgz", - "integrity": "sha512-fJ+dNs3CCvEsJK2/Vg5c2ZjuQ860ySOAsodDPwBaVlrGvRN+iCNC8kUfLFL8cT49W4GSiLPa/bHiMjYXA7EhKQ==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.10.0.tgz", + "integrity": "sha512-wQNiBokcP5ZsTuB+i4BlmVWq6o+oAhd8en2eSm/EE9m7BgZUIfEeYFd6z3S+T7bgNuloeiHA1/cevvbBDLr98g==", "dev": true, "requires": { "@types/eslint-visitor-keys": "^1.0.0", - "@typescript-eslint/experimental-utils": "2.9.0", - "@typescript-eslint/typescript-estree": "2.9.0", + "@typescript-eslint/experimental-utils": "2.10.0", + "@typescript-eslint/typescript-estree": "2.10.0", "eslint-visitor-keys": "^1.1.0" } }, "@typescript-eslint/typescript-estree": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.9.0.tgz", - "integrity": "sha512-v6btSPXEWCP594eZbM+JCXuFoXWXyF/z8kaSBSdCb83DF+Y7+xItW29SsKtSULgLemqJBT+LpT+0ZqdfH7QVmA==", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.10.0.tgz", + "integrity": "sha512-oOYnplddQNm/LGVkqbkAwx4TIBuuZ36cAQq9v3nFIU9FmhemHuVzAesMSXNQDdAzCa5bFgCrfD3JWhYVKlRN2g==", "dev": true, "requires": { "debug": "^4.1.1", @@ -1039,9 +1039,9 @@ "dev": true }, "eslint": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.1.tgz", - "integrity": "sha512-UWzBS79pNcsDSxgxbdjkmzn/B6BhsXMfUaOHnNwyE8nD+Q6pyT96ow2MccVayUTV4yMid4qLhMiQaywctRkBLA==", + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.7.2.tgz", + "integrity": "sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -3221,9 +3221,9 @@ "dev": true }, "typescript": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.2.tgz", - "integrity": "sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.3.tgz", + "integrity": "sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==", "dev": true }, "uc.micro": { diff --git a/package.json b/package.json index 547a62110..8a72e3177 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "@types/acorn": "^4.0.5", - "@types/cheerio": "^0.22.14", + "@types/cheerio": "^0.22.15", "@types/deep-diff": "^1.0.0", "@types/deep-equal": "^1.0.1", "@types/markdown-it": "0.0.9", @@ -48,13 +48,13 @@ "@types/mock-require": "^2.0.0", "@types/node": "^12.12.14", "@types/rimraf": "^2.0.3", - "@typescript-eslint/eslint-plugin": "^2.9.0", - "@typescript-eslint/parser": "^2.9.0", + "@typescript-eslint/eslint-plugin": "^2.10.0", + "@typescript-eslint/parser": "^2.10.0", "acorn": "^7.1.0", "cheerio": "^1.0.0-rc.3", "deep-diff": "^1.0.2", "deep-equal": "^1.1.1", - "eslint": "^6.7.1", + "eslint": "^6.7.2", "eslint-config-prettier": "^6.7.0", "eslint-plugin-mocha": "^6.2.2", "eslint-plugin-prettier": "^3.1.1", @@ -66,7 +66,7 @@ "nyc": "^14.1.1", "prettier": "^1.19.1", "rimraf": "^3.0.0", - "typescript": "^3.7.2" + "typescript": "^3.7.3" }, "husky": { "hooks": { diff --git a/src/default_index_html.js b/src/default_index_html.js index 9e0f30c5b..5667b96cd 100644 --- a/src/default_index_html.js +++ b/src/default_index_html.js @@ -45,9 +45,18 @@ exports.DEFAULT_INDEX_HTML = String.raw ` } button:hover { background-color: #2793da; + flex: none; + } + .spacer { + flex: auto; + } + .small { + font-size: 0.75rem; } footer { margin-top: 16px; + display: flex; + align-items: center; } .header-label { margin-right: 4px; @@ -91,7 +100,11 @@ exports.DEFAULT_INDEX_HTML = String.raw `
- + @@ -235,16 +248,13 @@ exports.DEFAULT_INDEX_HTML = String.raw ` renderBenchSet(name, benchset); } - const dlButton = document.createElement('button'); - dlButton.textContent = 'Download data as JSON'; - dlButton.onclick = () => { + document.getElementById('dl-button').onclick = () => { const dataUrl = 'data:,' + JSON.stringify(data, null, 2); const a = document.createElement('a'); a.href = dataUrl; a.download = 'benchmark_data.json'; a.click(); }; - document.getElementById('footer').appendChild(dlButton); })(); diff --git a/src/extract.js b/src/extract.js index c6793878f..76e865f18 100644 --- a/src/extract.js +++ b/src/extract.js @@ -10,17 +10,17 @@ Object.defineProperty(exports, "__esModule", { value: true }); const fs_1 = require("fs"); const github = __importStar(require("@actions/github")); function getHumanReadableUnitValue(seconds) { - if (seconds > 0) { - return [seconds, 'sec']; - } - else if (seconds > 1.0e-3) { - return [seconds * 1e3, 'msec']; + if (seconds < 1.0e-6) { + return [seconds * 1e9, 'nsec']; } - else if (seconds > 1.0e-6) { + else if (seconds < 1.0e-3) { return [seconds * 1e6, 'usec']; } + else if (seconds < 1.0) { + return [seconds * 1e3, 'msec']; + } else { - return [seconds * 1e9, 'nsec']; + return [seconds, 'sec']; } } function extractCargoResult(output) { diff --git a/src/git.js b/src/git.js index 2d4449d8e..24e418ffd 100644 --- a/src/git.js +++ b/src/git.js @@ -31,9 +31,8 @@ async function capture(cmd, args) { return res; } catch (err) { - const info = JSON.stringify(res); - const msg = `Command '${cmd}' failed with args '${args.join(' ')}': ${info}`; - core.debug(msg); + const msg = `Command '${cmd}' failed with args '${args.join(' ')}': ${err}`; + core.debug(`@actions/exec.exec() threw an error: ${msg}`); throw new Error(msg); } } @@ -42,7 +41,7 @@ async function cmd(...args) { const userArgs = ['-c', 'user.name=github-action-benchmark', '-c', 'user.email=github@users.noreply.github.com']; const res = await capture('git', userArgs.concat(args)); if (res.code !== 0) { - throw new Error(`Command 'git ${args.join(' ')}' failed: ${res}`); + throw new Error(`Command 'git ${args.join(' ')}' failed: ${JSON.stringify(res)}`); } return res.stdout; } diff --git a/src/write.js b/src/write.js index a68f00bd4..4dafbb5f8 100644 --- a/src/write.js +++ b/src/write.js @@ -80,7 +80,8 @@ function findAlerts(curSuite, prevSuite, threshold) { ? prev.value / current.value // e.g. current=100, prev=200 : current.value / prev.value; // e.g. current=200, prev=100 if (ratio > threshold) { - core.warning(`Performance alert! Previous value was ${prev.value} and current value is ${current.value}. Ratio ${ratio} is bigger than threshold ${threshold}`); + core.warning(`Performance alert! Previous value was ${prev.value} and current value is ${current.value}.` + + ` It is ${ratio}x worse than previous exceeding a ratio threshold ${threshold}`); alerts.push({ current, prev, ratio }); } } @@ -93,30 +94,34 @@ function getCurrentRepo() { } return repo; } +function floatStr(n) { + return Number.isInteger(n) ? n.toFixed(1) : n.toString(); +} function buildAlertComment(alerts, benchName, curSuite, prevSuite, threshold, cc) { var _a; + function strVal(b) { + let s = `\`${b.value}\` ${b.unit}`; + if (b.range) { + s += ` (\`${b.range}\`)`; + } + return s; + } // Do not show benchmark name if it is the default value 'Benchmark'. const benchmarkText = benchName === 'Benchmark' ? '' : ` **'${benchName}'**`; const title = threshold === 0 ? '# Performance Report' : '# :warning: **Performance Alert** :warning:'; + const thresholdString = floatStr(threshold); const lines = [ title, '', `Possible performance regression was detected for benchmark${benchmarkText}.`, - `Benchmark result of this commit is worse than the previous benchmark result exceeding threshold \`${threshold}\`.`, + `Benchmark result of this commit is worse than the previous benchmark result exceeding threshold \`${thresholdString}\`.`, '', `| Benchmark suite | Current: ${curSuite.commit.id} | Previous: ${prevSuite.commit.id} | Ratio |`, '|-|-|-|-|', ]; - function strOfValue(b) { - let s = `\`${b.value}\` ${b.unit}`; - if (b.range) { - s += ` (\`${b.range}\`)`; - } - return s; - } for (const alert of alerts) { const { current, prev, ratio } = alert; - const line = `| \`${current.name}\` | ${strOfValue(current)} | ${strOfValue(prev)} | \`${ratio}\` |`; + const line = `| \`${current.name}\` | ${strVal(current)} | ${strVal(prev)} | \`${floatStr(ratio)}\` |`; lines.push(line); } const repo = getCurrentRepo(); @@ -176,19 +181,19 @@ async function handleAlert(benchName, curSuite, prevSuite, config) { if (failOnAlert) { // Note: alertThreshold is smaller than failThreshold. It was checked in config.ts const len = alerts.length; + const threshold = floatStr(failThreshold); const failures = alerts.filter(a => a.ratio > failThreshold); if (failures.length > 0) { core.debug('Mark this workflow as fail since one or more fatal alerts found'); if (failThreshold !== alertThreshold) { // Prepend message that explains how these alerts were detected with different thresholds - message = - `${failures.length} of ${len} alerts exceeded the failure threshold \`${failThreshold}\` specified by fail-threshold input:\n\n` + - message; + message = `${failures.length} of ${len} alerts exceeded the failure threshold \`${threshold}\` specified by fail-threshold input:\n\n${message}`; } throw new Error(message); } else { - core.debug(`${len} alerts were found but all of them did not exceed failure threshold ${failThreshold}`); + core.debug(`${len} alerts exceeding the alert threshold ${alertThreshold} were found but` + + ` all of them did not exceed the failure threshold ${threshold}`); } } } @@ -221,6 +226,12 @@ function addBenchmarkToDataJson(benchName, bench, data, maxItems) { } return prevBench; } +function isRemoteRejectedError(err) { + if (err instanceof Error) { + return ['[remote rejected]', '[rejected]'].some(l => err.message.includes(l)); + } + return false; +} async function writeBenchmarkToGitHubPagesWithRetry(bench, config, retry) { var _a, _b; const { name, tool, ghPagesBranch, benchmarkDataDirPath, githubToken, autoPush, skipFetchGhPages, maxItemsInChart, } = config; @@ -229,7 +240,7 @@ async function writeBenchmarkToGitHubPagesWithRetry(bench, config, retry) { if (!skipFetchGhPages && (!isPrivateRepo || githubToken)) { await git.pull(githubToken, ghPagesBranch); } - else if (isPrivateRepo) { + else if (isPrivateRepo && !skipFetchGhPages) { core.warning("'git pull' was skipped. If you want to ensure GitHub Pages branch is up-to-date " + "before generating a commit, please set 'github-token' input to pull GitHub pages branch"); } @@ -246,7 +257,7 @@ async function writeBenchmarkToGitHubPagesWithRetry(bench, config, retry) { console.log(`Automatically pushed the generated commit to ${ghPagesBranch} branch since 'auto-push' is set to true`); } catch (err) { - if (!(err instanceof Error) || !err.message.includes('[remote rejected]')) { + if (!isRemoteRejectedError(err)) { throw err; } // Fall through @@ -258,19 +269,18 @@ async function writeBenchmarkToGitHubPagesWithRetry(bench, config, retry) { return await writeBenchmarkToGitHubPagesWithRetry(bench, config, retry - 1); // Recursively retry } else { - core.warning(`Failed to add benchmark data to '${name}' suite: ${JSON.stringify(bench, null, 2)}`); + core.warning(`Failed to add benchmark data to '${name}' data: ${JSON.stringify(bench)}`); throw new Error(`Auto-push failed 3 times since the remote branch ${ghPagesBranch} rejected pushing all the time. Last exception was: ${err.message}`); } } } else { - core.debug(`Auto-push to ${ghPagesBranch} is skipped because it requires both github-token and auto-push`); + core.debug(`Auto-push to ${ghPagesBranch} is skipped because it requires both 'github-token' and 'auto-push' inputs`); } return prevBench; } async function writeBenchmarkToGitHubPages(bench, config) { - const { ghPagesBranch } = config; - await git.cmd('switch', ghPagesBranch); + await git.cmd('switch', config.ghPagesBranch); try { return await writeBenchmarkToGitHubPagesWithRetry(bench, config, 2); }