Skip to content

Commit

Permalink
JSON Schema validation and URL validation for PRs
Browse files Browse the repository at this point in the history
  • Loading branch information
adamziel committed Apr 15, 2024
1 parent d2f9f8d commit f088c9a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Ships a valid Blueprint.json file?
name: Has a valid Blueprint.json file?

on:
pull_request:
Expand All @@ -15,6 +15,10 @@ jobs:
run: |
git fetch origin trunk
- name: Install pre-requisites
run: |
pip install -r requirements.txt
- name: Run validate_pr.py
run: |
python validate_pr.py
7 changes: 5 additions & 2 deletions blueprints/custom-post/blueprint.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
"title": "Custom Post Type: Books",
"description": "Blueprint that added a custom post type to playground",
"author": "bph",
"categories": ["Content", "CPT"]
"categories": [
"Content",
"CPT"
]
},
"landingPage": "/wp-admin/",
"steps": [
Expand All @@ -28,4 +31,4 @@
"pluginPath": "books/books.php"
}
]
}
}
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
requests
67 changes: 63 additions & 4 deletions validate_pr.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import os
import re
from jsonschema import Draft7Validator, validate, ValidationError
import json
import sys
import requests

def validate_blueprints():
errors = []

# Get the list of directories touched in the current branch
touched_dirs = get_touched_directories()

Expand All @@ -14,17 +18,71 @@ def validate_blueprints():

# Check if blueprint.json file exists
if not os.path.exists(blueprint_json_path):
print(f"Error: {dir}/{blueprint_json_path} file does not exist in this PR.")
sys.exit(1)
errors.append(f"Error: {dir}/{blueprint_json_path} file does not exist in this PR.")
continue

# Read and validate the JSON file
try:
with open(blueprint_json_path, 'r') as f:
blueprint_json = json.load(f)
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON in {blueprint_json_path}: {str(e)}")
sys.exit(1)
errors.append(f"Error: Invalid JSON in {blueprint_json_path}: {str(e)}")
continue

# Validate the Blueprint against the JSON schema
schema_url = 'https://playground.wordpress.net/blueprint-schema.json'
schema = json.loads(requests.get(schema_url).text)

try:
validate(instance=blueprint_json, schema=schema, cls=Draft7Validator)
except ValidationError as e:
error_path = " > ".join(e.absolute_path)
at_error = f"at {error_path}" if error_path else "at root"
errors.append(
f"Error: {dir}/{blueprint_json_path} does not match the JSON schema.\n"
f"{str(e.message)} {at_error}.\n"
)
continue

# Recursively find all urls in the blueprint.json file
urls = find_urls(blueprint_json)

# Check if the URLs all point to raw.githubusercontent.com/adamziel/blueprints/{CURRENT BRANCH}
urls_valid = True
current_branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
for url in urls:
if not url.startswith('https://') and not url.startswith('http://'):
continue
if not url.startswith(f'https://raw.githubusercontent.com/adamziel/blueprints/{current_branch}/'):
urls_valid = False
errors.append(
f"Error: {dir}/{blueprint_json_path} contains a URL that is not allowed: \n* {url}\n"
f"Since the current branch is {current_branch}, the URL should start with \n* https://raw.githubusercontent.com/adamziel/blueprints/{current_branch}/\n"
"In general, all URLs in the blueprint.json file must start with https://raw.githubusercontent.com/adamziel/blueprints/{CURRENT BRANCH}/"
)

if not urls_valid:
continue

if len(errors):
for error in errors:
print(error)
sys.exit(1)


def find_urls(obj):
urls = []
if isinstance(obj, dict):
for key, value in obj.items():
if key == 'url':
urls.append(value)
urls.extend(find_urls(value))
elif isinstance(obj, list):
for item in obj:
urls.extend(find_urls(item))
return urls



def get_touched_directories():
# Run git diff command to get the list of directories touched in the current branch
Expand All @@ -37,5 +95,6 @@ def get_touched_directories():
touched_dirs.add(dir_path)

return touched_dirs

# Call the function to validate blueprints
validate_blueprints()

0 comments on commit f088c9a

Please sign in to comment.