diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml new file mode 100644 index 0000000..0e7f94c --- /dev/null +++ b/.github/workflows/validate.yml @@ -0,0 +1,38 @@ +name: Validate Skills + +on: + push: + branches: [master] + paths: + - 'skills/**' + - 'scripts/validate.sh' + - 'requirements.txt' + - '.github/workflows/validate.yml' + pull_request: + branches: [master] + paths: + - 'skills/**' + - 'scripts/validate.sh' + - 'requirements.txt' + - '.github/workflows/validate.yml' + +jobs: + validate: + name: Validate Skills + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + cache: 'pip' + + - name: Install dependencies + run: pip install -r requirements.txt + + - name: Run validation + run: ./scripts/validate.sh diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..4bc9313 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +skills-ref @ git+https://github.com/agentskills/agentskills.git#subdirectory=skills-ref diff --git a/scripts/validate.sh b/scripts/validate.sh new file mode 100755 index 0000000..db099a7 --- /dev/null +++ b/scripts/validate.sh @@ -0,0 +1,98 @@ +#!/usr/bin/env bash +# +# Validate all skills in the repository using skills-ref +# +# Usage: ./scripts/validate.sh [skill-path] +# If no argument provided, validates all skills in skills/ directory +# If skill-path provided, validates only that skill + +set -euo pipefail + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Track validation results +FAILED=0 +PASSED=0 +SKILLS_CHECKED=() + +validate_skill() { + local skill_dir="$1" + local skill_name + skill_name=$(basename "$skill_dir") + + echo -e "${YELLOW}Validating:${NC} $skill_dir" + + if skills-ref validate "$skill_dir"; then + echo -e "${GREEN}✓${NC} $skill_name passed validation" + ((PASSED++)) + else + echo -e "${RED}✗${NC} $skill_name failed validation" + ((FAILED++)) + fi + + SKILLS_CHECKED+=("$skill_name") + echo "" +} + +# Change to repo root +cd "$(dirname "$0")/.." + +# Check if skills-ref is installed +if ! command -v skills-ref &> /dev/null; then + echo -e "${RED}Error:${NC} skills-ref is not installed" + echo "Install it with: pip install -r requirements.txt" + exit 1 +fi + +# If a specific skill path is provided, validate only that +if [[ $# -gt 0 ]]; then + if [[ -d "$1" ]]; then + validate_skill "$1" + else + echo -e "${RED}Error:${NC} Directory not found: $1" + exit 1 + fi +else + # Find all skill directories (containing SKILL.md), excluding _template + echo "Searching for skills to validate..." + echo "" + + while IFS= read -r -d '' skill_file; do + skill_dir=$(dirname "$skill_file") + + # Skip _template directory + if [[ "$skill_dir" == *"/_template"* ]] || [[ "$skill_dir" == *"_template"* ]]; then + echo -e "${YELLOW}Skipping template:${NC} $skill_dir" + continue + fi + + validate_skill "$skill_dir" + done < <(find skills -name "SKILL.md" -print0 2>/dev/null || true) +fi + +# Summary +echo "========================================" +echo "Validation Summary" +echo "========================================" +echo -e "Skills checked: ${#SKILLS_CHECKED[@]}" +echo -e "${GREEN}Passed:${NC} $PASSED" +echo -e "${RED}Failed:${NC} $FAILED" +echo "" + +if [[ ${#SKILLS_CHECKED[@]} -eq 0 ]]; then + echo -e "${YELLOW}No skills found to validate.${NC}" + echo "Skills should be placed in skills/.curated/ or skills/.experimental/" + exit 0 +fi + +if [[ $FAILED -gt 0 ]]; then + echo -e "${RED}Validation failed!${NC}" + exit 1 +else + echo -e "${GREEN}All skills passed validation!${NC}" + exit 0 +fi