CI: Validate JSON Schema of Services files

master
Matt Gajownik 2022-04-19 13:07:57 +10:00 committed by Matt Gajownik
parent 2960669f9a
commit de11632a9c
2 changed files with 124 additions and 0 deletions

40
.github/workflows/services-json.yml vendored Normal file
View File

@ -0,0 +1,40 @@
name: Services Validator
on:
push:
paths:
- "plugins/rtmp-services/data/services.json"
- "plugins/rtmp-services/data/package.json"
pull_request:
paths:
- "plugins/rtmp-services/data/services.json"
- "plugins/rtmp-services/data/package.json"
jobs:
schema:
name: Schema
runs-on: [ubuntu-latest]
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install & Configure Python
run: |
sudo apt install python3.9-dev
python3.9 -m pip install jsonschema json_source_map
- name: Validate Service JSON Schema
run: |
JSON_FILES=(
plugins/rtmp-services/data/services.json
plugins/rtmp-services/data/package.json
)
python3.9 CI/check-jsonschema.py "${JSON_FILES[@]}"
- name: Annotate Errors
if: failure()
uses: yuzutech/annotations-action@v0.4.0
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
title: "Service JSON Errors"
input: "./validation_errors.json"

84
CI/check-jsonschema.py Normal file
View File

@ -0,0 +1,84 @@
import json
from jsonschema import Draft7Validator
from json_source_map import calculate
from json_source_map.errors import InvalidInputError
import os
import sys
errors = []
def main():
if len(sys.argv) < 2:
print("JSON path required.")
return 1
for filename in sys.argv[1:]:
prep(filename)
try:
with open('validation_errors.json', 'w') as outfile:
json.dump(errors, outfile)
except OSError as e:
print(f'Failed to write validation output to file: {e}')
return 1
if errors:
return 1
return 0
def prep(filename):
try:
with open(filename) as json_file:
json_string = json_file.read()
json_data = json.loads(json_string)
except OSError as e:
print(f'Failed to load file "{filename}": {e}')
return
schema_filename = json_data.get('$schema')
if not schema_filename:
print('File has no schema:', filename)
return
file_path = os.path.split(filename)[0]
schema_file = os.path.join(file_path, schema_filename)
try:
with open(schema_file) as json_file:
schema = json.load(json_file)
except OSError as e:
print(f'Failed to load schema file "{schema_file}": {e}')
return
validate(filename, json_data, json_string, schema)
def validate(filename, json_data, json_string, schema):
try:
servicesPaths = calculate(json_string)
except InvalidInputError as e:
print("Error with file:", e)
return
cls = Draft7Validator(schema)
for e in sorted(cls.iter_errors(json_data), key=str):
print(f'{e}\nIn "{filename}"\n\n')
errorPath = '/'.join(str(v) for v in e.absolute_path)
errorEntry = servicesPaths['/' + errorPath]
errors.append({
"file": filename,
"start_line": errorEntry.value_start.line + 1,
"end_line": errorEntry.value_end.line + 1,
"title": "Validation Error",
"message": e.message,
"annotation_level": "failure"
})
if __name__ == '__main__':
sys.exit(main())