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

feat(ajv-custom-format): initial poc #61

Merged
merged 9 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
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
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