125 lines
4.2 KiB
YAML
125 lines
4.2 KiB
YAML
name: Tests
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
|
|
jobs:
|
|
test:
|
|
name: Hermetic test suite
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.11'
|
|
|
|
- name: Verify Python version
|
|
run: python3 --version
|
|
|
|
- name: Verify Bash + GNU coreutils
|
|
run: bash --version && date --version | head -1
|
|
|
|
- name: Make scripts executable
|
|
run: chmod +x scripts/*.sh scripts/*.py bin/*.sh tests/*.sh 2>/dev/null || true
|
|
|
|
- name: Run hermetic test suite
|
|
run: make test
|
|
|
|
- name: Verify wiki-mode CLI surfaces
|
|
run: |
|
|
python3 scripts/wiki-mode.py get
|
|
python3 scripts/wiki-mode.py config | python3 -m json.tool > /dev/null
|
|
python3 scripts/wiki-mode.py id
|
|
python3 scripts/wiki-mode.py templates
|
|
|
|
- name: Verify transport detection
|
|
run: bash scripts/detect-transport.sh --peek | python3 -m json.tool > /dev/null
|
|
|
|
lint-skills:
|
|
name: Skill frontmatter validation
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 2
|
|
|
|
steps:
|
|
- name: Checkout
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.11'
|
|
|
|
- name: Install PyYAML
|
|
run: pip install pyyaml
|
|
|
|
- name: Validate every SKILL.md has valid YAML frontmatter
|
|
run: |
|
|
python3 <<'PYEOF'
|
|
import os, sys, yaml
|
|
errors = []
|
|
for root, dirs, files in os.walk('skills'):
|
|
for f in files:
|
|
if f == 'SKILL.md':
|
|
path = os.path.join(root, f)
|
|
with open(path) as fh:
|
|
content = fh.read()
|
|
if not content.startswith('---'):
|
|
errors.append(f"{path}: missing frontmatter")
|
|
continue
|
|
try:
|
|
end = content.index('\n---', 4)
|
|
frontmatter = yaml.safe_load(content[4:end])
|
|
if not frontmatter.get('name'):
|
|
errors.append(f"{path}: missing 'name' in frontmatter")
|
|
if not frontmatter.get('description'):
|
|
errors.append(f"{path}: missing 'description' in frontmatter")
|
|
except Exception as e:
|
|
errors.append(f"{path}: frontmatter parse error: {e}")
|
|
if errors:
|
|
print("\n".join(errors))
|
|
sys.exit(1)
|
|
print("All SKILL.md files have valid frontmatter.")
|
|
PYEOF
|
|
|
|
- name: Validate every agent has tools declared
|
|
run: |
|
|
python3 <<'PYEOF'
|
|
import os, sys, yaml
|
|
errors = []
|
|
for f in os.listdir('agents'):
|
|
if f.endswith('.md'):
|
|
path = os.path.join('agents', f)
|
|
with open(path) as fh:
|
|
content = fh.read()
|
|
if not content.startswith('---'):
|
|
errors.append(f"{path}: missing frontmatter")
|
|
continue
|
|
try:
|
|
end = content.index('\n---', 4)
|
|
frontmatter = yaml.safe_load(content[4:end])
|
|
if not frontmatter.get('tools'):
|
|
errors.append(f"{path}: missing 'tools' in frontmatter")
|
|
except Exception as e:
|
|
errors.append(f"{path}: frontmatter parse error: {e}")
|
|
if errors:
|
|
print("\n".join(errors))
|
|
sys.exit(1)
|
|
print("All agents have tools declared.")
|
|
PYEOF
|
|
|
|
- name: Validate plugin.json + marketplace.json
|
|
run: |
|
|
python3 -c "import json; json.load(open('.claude-plugin/plugin.json'))"
|
|
python3 -c "import json; json.load(open('.claude-plugin/marketplace.json'))"
|
|
python3 -c "import json; json.load(open('hooks/hooks.json'))"
|
|
echo "All plugin manifests are valid JSON."
|