Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check min coverage, ignore node_modules during pacakge tranversal, refactor the code, etc. #55

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ module.exports = {
"generator-star-spacing": ["error", { before: false, after: true }],
"jsx-quotes": ["error", "prefer-double"],
"max-depth": ["error", 10],
"newline-before-return": "error",
"no-alert": "error",
"no-confusing-arrow": ["error", { allowParens: false }],
"no-constant-condition": "error",
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ node_modules/
coverage/
.eslintcache
.DS_Store
.idea
badges/
26 changes: 26 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,32 @@ inputs:
app-name:
description: App name to display on comment
required: false
max_lines:
description: Maximum numbers of line print
required: false
default: "15"
min_coverage:
description: Minimum coverage percentage allowed
required: false
default: "100"
exclude:
description: list of files you would like to exclude from min_coverage check
required: false
exclude_root:
description: exclude the root project coverage from min_coverage check
required: false
badge_path:
description: Output badge path.
default: build
required: false
badge_style:
description: 'Badges style: flat, classic.'
default: classic
required: false
badge_label:
description: The left label of the badge, usually static.
default: coverage
required: false
runs:
using: node16
main: dist/main.js
4 changes: 2 additions & 2 deletions dist/main.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"dependencies": {
"@actions/core": "^1.10.0",
"@actions/github": "^4.0.0",
"badgen": "^3.2.3",
"lcov-parse": "^1.0.0"
},
"devDependencies": {
Expand Down
49 changes: 49 additions & 0 deletions src/badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import path from "path";
import fs from "fs";
import { badgen } from "badgen";
import { percentage } from "./lcov";

const badge = (option, pct) => {
const { label = "coverage", style = "classic" } = option || {};
const colorData = {
"49c31a": [100],
"97c40f": [99.99, 90],
a0a127: [89.99, 80],
cba317: [79.99, 60],
ce0000: [59.99, 0],
};
const color = Object.keys(colorData).find(
(value) =>
(colorData[value].length === 1 && pct >= colorData[value][0]) ||
(colorData[value].length === 2 &&
pct <= colorData[value][0] &&
pct >= colorData[value][1]),
);
const badgenArgs = {
style,
label,
status: `${pct < 0 ? "Unknown" : `${pct}%`}`,
color: color || "e5e5e5",
};
return badgen(badgenArgs);
};

export const createBadges = (badgePath, toCheck, options) => {
const dirName = path.resolve(badgePath);
if (!fs.existsSync(dirName)) {
fs.mkdirSync(dirName);
} else if (!fs.statSync(dirName).isDirectory()) {
throw new Error("badge path is not a directory");
}
for (const lcovObj of toCheck) {
const coverage = percentage(lcovObj.lcov);
const svgStr = badge(options, coverage.toFixed(2));
const fileName = path.join(dirName, `${lcovObj.packageName}.svg`);
console.log("writing badge", fileName);
try {
fs.writeFileSync(fileName, svgStr);
} catch (err) {
console.error("Error writing badge", fileName, err.toString());
}
}
};
19 changes: 19 additions & 0 deletions src/check.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { percentage } from "./lcov";

export const checkCoverage = (minCoverage, toCheck) => {
let accum = 0;
for (const lcovObj of toCheck) {
const coverage = percentage(lcovObj.lcov);
const isValidBuild = coverage >= minCoverage;
if (!isValidBuild) {
return { isValidBuild, coverage, name: lcovObj.packageName };
}
accum += coverage;
}

return {
isValidBuild: true,
coverage: toCheck.length === 0 ? 0 : accum / toCheck.length,
name: "average",
};
};
60 changes: 46 additions & 14 deletions src/cli.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,64 @@
import process from "process";
import { promises as fs } from "fs";
import fs from "fs";
import path from "path";
import { parse } from "./lcov";
import { diff } from "./comment";
import { diff, diffForMonorepo } from "./comment";
import { getLcovArray, readLcov } from "./monorepo";
import { checkCoverage } from "./check";
import { createBadges } from "./badge";

const addPackageName = (x) => ({
...x,
...{ packageName: x.dir.split("/").slice(-2)[0] },
});
const main = async () => {
const file = process.argv[2];
const beforeFile = process.argv[3];
const prefix = `${path.dirname(path.dirname(path.resolve(file)))}/`;

const content = await fs.readFile(file, "utf-8");
const lcov = await parse(content);

let before;
if (beforeFile) {
const contentBefore = await fs.readFile(beforeFile, "utf-8");
before = await parse(contentBefore);
}

const prefix = `${path.dirname(path.dirname(path.resolve(file)))}/`;
const options = {
repository: "example/foo",
commit: "f9d42291812ed03bb197e48050ac38ac6befe4e5",
prefix,
head: "feat/test",
base: "master",
maxLines: "10",
};

console.log(diff(lcov, before, options));
if (fs.statSync(file).isDirectory()) {
const lcovArrayForMonorepo = (
await getLcovArray(file, "lcov.info")
).map(addPackageName);
console.log(
diffForMonorepo(
lcovArrayForMonorepo,
await getLcovArray(file, "lcov-base"),
options,
),
);
createBadges("./badges", lcovArrayForMonorepo, {});
console.log(checkCoverage(90, lcovArrayForMonorepo));
} else {
const lcov = await readLcov(file);
console.log(
diff(lcov, beforeFile && (await readLcov(beforeFile)), options),
);
createBadges(
"./build",
{
packageName: "root",
lcov,
},
{},
);
console.log(
checkCoverage(90, [
{
packageName: "root",
lcov,
},
]),
);
}
};

main().catch((err) => {
Expand Down
Loading