Skip to content

Commit

Permalink
Merge pull request #61 from cfuerst/feat/60/suport-custom-ajv-format
Browse files Browse the repository at this point in the history
feat(ajv-custom-format): initial poc
  • Loading branch information
GrantBirki committed Apr 17, 2024
2 parents d5bdaec + 1e8d0ce commit 9fe5266
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 1 deletion.
12 changes: 12 additions & 0 deletions .github/workflows/acceptance-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,15 @@ jobs:
files: |
__tests__/**/test1.yml
__tests__/**/test*.json
- name: acceptance test - custom formats
uses: ./
id: json-yaml-validate-custom-formats-test
with:
comment: "true"
json_schema: ./__tests__/fixtures/schemas/schema_with_custom_ajv_regexp_format.json
ajv_custom_regexp_formats: |
lowercase_char=^[a-z]*$
lowercase_alphanumeric=^[a-z0-9]*$
files: |
__tests__/fixtures/json/custom_ajv_regexp_format/valid.json
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Here is a quick example of how to install this action in any workflow:
| `git_ignore_path` | `false` | `".gitignore"` | The full path to the .gitignore file to use if use_gitignore is set to "true" (e.g. ./src/.gitignore) - Default is ".gitignore" which uses the .gitignore file in the root of the repository |
| `allow_multiple_documents` | `false` | `"false"` | Whether or not to allow multiple documents in a single YAML file - `"true"` or `"false"` - Default is `"false"`. Useful for k8s documents. |
| `ajv_strict_mode` | `false` | `"true"` | Whether or not to use strict mode for AJV - "true" or "false" - Default is "true" |
| `ajv_custom_regexp_formats` | `false` | `""` | List of key value pairs of format_name=regexp. Each pair must be on a newline. (e.g. lowercase_chars=^[a-z]*$ ) |
| `github_token` | `false` | `${{ github.token }}` | The GitHub token used to create an authenticated client - Provided for you by default! |

## Outputs 📤
Expand Down
4 changes: 4 additions & 0 deletions __tests__/fixtures/json/custom_ajv_regexp_format/invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"lowercase_char_property": "INVALID",
"lowercase_alphanumeric_property": "INVALID"
}
4 changes: 4 additions & 0 deletions __tests__/fixtures/json/custom_ajv_regexp_format/valid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"lowercase_char_property": "valid",
"lowercase_alphanumeric_property": "valid1"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"type": "object",
"properties": {
"lowercase_char_property": {
"type": "string",
"format": "lowercase_char"
},
"lowercase_alphanumeric_property": {
"type": "string",
"format": "lowercase_alphanumeric"
}
},
"required": ["lowercase_char_property", "lowercase_alphanumeric_property"],
"additionalProperties": false
}
51 changes: 51 additions & 0 deletions __tests__/functions/json-validator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ beforeEach(() => {
process.env.INPUT_FILES = ''
process.env.INPUT_JSON_SCHEMA_VERSION = 'draft-07'
process.env.INPUT_AJV_STRICT_MODE = 'true'
process.env.INPUT_AJV_CUSTOM_REGEXP_FORMATS = ''
})

test('successfully validates a json file with a schema', async () => {
Expand Down Expand Up @@ -472,3 +473,53 @@ test('fails to validate a yaml file with an incorrect schema when yaml_as_json i
)
)
})

test('successfully validates a json file with a schema containing a custom ajv format when custom format was added', async () => {
process.env.INPUT_JSON_SCHEMA =
'__tests__/fixtures/schemas/schema_with_custom_ajv_regexp_format.json'
process.env.INPUT_FILES =
'__tests__/fixtures/json/custom_ajv_regexp_format/valid.json'
process.env.INPUT_AJV_CUSTOM_REGEXP_FORMATS =
'lowercase_char=^[a-z]*$\nlowercase_alphanumeric=^[a-z0-9]*$'
expect(await jsonValidator(excludeMock)).toStrictEqual({
failed: 0,
passed: 1,
skipped: 0,
success: true,
violations: []
})
})

test('fails to validate a json file with a schema containing a custom ajv format when custom format added', async () => {
process.env.INPUT_JSON_SCHEMA =
'__tests__/fixtures/schemas/schema_with_custom_ajv_regexp_format.json'
process.env.INPUT_FILES =
'__tests__/fixtures/json/custom_ajv_regexp_format/invalid.json'
process.env.INPUT_AJV_CUSTOM_REGEXP_FORMATS =
'lowercase_char=^[a-z]*$\nlowercase_alphanumeric=^[a-z0-9]*$'
expect(await jsonValidator(excludeMock)).toStrictEqual({
failed: 1,
passed: 0,
skipped: 0,
success: false,
violations: [
{
file: '__tests__/fixtures/json/custom_ajv_regexp_format/invalid.json',
errors: [
{
path: '/lowercase_char_property',
message: 'must match format "lowercase_char"'
},
{
path: '/lowercase_alphanumeric_property',
message: 'must match format "lowercase_alphanumeric"'
}
]
}
]
})
})

test('todo - testcase needed for format referenced in schema but not added?', async () => {})

test('todo - testcase needed for invalid INPUT_AJV_CUSTOM_REGEXP_FORMATS input (structure, regex etc.)?', async () => {})
4 changes: 4 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ inputs:
description: Whether or not to use strict mode for AJV - "true" or "false" - Default is "true"
required: false
default: "true"
ajv_custom_regexp_formats:
description: List of key value pairs of format_name=regexp. Each pair must be on a newline. (e.g. lowercase_chars=^[a-z]*$ )
required: false
default: ""
outputs:
success:
description: Whether or not the validation was successful for all files - "true" or "false"
Expand Down
8 changes: 8 additions & 0 deletions dist/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions src/functions/json-validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ async function schema(jsonSchema) {
core.debug('ajv-formats will not be used with the json-validator')
}

// add custom regexp format if provided
core
.getMultilineInput('ajv_custom_regexp_formats')
.filter(Boolean)
.forEach(customFormat => {
customFormat = customFormat.trim().split(/=(.*)/s).filter(Boolean)
ajv.addFormat(customFormat[0], new RegExp(customFormat[1]))
})

// if a jsonSchema is provided, validate the json against it
var schema
if (jsonSchema && jsonSchema !== '') {
Expand Down

0 comments on commit 9fe5266

Please sign in to comment.