1212 steps :
1313 - uses : actions/checkout@v4
1414
15+ - name : Install PyYAML
16+ run : pip install pyyaml
17+
1518 - name : Validate SKILL.md front matter
1619 run : |
1720 ERRORS=0
@@ -23,30 +26,33 @@ jobs:
2326 continue
2427 fi
2528
26- # Check front matter exists (starts with ---)
29+ # Check front matter exists
2730 if ! head -1 "$FILE" | grep -q '^---$'; then
28- echo "❌ $skill_dir: missing front matter (no opening ---) "
31+ echo "❌ $skill_dir: missing front matter"
2932 ERRORS=$((ERRORS + 1))
3033 continue
3134 fi
3235
33- # Extract front matter
34- FM=$(sed -n '2, /^---$/p ' "$FILE" | head -n -1 )
36+ # Extract front matter between first two ---
37+ FM=$(awk ' /^---$/{n++; next} n==1{print} n==2{exit} ' "$FILE")
3538
3639 # Check required fields
37- if ! echo "$FM" | grep -q '^name:'; then
40+ HAS_NAME=$(echo "$FM" | grep -c '^name:' || true)
41+ HAS_DESC=$(echo "$FM" | grep -c '^description:' || true)
42+
43+ if [[ "$HAS_NAME" -eq 0 ]]; then
3844 echo "❌ $skill_dir: front matter missing 'name'"
3945 ERRORS=$((ERRORS + 1))
4046 fi
41- if ! echo "$FM" | grep -q '^description:' ; then
47+ if [[ "$HAS_DESC" -eq 0 ]] ; then
4248 echo "❌ $skill_dir: front matter missing 'description'"
4349 ERRORS=$((ERRORS + 1))
4450 fi
4551
4652 # Check name matches directory
4753 FM_NAME=$(echo "$FM" | grep '^name:' | sed 's/name: *//' | tr -d '"' | tr -d "'")
4854 if [[ "$FM_NAME" != "$skill_dir" ]]; then
49- echo "❌ $skill_dir: front matter name '$FM_NAME' doesn't match directory"
55+ echo "❌ $skill_dir: name '$FM_NAME' doesn't match directory"
5056 ERRORS=$((ERRORS + 1))
5157 else
5258 echo "✅ $skill_dir: OK"
@@ -70,26 +76,23 @@ jobs:
7076 continue
7177 fi
7278
73- # Validate YAML syntax
74- python3 -c "
79+ python3 << PYEOF
7580import yaml, sys
76- with open(' $EVAL' ) as f :
81+ with open(" $EVAL" ) as f :
7782 data = yaml.safe_load(f)
7883if not isinstance(data, list) :
79- print(' ❌ $skill_dir : test_cases.yaml must be a list' )
84+ print(" ❌ $skill_dir : test_cases.yaml must be a list" )
8085 sys.exit(1)
8186for i, case in enumerate(data) :
82- if 'id' not in case :
83- print(f'❌ $skill_dir : case {i} missing id')
84- sys.exit(1)
85- if 'prompt' not in case :
86- print(f'❌ $skill_dir : case {case["id"]} missing prompt')
87- sys.exit(1)
88- if 'expectations' not in case or not case['expectations'] :
89- print(f'❌ $skill_dir : case {case["id"]} missing expectations')
90- sys.exit(1)
91- print(f'✅ $skill_dir : {len(data)} test case(s) valid')
92- " || ERRORS=$((ERRORS + 1))
87+ for field in ["id", "prompt", "expectations"] :
88+ if field not in case or not case[field] :
89+ print(f"❌ $skill_dir : case {i} missing {field}")
90+ sys.exit(1)
91+ print(f"✅ $skill_dir : {len(data)} test case(s) valid")
92+ PYEOF
93+ if [[ $? -ne 0 ]]; then
94+ ERRORS=$((ERRORS + 1))
95+ fi
9396 done
9497
9598 if [[ $ERRORS -gt 0 ]]; then
@@ -98,6 +101,5 @@ print(f'✅ $skill_dir: {len(data)} test case(s) valid')
98101 exit 1
99102 fi
100103
101- - name : Check setup script
102- run : |
103- bash -n setup && echo "✅ setup: syntax OK" || { echo "❌ setup: syntax error"; exit 1; }
104+ - name : Check setup script syntax
105+ run : bash -n setup && echo "✅ setup: syntax OK"
0 commit comments