coverage-check 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +119 -3
- package/dist/src/cli.mjs +25 -0
- package/dist/src/commands/check-args.d.mts +6 -0
- package/dist/src/commands/check-args.mjs +20 -2
- package/dist/src/commands/check-output.d.mts +5 -0
- package/dist/src/commands/check-output.mjs +15 -10
- package/dist/src/commands/check-render.d.mts +1 -0
- package/dist/src/commands/check-render.mjs +27 -0
- package/dist/src/commands/check-result.d.mts +17 -0
- package/dist/src/commands/check-result.mjs +12 -0
- package/dist/src/commands/check.d.mts +21 -0
- package/dist/src/commands/check.mjs +150 -49
- package/dist/src/commands/prepare-artifacts.d.mts +18 -0
- package/dist/src/commands/prepare-artifacts.mjs +105 -0
- package/dist/src/coverage-check.d.mts +6 -2
- package/dist/src/coverage-check.mjs +4 -1
- package/dist/src/github-comment.mjs +6 -4
- package/dist/src/lcov-records.mjs +13 -4
- package/dist/src/rules.d.mts +4 -0
- package/dist/src/rules.mjs +10 -0
- package/dist/src/s3-diagnostics.d.mts +9 -0
- package/dist/src/s3-diagnostics.mjs +60 -0
- package/dist/src/s3-suite-store-reads.d.mts +17 -0
- package/dist/src/s3-suite-store-reads.mjs +57 -0
- package/dist/src/s3-suite-store.d.mts +7 -10
- package/dist/src/s3-suite-store.mjs +68 -75
- package/dist/src/suite-store.d.mts +1 -0
- package/dist/src/suite-store.mjs +22 -2
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -51,12 +51,29 @@ The `--suite` flag on `check` tells the tool to use fresh `--artifacts` for the
|
|
|
51
51
|
**S3 key layout:**
|
|
52
52
|
|
|
53
53
|
```text
|
|
54
|
-
<prefix>/<suite>/sha/<sha>/lcov.info
|
|
55
|
-
<prefix>/<suite>/branch/<encoded-branch>/latest.json # pointer
|
|
54
|
+
<prefix>/<suite>/sha/<sha>/lcov.info.gz # gzip payload for new versioned writes
|
|
55
|
+
<prefix>/<suite>/branch/<encoded-branch>/latest.json # pointer with sha, payloadKey, encoding, byte counts, timestamp
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
S3-backed stores need `s3:PutObject` for writes and `s3:GetObject` for reading branch pointers and baselines. The pointer reader also checks the previous unencoded pointer key (for example `branch/main/latest.json`) so stores written before branch-name encoding remain readable.
|
|
59
59
|
|
|
60
|
+
Versioned S3 writes (`store-put --sha ... --branch ...`) gzip the LCOV payload and write pointer
|
|
61
|
+
metadata with `payloadKey`, `encoding`, `rawBytes`, and `storedBytes`. Existing raw
|
|
62
|
+
`sha/<sha>/lcov.info` payloads and legacy `<suite>/lcov.info` payloads remain readable. Legacy
|
|
63
|
+
writes without `--sha`/`--branch` keep the old raw `<suite>/lcov.info` layout.
|
|
64
|
+
|
|
65
|
+
Every S3 operation logs a concise diagnostic line to stderr with the operation name, bucket, key,
|
|
66
|
+
elapsed time, and byte counts where applicable. Use these lines to distinguish payload writes,
|
|
67
|
+
branch-pointer reads, and branch-pointer writes when CI storage stalls.
|
|
68
|
+
|
|
69
|
+
S3 request bounds are configurable with environment variables:
|
|
70
|
+
|
|
71
|
+
| Variable | Default | Purpose |
|
|
72
|
+
| ----------------------------------------- | ------- | ---------------------------------------- |
|
|
73
|
+
| `COVERAGE_CHECK_S3_CONNECTION_TIMEOUT_MS` | `5000` | Socket connection timeout for S3 calls |
|
|
74
|
+
| `COVERAGE_CHECK_S3_REQUEST_TIMEOUT_MS` | `30000` | Whole-request timeout for S3 calls |
|
|
75
|
+
| `COVERAGE_CHECK_S3_MAX_ATTEMPTS` | `2` | AWS SDK attempt count, including retries |
|
|
76
|
+
|
|
60
77
|
### Suite store with filesystem
|
|
61
78
|
|
|
62
79
|
For local development or simpler deployments:
|
|
@@ -145,6 +162,22 @@ coverage-check check \
|
|
|
145
162
|
--advisory
|
|
146
163
|
```
|
|
147
164
|
|
|
165
|
+
For wrappers that need machine-readable advisory results without a temp file, pass `--json -`.
|
|
166
|
+
This writes JSON-only output to stdout and suppresses the human report:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
coverage-check check \
|
|
170
|
+
--rules .coverage-rules.yml \
|
|
171
|
+
--artifacts ./coverage-artifacts \
|
|
172
|
+
--base origin/main \
|
|
173
|
+
--head HEAD \
|
|
174
|
+
--advisory \
|
|
175
|
+
--json -
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
JSON output keeps the normal check result fields (`passed`, `buckets`, `drops`, `informational`) and
|
|
179
|
+
adds `exitCode`, `advisory`, and `skipped`.
|
|
180
|
+
|
|
148
181
|
### PR-scoped regression gate
|
|
149
182
|
|
|
150
183
|
By default, `no_coverage_drop` applies to every rule area regardless of what changed. Pass `--drop-only-changed-areas` to restrict the drop gate to rule areas that contain at least one changed file in the PR diff. Areas with no changed files are reported as `skipped` — they pass non-blockingly:
|
|
@@ -174,6 +207,24 @@ coverage-check check \
|
|
|
174
207
|
|
|
175
208
|
`--require-artifact` is also accepted by `coverage-check merge`.
|
|
176
209
|
|
|
210
|
+
### Preparing fan-in artifacts
|
|
211
|
+
|
|
212
|
+
Use `prepare-artifacts` before a fan-in coverage check when downloaded artifacts may be either
|
|
213
|
+
nested as `coverage-<suite>/lcov.info` or flattened to a root-level `lcov.info`. Pass one
|
|
214
|
+
`--expect-suite <job>=<suite>` for each successful coverage producer. The command normalizes a
|
|
215
|
+
single flat LCOV into the expected suite directory and fails if any expected LCOV is missing:
|
|
216
|
+
|
|
217
|
+
```sh
|
|
218
|
+
coverage-check prepare-artifacts \
|
|
219
|
+
--artifacts ./coverage-artifacts \
|
|
220
|
+
--expect-suite test-backend=backend \
|
|
221
|
+
--expect-suite test-web=web
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
For local or fan-in wrappers, `check --aggregate-artifacts` treats all fresh LCOV files as one source
|
|
225
|
+
for diagnostics, `check --fail-on-empty` exits `1` instead of skipping when no LCOV exists, and
|
|
226
|
+
`check --ignore-path <glob>` prepends a zero-threshold override for CI-only paths in that run.
|
|
227
|
+
|
|
177
228
|
## Rules file
|
|
178
229
|
|
|
179
230
|
```yaml
|
|
@@ -218,6 +269,8 @@ First-match-wins means that if you have a more specific rule before a broader on
|
|
|
218
269
|
|
|
219
270
|
## CLI reference
|
|
220
271
|
|
|
272
|
+
Run `coverage-check --help` or `coverage-check check --help` to print the available commands and check flags.
|
|
273
|
+
|
|
221
274
|
### `coverage-check check`
|
|
222
275
|
|
|
223
276
|
| Flag | Default | Description |
|
|
@@ -234,11 +287,14 @@ First-match-wins means that if you have a more specific rule before a broader on
|
|
|
234
287
|
| `--strip-prefix` | — | Extra path prefix to strip from LCOV `SF:` lines (repeatable) |
|
|
235
288
|
| `--pr` | — | Pull request number for sticky comment |
|
|
236
289
|
| `--repo` | `$GITHUB_REPOSITORY` | `owner/repo` for sticky comment |
|
|
237
|
-
| `--json` | — | Write JSON result to this path
|
|
290
|
+
| `--json` | — | Write JSON result to this path; use `-` for JSON-only stdout |
|
|
238
291
|
| `--annotate-source` | — | Print the trimmed source text of each uncovered line in stdout (does not alter PR comment or step summary) |
|
|
239
292
|
| `--advisory` | — | Exit `0` even on shortfall; still prints, writes JSON, and posts PR comment |
|
|
240
293
|
| `--drop-only-changed-areas` | — | Restrict `no_coverage_drop` to rule areas that have ≥1 changed file; others are reported as skipped |
|
|
241
294
|
| `--require-artifact` | — | Fail (exit `2`) if this relative path is absent under `--artifacts` (repeatable) |
|
|
295
|
+
| `--fail-on-empty` | — | Exit `1` when no coverage data is found instead of skipping |
|
|
296
|
+
| `--aggregate-artifacts` | — | Treat fresh LCOV files as one source for diagnostics and summaries |
|
|
297
|
+
| `--ignore-path` | — | Prepend a zero-threshold override glob for this run (repeatable) |
|
|
242
298
|
|
|
243
299
|
### `coverage-check merge`
|
|
244
300
|
|
|
@@ -251,6 +307,13 @@ First-match-wins means that if you have a more specific rule before a broader on
|
|
|
251
307
|
|
|
252
308
|
Hit counts are summed across all inputs. Function (`FN`/`FNDA`) and branch (`BRDA`) records are preserved; summary counters (`LF/LH/FNF/FNH/BRF/BRH`) are recomputed from the merged data.
|
|
253
309
|
|
|
310
|
+
### `coverage-check prepare-artifacts`
|
|
311
|
+
|
|
312
|
+
| Flag | Default | Description |
|
|
313
|
+
| ---------------- | ---------------------- | ---------------------------------------------- |
|
|
314
|
+
| `--artifacts` | `./coverage-artifacts` | Coverage artifact directory to normalize/check |
|
|
315
|
+
| `--expect-suite` | — | Expected producer and suite as `<job>=<suite>` |
|
|
316
|
+
|
|
254
317
|
### `coverage-check store-put`
|
|
255
318
|
|
|
256
319
|
| Flag | Default | Description |
|
|
@@ -272,10 +335,15 @@ When `--sha` and `--branch` are both provided, `store-put` writes a SHA-addresse
|
|
|
272
335
|
|
|
273
336
|
```ts
|
|
274
337
|
import {
|
|
338
|
+
checkCoverage,
|
|
339
|
+
evaluateCheck,
|
|
275
340
|
runCheck,
|
|
276
341
|
runMerge,
|
|
277
342
|
runStorePut,
|
|
343
|
+
prepareCoverageArtifacts,
|
|
278
344
|
collapseRanges,
|
|
345
|
+
collectLcovFiles,
|
|
346
|
+
zeroThresholdGlobs,
|
|
279
347
|
parseLcovFull,
|
|
280
348
|
mergeLcovFull,
|
|
281
349
|
toLcovFull,
|
|
@@ -289,6 +357,27 @@ const fsStore = new FileSystemSuiteStore("/path/to/store");
|
|
|
289
357
|
// S3 store (requires AWS credentials — see https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/setting-credentials-node.html)
|
|
290
358
|
const s3Store = new S3SuiteStore({ bucket: "my-bucket", prefix: "coverage" });
|
|
291
359
|
|
|
360
|
+
const check = await checkCoverage({
|
|
361
|
+
rules: ".coverage-rules.yml",
|
|
362
|
+
artifacts: "./coverage",
|
|
363
|
+
base: "origin/main",
|
|
364
|
+
head: "HEAD",
|
|
365
|
+
pr: null,
|
|
366
|
+
repo: "",
|
|
367
|
+
json: null,
|
|
368
|
+
stripPrefixes: [],
|
|
369
|
+
store: s3Store,
|
|
370
|
+
suite: "backend",
|
|
371
|
+
branch: "main",
|
|
372
|
+
advisory: true,
|
|
373
|
+
dropOnlyChangedAreas: false,
|
|
374
|
+
requireArtifacts: [],
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
if (!check.result?.passed) {
|
|
378
|
+
console.log(check.exitCode, check.advisory, check.result);
|
|
379
|
+
}
|
|
380
|
+
|
|
292
381
|
await runCheck({
|
|
293
382
|
rules: ".coverage-rules.yml",
|
|
294
383
|
artifacts: "./coverage",
|
|
@@ -304,7 +393,34 @@ await runCheck({
|
|
|
304
393
|
advisory: false,
|
|
305
394
|
dropOnlyChangedAreas: false,
|
|
306
395
|
requireArtifacts: [],
|
|
396
|
+
failOnEmpty: false,
|
|
397
|
+
aggregateArtifacts: false,
|
|
398
|
+
ignorePaths: [],
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
const evaluated = await evaluateCheck({
|
|
402
|
+
rules: ".coverage-rules.yml",
|
|
403
|
+
artifacts: "./coverage",
|
|
404
|
+
base: "origin/main",
|
|
405
|
+
head: "HEAD",
|
|
406
|
+
pr: null,
|
|
407
|
+
repo: "",
|
|
408
|
+
json: null,
|
|
409
|
+
stripPrefixes: [],
|
|
410
|
+
store: null,
|
|
411
|
+
suite: null,
|
|
307
412
|
});
|
|
413
|
+
if (evaluated.result?.passed === false) {
|
|
414
|
+
// Integrations can render their own advisory output from the typed result.
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
prepareCoverageArtifacts({
|
|
418
|
+
artifacts: "./coverage-artifacts",
|
|
419
|
+
expectedSuites: [{ job: "test-backend", suite: "backend" }],
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
collectLcovFiles("./coverage-artifacts");
|
|
423
|
+
zeroThresholdGlobs(".coverage-rules.yml");
|
|
308
424
|
|
|
309
425
|
await runMerge({
|
|
310
426
|
artifacts: "./coverage-artifacts",
|
package/dist/src/cli.mjs
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { main as checkMain } from "./commands/check.mjs";
|
|
2
|
+
import { checkHelp } from "./commands/check-render.mjs";
|
|
2
3
|
import { main as storePutMain } from "./commands/store-put.mjs";
|
|
3
4
|
import { main as htmlMain } from "./commands/html.mjs";
|
|
4
5
|
import { main as mergeMain } from "./commands/merge.mjs";
|
|
5
6
|
import { main as summaryMain } from "./commands/summary.mjs";
|
|
7
|
+
import { main as prepareArtifactsMain } from "./commands/prepare-artifacts.mjs";
|
|
6
8
|
const stderr = (msg) => process.stderr.write(`${msg}\n`);
|
|
9
|
+
const stdout = (msg) => process.stdout.write(`${msg}\n`);
|
|
7
10
|
export async function main(argv) {
|
|
8
11
|
const sub = argv[0];
|
|
12
|
+
if (sub === "--help" || sub === "-h") {
|
|
13
|
+
stdout(help());
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
9
16
|
if (!sub || sub.startsWith("-"))
|
|
10
17
|
return checkMain(argv);
|
|
11
18
|
if (sub === "check")
|
|
@@ -18,6 +25,24 @@ export async function main(argv) {
|
|
|
18
25
|
return htmlMain(argv.slice(1));
|
|
19
26
|
if (sub === "summary")
|
|
20
27
|
return summaryMain(argv.slice(1));
|
|
28
|
+
if (sub === "prepare-artifacts")
|
|
29
|
+
return prepareArtifactsMain(argv.slice(1));
|
|
21
30
|
stderr(`coverage-check: unknown subcommand: ${JSON.stringify(sub)}`);
|
|
22
31
|
return 2;
|
|
23
32
|
}
|
|
33
|
+
function help() {
|
|
34
|
+
return `coverage-check
|
|
35
|
+
|
|
36
|
+
Usage:
|
|
37
|
+
coverage-check <command> [options]
|
|
38
|
+
coverage-check [check options]
|
|
39
|
+
|
|
40
|
+
Commands:
|
|
41
|
+
check Check patch coverage (default)
|
|
42
|
+
store-put Store suite LCOV data
|
|
43
|
+
merge Merge lcov.info files
|
|
44
|
+
html Generate HTML coverage reports
|
|
45
|
+
summary Generate a coverage summary
|
|
46
|
+
|
|
47
|
+
${checkHelp()}`;
|
|
48
|
+
}
|
|
@@ -24,5 +24,11 @@ export type CheckArgs = {
|
|
|
24
24
|
dropOnlyChangedAreas?: boolean;
|
|
25
25
|
/** Relative paths under --artifacts that must exist before the check runs (repeatable). */
|
|
26
26
|
requireArtifacts?: string[];
|
|
27
|
+
/** Exit non-zero when no LCOV data is available instead of treating the check as skipped. */
|
|
28
|
+
failOnEmpty?: boolean;
|
|
29
|
+
/** Merge fresh LCOV artifacts before evaluating, so fan-in artifacts are treated as one source. */
|
|
30
|
+
aggregateArtifacts?: boolean;
|
|
31
|
+
/** Path globs to exempt by prepending zero-threshold override rules (repeatable). */
|
|
32
|
+
ignorePaths?: string[];
|
|
27
33
|
};
|
|
28
34
|
export declare function parseCheckArgs(argv: string[]): CheckArgs;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { makeStore } from "../store-factory.mjs";
|
|
2
|
-
import { assertSafePathComponent } from "../suite-store.mjs";
|
|
2
|
+
import { assertSafePathComponent, assertValidRepo } from "../suite-store.mjs";
|
|
3
3
|
export function parseCheckArgs(argv) {
|
|
4
4
|
let storeFs = null;
|
|
5
5
|
let storeS3 = null;
|
|
@@ -20,6 +20,9 @@ export function parseCheckArgs(argv) {
|
|
|
20
20
|
advisory: false,
|
|
21
21
|
dropOnlyChangedAreas: false,
|
|
22
22
|
requireArtifacts: [],
|
|
23
|
+
failOnEmpty: false,
|
|
24
|
+
aggregateArtifacts: false,
|
|
25
|
+
ignorePaths: [],
|
|
23
26
|
};
|
|
24
27
|
for (let i = 0; i < argv.length; i++) {
|
|
25
28
|
const flag = argv[i];
|
|
@@ -92,14 +95,29 @@ export function parseCheckArgs(argv) {
|
|
|
92
95
|
case "--require-artifact":
|
|
93
96
|
args.requireArtifacts.push(val());
|
|
94
97
|
break;
|
|
98
|
+
case "--fail-on-empty":
|
|
99
|
+
args.failOnEmpty = true;
|
|
100
|
+
break;
|
|
101
|
+
case "--aggregate-artifacts":
|
|
102
|
+
args.aggregateArtifacts = true;
|
|
103
|
+
break;
|
|
104
|
+
case "--ignore-path":
|
|
105
|
+
args.ignorePaths.push(val());
|
|
106
|
+
break;
|
|
95
107
|
default:
|
|
96
108
|
throw new Error(`unknown flag: ${flag}`);
|
|
97
109
|
}
|
|
98
110
|
}
|
|
99
111
|
if (storeFs && storeS3)
|
|
100
112
|
throw new Error("--store-fs and --store-s3 are mutually exclusive");
|
|
101
|
-
|
|
113
|
+
const repo = args.repo.trim();
|
|
114
|
+
args.repo = repo;
|
|
115
|
+
if (args.pr !== null && repo.length === 0) {
|
|
102
116
|
throw new Error("--repo is required when --pr is set (or define GITHUB_REPOSITORY)");
|
|
117
|
+
}
|
|
118
|
+
if (repo !== "") {
|
|
119
|
+
args.repo = assertValidRepo(repo);
|
|
120
|
+
}
|
|
103
121
|
args.store = makeStore({ fs: storeFs, s3: storeS3 });
|
|
104
122
|
return args;
|
|
105
123
|
}
|
|
@@ -4,8 +4,13 @@ import type { DropResult, DiffLines, LcovData } from "../types.mts";
|
|
|
4
4
|
* Prints `::error::` to stderr for each missing file and returns false if any are absent.
|
|
5
5
|
*/
|
|
6
6
|
export declare function checkRequiredArtifacts(artifactsDir: string, requireArtifacts: string[]): boolean;
|
|
7
|
+
export declare function missingRequiredArtifacts(artifactsDir: string, requireArtifacts: string[]): string[];
|
|
7
8
|
export declare function warnNonContributing(parsedSources: {
|
|
8
9
|
name: string;
|
|
9
10
|
lcov: LcovData;
|
|
10
11
|
}[], diff: DiffLines): void;
|
|
12
|
+
export declare function nonContributingWarnings(parsedSources: {
|
|
13
|
+
name: string;
|
|
14
|
+
lcov: LcovData;
|
|
15
|
+
}[], diff: DiffLines): string[];
|
|
11
16
|
export declare function printDropOutput(drops: DropResult[]): void;
|
|
@@ -26,23 +26,28 @@ function lcovContributesToDiff(sourceLcov, diff) {
|
|
|
26
26
|
* Prints `::error::` to stderr for each missing file and returns false if any are absent.
|
|
27
27
|
*/
|
|
28
28
|
export function checkRequiredArtifacts(artifactsDir, requireArtifacts) {
|
|
29
|
-
|
|
30
|
-
for (const rel of
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
return ok;
|
|
29
|
+
const missing = missingRequiredArtifacts(artifactsDir, requireArtifacts);
|
|
30
|
+
for (const rel of missing)
|
|
31
|
+
stderr(`::error:: missing expected coverage artifact: ${rel}`);
|
|
32
|
+
return missing.length === 0;
|
|
33
|
+
}
|
|
34
|
+
export function missingRequiredArtifacts(artifactsDir, requireArtifacts) {
|
|
35
|
+
return requireArtifacts.filter((rel) => !existsSync(join(artifactsDir, rel)));
|
|
37
36
|
}
|
|
38
37
|
export function warnNonContributing(parsedSources, diff) {
|
|
38
|
+
for (const warning of nonContributingWarnings(parsedSources, diff))
|
|
39
|
+
stderr(warning);
|
|
40
|
+
}
|
|
41
|
+
export function nonContributingWarnings(parsedSources, diff) {
|
|
39
42
|
if (diff.size === 0)
|
|
40
|
-
return;
|
|
43
|
+
return [];
|
|
44
|
+
const warnings = [];
|
|
41
45
|
for (const { name, lcov: sourceLcov } of parsedSources) {
|
|
42
46
|
if (!lcovContributesToDiff(sourceLcov, diff)) {
|
|
43
|
-
|
|
47
|
+
warnings.push(`coverage-check: warning: coverage from ${name} contributed 0 coverable lines to the patch result. This may indicate a path prefix mismatch.`);
|
|
44
48
|
}
|
|
45
49
|
}
|
|
50
|
+
return warnings;
|
|
46
51
|
}
|
|
47
52
|
export function printDropOutput(drops) {
|
|
48
53
|
if (drops.length === 0)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function checkHelp(): string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export function checkHelp() {
|
|
2
|
+
return `coverage-check check
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
coverage-check check [options]
|
|
6
|
+
coverage-check [options]
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--rules <path> Path to YAML rules file (default: .coverage-rules.yml)
|
|
10
|
+
--artifacts <dir> Directory to scan for lcov.info files (default: ./coverage-artifacts)
|
|
11
|
+
--base <ref> Base git ref for git diff (default: origin/main)
|
|
12
|
+
--head <ref> Head git ref for git diff (default: HEAD)
|
|
13
|
+
--store-fs <path> Path to a filesystem suite store directory
|
|
14
|
+
--store <path> Alias for --store-fs
|
|
15
|
+
--store-s3 <bucket[/prefix]> S3 suite store
|
|
16
|
+
--branch <name> Branch pointer to follow when reading from the store (default: main)
|
|
17
|
+
--suite <name> Name of the current suite
|
|
18
|
+
--strip-prefix <prefix> Extra path prefix to strip from LCOV SF: lines (repeatable)
|
|
19
|
+
--pr <number> Pull request number for sticky comment
|
|
20
|
+
--repo <owner/repo> Repository for sticky comment (default: $GITHUB_REPOSITORY)
|
|
21
|
+
--json <path|-> Write JSON result to a path, or JSON-only stdout with -
|
|
22
|
+
--annotate-source Print trimmed source text for each uncovered line
|
|
23
|
+
--advisory Exit 0 even on coverage shortfall
|
|
24
|
+
--drop-only-changed-areas Restrict no_coverage_drop to changed rule areas
|
|
25
|
+
--require-artifact <relpath> Fail if this path is absent under --artifacts (repeatable)
|
|
26
|
+
-h, --help Show this help`;
|
|
27
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CoverageCheckResult } from "../types.mts";
|
|
2
|
+
export type CheckRunResult = {
|
|
3
|
+
result: CoverageCheckResult | null;
|
|
4
|
+
exitCode: 0 | 1 | 2;
|
|
5
|
+
advisory: boolean;
|
|
6
|
+
skipped: boolean;
|
|
7
|
+
error: string | null;
|
|
8
|
+
warnings: string[];
|
|
9
|
+
};
|
|
10
|
+
export type CheckJsonPayload = CoverageCheckResult & {
|
|
11
|
+
exitCode: 0 | 1 | 2;
|
|
12
|
+
advisory: boolean;
|
|
13
|
+
skipped: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function emptyResult(passed: boolean): CoverageCheckResult;
|
|
17
|
+
export declare function toJsonPayload(check: CheckRunResult): CheckJsonPayload;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function emptyResult(passed) {
|
|
2
|
+
return { buckets: [], drops: [], informational: [], passed };
|
|
3
|
+
}
|
|
4
|
+
export function toJsonPayload(check) {
|
|
5
|
+
return {
|
|
6
|
+
...(check.result ?? emptyResult(false)),
|
|
7
|
+
exitCode: check.exitCode,
|
|
8
|
+
advisory: check.advisory,
|
|
9
|
+
skipped: check.skipped,
|
|
10
|
+
...(check.error === null ? {} : { error: check.error }),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
import type { CheckArgs } from "./check-args.mts";
|
|
2
|
+
import type { CheckRunResult } from "./check-result.mts";
|
|
3
|
+
import type { SuiteSource } from "../step-summary.mts";
|
|
4
|
+
import type { DiffLineContent, LcovData } from "../types.mts";
|
|
5
|
+
import type { CoverageCheckResult } from "../types.mts";
|
|
2
6
|
export type { CheckArgs } from "./check-args.mts";
|
|
7
|
+
export type { CheckRunResult } from "./check-result.mts";
|
|
8
|
+
export type EvaluatedCheck = {
|
|
9
|
+
exitCode: number;
|
|
10
|
+
result: CoverageCheckResult | null;
|
|
11
|
+
suiteSources: SuiteSource[];
|
|
12
|
+
runUrl: string;
|
|
13
|
+
branch: string;
|
|
14
|
+
diffContent: DiffLineContent | null;
|
|
15
|
+
skippedReason?: string;
|
|
16
|
+
parsedSources: {
|
|
17
|
+
name: string;
|
|
18
|
+
lcov: LcovData;
|
|
19
|
+
}[];
|
|
20
|
+
warnings: string[];
|
|
21
|
+
};
|
|
3
22
|
export declare function main(argv: string[]): Promise<number>;
|
|
23
|
+
export declare function checkCoverage(args: CheckArgs): Promise<CheckRunResult>;
|
|
24
|
+
export declare function evaluateCheck(args: CheckArgs): Promise<EvaluatedCheck>;
|
|
4
25
|
export declare function runCheck(args: CheckArgs): Promise<number>;
|