Skip to content

feat(v1.2.0): catalog site polish - dark/light mode, search, fonts, a… #21

feat(v1.2.0): catalog site polish - dark/light mode, search, fonts, a…

feat(v1.2.0): catalog site polish - dark/light mode, search, fonts, a… #21

Workflow file for this run

name: Validate
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
jobs:
validate-registry:
name: Validate registry.json
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate JSON syntax
run: python3 -c "import json; json.load(open('registry.json'))"
- name: Validate registry schema
shell: bash
run: |
python3 << 'PYEOF'
import json, sys
data = json.load(open("registry.json"))
assert isinstance(data, list), "registry.json must be an array"
SCHEMA = {
"name": str,
"repo": str,
"slug": str,
"description": str,
"type": str,
"homepage": str,
"skills": int,
"rules": int,
"mcpTools": int,
"extras": dict,
"topics": list,
"status": str,
"version": str,
"language": str,
"license": str,
"pagesType": str,
"hasCI": bool,
}
OPTIONAL = {"npm": str}
VALID_TYPES = {"cursor-plugin", "mcp-server"}
VALID_STATUS = {"active", "beta", "deprecated"}
VALID_PAGES = {"static", "mkdocs", "none"}
errors = []
for i, tool in enumerate(data):
label = "Entry %d (%s)" % (i, tool.get("name", "?"))
for field, expected_type in SCHEMA.items():
if field not in tool:
errors.append("%s: missing required field '%s'" % (label, field))
elif not isinstance(tool[field], expected_type):
errors.append("%s: '%s' must be %s, got %s" % (label, field, expected_type.__name__, type(tool[field]).__name__))
for field, expected_type in OPTIONAL.items():
if field in tool and not isinstance(tool[field], expected_type):
errors.append("%s: optional '%s' must be %s" % (label, field, expected_type.__name__))
if tool.get("type") not in VALID_TYPES:
errors.append("%s: type must be one of %s" % (label, VALID_TYPES))
if tool.get("status") not in VALID_STATUS:
errors.append("%s: status must be one of %s" % (label, VALID_STATUS))
if tool.get("pagesType") not in VALID_PAGES:
errors.append("%s: pagesType must be one of %s" % (label, VALID_PAGES))
if not isinstance(tool.get("topics", []), list):
pass
elif not all(isinstance(t, str) for t in tool.get("topics", [])):
errors.append("%s: topics must be array of strings" % label)
if errors:
for e in errors:
print("::error::" + e, file=sys.stderr)
sys.exit(1)
print("Registry valid: %d tools" % len(data))
PYEOF
validate-docs:
name: Validate docs site
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check docs/index.html exists
run: test -f docs/index.html
- name: Check docs/style.css exists
run: test -f docs/style.css
- name: Check docs/script.js exists
run: test -f docs/script.js
validate-scaffold:
name: Validate scaffold
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: pip install Jinja2
- name: Check scaffold syntax
run: python3 -m py_compile scaffold/create-tool.py
- name: Test scaffold dry run
run: |
python3 scaffold/create-tool.py \
--name "CI Test Plugin" \
--description "Automated test" \
--mcp-server \
--skills 2 \
--rules 1 \
--output /tmp/scaffold-test
test -f /tmp/scaffold-test/ci-test-plugin/.cursor-plugin/plugin.json
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/validate.yml
test -f /tmp/scaffold-test/ci-test-plugin/.github/workflows/pages.yml
test -f /tmp/scaffold-test/ci-test-plugin/site.json
test -f /tmp/scaffold-test/ci-test-plugin/mcp-tools.json
test -f /tmp/scaffold-test/ci-test-plugin/mcp-server/server.py
echo "Scaffold test passed"