Skip to content

Commit b5da274

Browse files
authored
feat: input to report all errors instead of just the first (#41)
Closes #27
1 parent ac9035e commit b5da274

File tree

6 files changed

+45
-14
lines changed

6 files changed

+45
-14
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ jobs:
5151
schema: https://gist.githubusercontent.com/dsanders11/b17fd12c00fc44b487df66d61039398e/raw/f05a9c19d6662282b1576b268e5c3228befc4700/schema.json
5252
files: .github/workflows/ci.yml
5353
fail-on-invalid: false
54+
all-errors: true
5455
- name: Test Local Action (Multiple File Valid)
5556
id: multiple-file-valid
5657
uses: ./
@@ -65,6 +66,7 @@ jobs:
6566
schema: https://gist.githubusercontent.com/dsanders11/b17fd12c00fc44b487df66d61039398e/raw/f05a9c19d6662282b1576b268e5c3228befc4700/schema.json
6667
files: .github/workflows/**.yml
6768
fail-on-invalid: false
69+
all-errors: true
6870
- name: Confirm Output
6971
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
7072
with:

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
fi
2929
- name: Validate workflows
3030
if: steps.check-for-changed-workflows.outputs.any_changed == 'true'
31-
uses: dsanders11/json-schema-validate-action@1.2.1
31+
uses: dsanders11/json-schema-validate-action@v1.3.0
3232
with:
3333
schema: https://json.schemastore.org/github-workflow.json
3434
files: .github/workflows/**.yml
@@ -54,6 +54,8 @@ simply set a URL fragment (e.g. `#bust-cache`) on the schema URL.
5454
(default: `true`)
5555
- `cache-remote-schema` - Whether or not to cache the schema if remote (default:
5656
`true`)
57+
- `all-errors` - Whether to report all errors or stop after the first (default:
58+
`false`)
5759

5860
### Outputs
5961

__tests__/main.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ describe('action', () => {
405405
expect(runSpy).toHaveReturned();
406406
expect(process.exitCode).not.toBeDefined();
407407

408+
expect(core.error).toHaveBeenCalledTimes(2);
408409
expect(core.setOutput).toHaveBeenCalledTimes(1);
409410
expect(core.setOutput).toHaveBeenLastCalledWith('valid', false);
410411
});
@@ -453,6 +454,26 @@ describe('action', () => {
453454
expect(core.setOutput).toHaveBeenLastCalledWith('valid', true);
454455
});
455456

457+
it('reports all errors if all-errors input is true', async () => {
458+
mockGetBooleanInput({ 'all-errors': true, 'fail-on-invalid': false });
459+
mockGetInput({ schema });
460+
mockGetMultilineInput({ files });
461+
462+
vi.mocked(fs.readFile)
463+
.mockResolvedValueOnce(schemaContents)
464+
.mockResolvedValueOnce('invalid content')
465+
.mockResolvedValueOnce(instanceContents);
466+
mockGlobGenerator(['/foo/bar/baz/config.yml', '/foo/bar/baz/e/config.yml']);
467+
468+
await main.run();
469+
expect(runSpy).toHaveReturned();
470+
expect(process.exitCode).not.toBeDefined();
471+
472+
expect(core.error).toHaveBeenCalledTimes(4);
473+
expect(core.setOutput).toHaveBeenCalledTimes(1);
474+
expect(core.setOutput).toHaveBeenLastCalledWith('valid', false);
475+
});
476+
456477
describe('can validate schemas', () => {
457478
beforeEach(() => {
458479
mockGetBooleanInput({});

action.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ inputs:
2121
description: Whether or not to cache the schema if remote
2222
required: false
2323
default: true
24+
all-errors:
25+
description: Report all errors instead of stopping at the first
26+
required: false
27+
default: false
2428

2529
outputs:
2630
valid:

dist/index.js

Lines changed: 7 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,25 @@ import * as core from '@actions/core';
77
import * as glob from '@actions/glob';
88
import * as http from '@actions/http-client';
99

10-
import type { default as Ajv, ErrorObject } from 'ajv';
10+
import type { default as Ajv, ErrorObject, Options } from 'ajv';
1111
import { default as Ajv2019 } from 'ajv/dist/2019';
1212
import { default as Ajv2020 } from 'ajv/dist/2020';
1313
import AjvDraft04 from 'ajv-draft-04';
1414
import AjvFormats from 'ajv-formats';
1515
import * as yaml from 'yaml';
1616

17-
function newAjv(schema: Record<string, unknown>): Ajv {
17+
function newAjv(schema: Record<string, unknown>, options: Options): Ajv {
1818
const draft04Schema =
1919
schema.$schema === 'http://json-schema.org/draft-04/schema#';
2020
const draft2020Schema =
2121
schema.$schema === 'https://json-schema.org/draft/2020-12/schema';
2222

2323
const ajv = AjvFormats(
2424
draft04Schema
25-
? new AjvDraft04()
25+
? new AjvDraft04(options)
2626
: draft2020Schema
27-
? new Ajv2020()
28-
: new Ajv2019()
27+
? new Ajv2020(options)
28+
: new Ajv2019(options)
2929
);
3030

3131
if (!draft04Schema && !draft2020Schema) {
@@ -46,6 +46,7 @@ export async function run(): Promise<void> {
4646
try {
4747
let schemaPath = core.getInput('schema', { required: true });
4848
const files = core.getMultilineInput('files', { required: true });
49+
const allErrors = core.getBooleanInput('all-errors');
4950
const cacheRemoteSchema = core.getBooleanInput('cache-remote-schema');
5051
const failOnInvalid = core.getBooleanInput('fail-on-invalid');
5152

@@ -108,7 +109,7 @@ export async function run(): Promise<void> {
108109
validate = async (data: Record<string, unknown>) => {
109110
// Create a new Ajv instance per-schema since
110111
// they may require different draft versions
111-
const ajv = newAjv(data);
112+
const ajv = newAjv(data, { allErrors });
112113

113114
await ajv.validateSchema(data);
114115
return ajv.errors || [];
@@ -129,7 +130,7 @@ export async function run(): Promise<void> {
129130
return;
130131
}
131132

132-
const ajv = newAjv(schema);
133+
const ajv = newAjv(schema, { allErrors });
133134

134135
validate = async (data: object) => {
135136
ajv.validate(schema, data);

0 commit comments

Comments
 (0)