@@ -7,11 +7,28 @@ import * as core from '@actions/core';
77import * as glob from '@actions/glob' ;
88import * as http from '@actions/http-client' ;
99
10- import Ajv2019 from 'ajv/dist/2019' ;
10+ import type { default as Ajv } from 'ajv' ;
11+ import { default as Ajv2019 , ErrorObject } from 'ajv/dist/2019' ;
1112import AjvDraft04 from 'ajv-draft-04' ;
1213import AjvFormats from 'ajv-formats' ;
1314import * as yaml from 'yaml' ;
1415
16+ function newAjv ( schema : Record < string , unknown > ) : Ajv {
17+ const draft04Schema =
18+ schema . $schema === 'http://json-schema.org/draft-04/schema#' ;
19+
20+ const ajv = AjvFormats ( draft04Schema ? new AjvDraft04 ( ) : new Ajv2019 ( ) ) ;
21+
22+ if ( ! draft04Schema ) {
23+ /* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
24+ ajv . addMetaSchema ( require ( 'ajv/dist/refs/json-schema-draft-06.json' ) ) ;
25+ ajv . addMetaSchema ( require ( 'ajv/dist/refs/json-schema-draft-07.json' ) ) ;
26+ /* eslint-enable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
27+ }
28+
29+ return ajv ;
30+ }
31+
1532/**
1633 * The main function for the action.
1734 * @returns {Promise<void> } Resolves when the action is complete.
@@ -72,47 +89,63 @@ export async function run(): Promise<void> {
7289 }
7390 }
7491
75- // Load and compile the schema
76- const schema : Record < string , unknown > = JSON . parse (
77- await fs . readFile ( schemaPath , 'utf-8' )
78- ) ;
79-
80- if ( typeof schema . $schema !== 'string' ) {
81- core . setFailed ( 'JSON schema missing $schema key' ) ;
82- return ;
83- }
92+ const validatingSchema = schemaPath === 'json-schema' ;
93+
94+ let validate : (
95+ data : Record < string , unknown >
96+ ) => Promise < ErrorObject < string , Record < string , unknown > , unknown > [ ] > ;
97+
98+ if ( validatingSchema ) {
99+ validate = async ( data : Record < string , unknown > ) => {
100+ // Create a new Ajv instance per-schema since
101+ // they may require different draft versions
102+ const ajv = newAjv ( data ) ;
103+
104+ await ajv . validateSchema ( data ) ;
105+ return ajv . errors || [ ] ;
106+ } ;
107+ } else {
108+ // Load and compile the schema
109+ const schema : Record < string , unknown > = JSON . parse (
110+ await fs . readFile ( schemaPath , 'utf-8' )
111+ ) ;
84112
85- const draft04Schema =
86- schema . $schema === 'http://json-schema.org/draft-04/schema#' ;
113+ if ( typeof schema . $schema !== 'string' ) {
114+ core . setFailed ( 'JSON schema missing $schema key' ) ;
115+ return ;
116+ }
87117
88- const ajv = draft04Schema ? new AjvDraft04 ( ) : new Ajv2019 ( ) ;
118+ const ajv = newAjv ( schema ) ;
89119
90- if ( ! draft04Schema ) {
91- /* eslint-disable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
92- ajv . addMetaSchema ( require ( 'ajv/dist/refs/json-schema-draft-06.json' ) ) ;
93- ajv . addMetaSchema ( require ( 'ajv/dist/refs/json-schema-draft-07.json' ) ) ;
94- /* eslint-enable @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
120+ validate = async ( data : object ) => {
121+ ajv . validate ( schema , data ) ;
122+ return ajv . errors || [ ] ;
123+ } ;
95124 }
96125
97- const validate = AjvFormats ( ajv ) . compile ( schema ) ;
98-
99126 let valid = true ;
100127 let filesValidated = false ;
101128
102129 const globber = await glob . create ( files . join ( '\n' ) ) ;
103130
104131 for await ( const file of globber . globGenerator ( ) ) {
105132 filesValidated = true ;
133+
106134 const instance = yaml . parse ( await fs . readFile ( file , 'utf-8' ) ) ;
107135
108- if ( ! validate ( instance ) ) {
136+ if ( validatingSchema && typeof instance . $schema !== 'string' ) {
137+ core . setFailed ( 'JSON schema missing $schema key' ) ;
138+ return ;
139+ }
140+
141+ const errors = await validate ( instance ) ;
142+
143+ if ( errors . length ) {
109144 valid = false ;
110145 core . debug ( `𐄂 ${ file } is not valid` ) ;
111146
112- if ( validate . errors ) {
113- for ( const error of validate . errors ) {
114- core . error ( JSON . stringify ( error , null , 4 ) ) ;
115- }
147+ for ( const error of errors ) {
148+ core . error ( JSON . stringify ( error , null , 4 ) ) ;
116149 }
117150 } else {
118151 core . debug ( `✓ ${ file } is valid` ) ;
0 commit comments