-
Notifications
You must be signed in to change notification settings - Fork 0
121 lines (108 loc) · 4.15 KB
/
validate.yml
File metadata and controls
121 lines (108 loc) · 4.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
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@v6
- 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@v6
- name: Check docs/index.html exists
run: test -f docs/index.html
validate-scaffold:
name: Validate scaffold
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- 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"