Skip to content

Commit 0c67660

Browse files
committed
feat: CI workflow — lint SKILL.md front matter, validate evals, check setup syntax
1 parent 5d2f31a commit 0c67660

1 file changed

Lines changed: 103 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint-skills:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Validate SKILL.md front matter
16+
run: |
17+
ERRORS=0
18+
for skill_dir in plan-product plan-eng code-review ship qa retro; do
19+
FILE="$skill_dir/SKILL.md"
20+
if [[ ! -f "$FILE" ]]; then
21+
echo "❌ $skill_dir: SKILL.md missing"
22+
ERRORS=$((ERRORS + 1))
23+
continue
24+
fi
25+
26+
# Check front matter exists (starts with ---)
27+
if ! head -1 "$FILE" | grep -q '^---$'; then
28+
echo "❌ $skill_dir: missing front matter (no opening ---)"
29+
ERRORS=$((ERRORS + 1))
30+
continue
31+
fi
32+
33+
# Extract front matter
34+
FM=$(sed -n '2,/^---$/p' "$FILE" | head -n -1)
35+
36+
# Check required fields
37+
if ! echo "$FM" | grep -q '^name:'; then
38+
echo "❌ $skill_dir: front matter missing 'name'"
39+
ERRORS=$((ERRORS + 1))
40+
fi
41+
if ! echo "$FM" | grep -q '^description:'; then
42+
echo "❌ $skill_dir: front matter missing 'description'"
43+
ERRORS=$((ERRORS + 1))
44+
fi
45+
46+
# Check name matches directory
47+
FM_NAME=$(echo "$FM" | grep '^name:' | sed 's/name: *//' | tr -d '"' | tr -d "'")
48+
if [[ "$FM_NAME" != "$skill_dir" ]]; then
49+
echo "❌ $skill_dir: front matter name '$FM_NAME' doesn't match directory"
50+
ERRORS=$((ERRORS + 1))
51+
else
52+
echo "✅ $skill_dir: OK"
53+
fi
54+
done
55+
56+
if [[ $ERRORS -gt 0 ]]; then
57+
echo ""
58+
echo "$ERRORS error(s) found."
59+
exit 1
60+
fi
61+
62+
- name: Validate eval test cases
63+
run: |
64+
ERRORS=0
65+
for skill_dir in plan-product plan-eng code-review ship qa retro; do
66+
EVAL="$skill_dir/evals/test_cases.yaml"
67+
if [[ ! -f "$EVAL" ]]; then
68+
echo "❌ $skill_dir: evals/test_cases.yaml missing"
69+
ERRORS=$((ERRORS + 1))
70+
continue
71+
fi
72+
73+
# Validate YAML syntax
74+
python3 -c "
75+
import yaml, sys
76+
with open('$EVAL') as f:
77+
data = yaml.safe_load(f)
78+
if not isinstance(data, list):
79+
print('❌ $skill_dir: test_cases.yaml must be a list')
80+
sys.exit(1)
81+
for 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))
93+
done
94+
95+
if [[ $ERRORS -gt 0 ]]; then
96+
echo ""
97+
echo "$ERRORS error(s) found."
98+
exit 1
99+
fi
100+
101+
- name: Check setup script
102+
run: |
103+
bash -n setup && echo "✅ setup: syntax OK" || { echo "❌ setup: syntax error"; exit 1; }

0 commit comments

Comments
 (0)