CI #278
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| schedule: | |
| - cron: "0 * * * *" # λ§€ μκ° μ κ° | |
| workflow_dispatch: | |
| pull_request: | |
| push: | |
| branches: [main] | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| timeout-minutes: 10 | |
| strategy: | |
| matrix: | |
| skill: [humanizer, grammar-checker, style-guide, humanizer] | |
| fail-fast: false # ν μ€ν¬μ΄ μ€ν¨ν΄λ λ€λ₯Έ μ€ν¬ ν μ€νΈ κ³μ | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v6 | |
| - name: Validate SKILL.md frontmatter | |
| run: | | |
| echo "π Validating YAML frontmatter for ${{ matrix.skill }}..." | |
| SKILL_FILE="skills/${{ matrix.skill }}/SKILL.md" | |
| if [ ! -f "$SKILL_FILE" ]; then | |
| echo "β SKILL.md not found" | |
| exit 1 | |
| fi | |
| # Extract frontmatter (between --- markers) | |
| FRONTMATTER=$(sed -n '/^---$/,/^---$/p' "$SKILL_FILE" | sed '1d;$d') | |
| # Check required field: name | |
| if echo "$FRONTMATTER" | grep -q "^name:"; then | |
| NAME=$(echo "$FRONTMATTER" | grep "^name:" | sed 's/name: *//') | |
| echo "β Found name: $NAME" | |
| # Verify name matches matrix skill | |
| if [ "$NAME" = "${{ matrix.skill }}" ]; then | |
| echo "β Name is correct: ${{ matrix.skill }}" | |
| else | |
| echo "β Name should be '${{ matrix.skill }}', got '$NAME'" | |
| exit 1 | |
| fi | |
| else | |
| echo "β Missing required field: name" | |
| exit 1 | |
| fi | |
| # Check required field: description | |
| if echo "$FRONTMATTER" | grep -q "^description:"; then | |
| # Handle both quoted and unquoted descriptions | |
| DESC=$(echo "$FRONTMATTER" | sed -n 's/^description: *"\?\(.*\)"\?$/\1/p') | |
| DESC_LEN=${#DESC} | |
| echo "β Found description ($DESC_LEN chars)" | |
| # Verify description length (1-1024 chars per Agent Skills spec) | |
| if [ $DESC_LEN -lt 1 ] || [ $DESC_LEN -gt 1024 ]; then | |
| echo "β Description must be 1-1024 characters, got $DESC_LEN" | |
| exit 1 | |
| fi | |
| # Check for non-ASCII characters in description (CLI compatibility) | |
| if echo "$DESC" | grep -qP '[^\x00-\x7F]'; then | |
| echo "β οΈ Warning: Description contains non-ASCII characters (may cause CLI parsing issues)" | |
| else | |
| echo "β Description is ASCII-safe" | |
| fi | |
| else | |
| echo "β Missing required field: description" | |
| exit 1 | |
| fi | |
| echo "β Frontmatter validation passed for ${{ matrix.skill }}" | |
| - name: Validate skill structure | |
| run: | | |
| echo "π Validating skill structure for ${{ matrix.skill }}..." | |
| SKILL_DIR="skills/${{ matrix.skill }}" | |
| # Check SKILL.md exists | |
| if [ ! -f "$SKILL_DIR/SKILL.md" ]; then | |
| echo "β SKILL.md not found" | |
| exit 1 | |
| fi | |
| echo "β SKILL.md exists" | |
| # Check for references directory (if it exists) | |
| if [ -d "$SKILL_DIR/references" ]; then | |
| echo "β references/ directory found" | |
| REF_COUNT=$(find "$SKILL_DIR/references" -name "*.md" | wc -l) | |
| echo " Found $REF_COUNT reference files" | |
| fi | |
| # Check for examples directory (if it exists) | |
| if [ -d "$SKILL_DIR/examples" ]; then | |
| echo "β examples/ directory found" | |
| EX_COUNT=$(find "$SKILL_DIR/examples" -type f | wc -l) | |
| echo " Found $EX_COUNT example files" | |
| fi | |
| # Check for scripts directory (if it exists) | |
| if [ -d "$SKILL_DIR/scripts" ]; then | |
| echo "β scripts/ directory found" | |
| SCRIPT_COUNT=$(find "$SKILL_DIR/scripts" -type f | wc -l) | |
| echo " Found $SCRIPT_COUNT scripts" | |
| fi | |
| # Check for assets directory (if it exists) | |
| if [ -d "$SKILL_DIR/assets" ]; then | |
| echo "β assets/ directory found" | |
| ASSET_COUNT=$(find "$SKILL_DIR/assets" -type f | wc -l) | |
| echo " Found $ASSET_COUNT assets" | |
| fi | |
| echo "β Skill structure validation passed for ${{ matrix.skill }}" | |
| - name: Validate skill-specific requirements | |
| run: | | |
| echo "π Running skill-specific validation for ${{ matrix.skill }}..." | |
| if [ "${{ matrix.skill }}" = "humanizer" ]; then | |
| echo "Validating humanizer-specific files..." | |
| # Expected reference files for humanizer | |
| EXPECTED_FILES=( | |
| "skills/humanizer/references/punctuation-patterns.md" | |
| "skills/humanizer/references/spacing-patterns.md" | |
| "skills/humanizer/references/pos-patterns.md" | |
| "skills/humanizer/references/vocabulary-patterns.md" | |
| "skills/humanizer/references/structure-patterns.md" | |
| ) | |
| for file in "${EXPECTED_FILES[@]}"; do | |
| if [ -f "$file" ]; then | |
| echo "β Found: $file" | |
| else | |
| echo "β Missing: $file" | |
| exit 1 | |
| fi | |
| done | |
| elif [ "${{ matrix.skill }}" = "grammar-checker" ]; then | |
| echo "Validating grammar-checker-specific files..." | |
| # Expected reference files for grammar-checker | |
| EXPECTED_FILES=( | |
| "skills/grammar-checker/references/rules.md" | |
| "skills/grammar-checker/references/common-errors.md" | |
| ) | |
| for file in "${EXPECTED_FILES[@]}"; do | |
| if [ -f "$file" ]; then | |
| echo "β Found: $file" | |
| else | |
| echo "β Missing: $file" | |
| exit 1 | |
| fi | |
| done | |
| fi | |
| echo "β Skill-specific validation passed for ${{ matrix.skill }}" | |
| - name: Install skill with npx skills add | |
| run: | | |
| echo "π§ͺ Installing ${{ matrix.skill }} with npx skills add..." | |
| # Install skill with claude-code agent and auto-confirm | |
| npx skills add DaleSeo/korean-skills --skill ${{ matrix.skill }} --agent claude-code --yes || { | |
| echo "β οΈ npx skills add failed, but continuing to verify..." | |
| echo "This may be expected in CI environment due to TTY issues" | |
| } | |
| echo "β Skill installation step completed for ${{ matrix.skill }}" | |
| - name: Verify installed skill | |
| run: | | |
| echo "π Verifying installed ${{ matrix.skill }}..." | |
| # Debug: Show all potential skill locations | |
| echo "π Searching for skill installation..." | |
| echo "Checking ~/.claude/skills/:" | |
| ls -laR ~/.claude/ 2>/dev/null || echo "~/.claude/ not found" | |
| echo "" | |
| echo "Checking ~/.agents/skills/:" | |
| ls -laR ~/.agents/ 2>/dev/null || echo "~/.agents/ not found" | |
| echo "" | |
| echo "Searching entire home directory for ${{ matrix.skill }}:" | |
| find ~ -name "${{ matrix.skill }}" -type d 2>/dev/null | head -10 || echo "No directories found" | |
| # Try to find the skill in any location | |
| SKILL_DIR="" | |
| if [ -d ~/.claude/skills/${{ matrix.skill }} ]; then | |
| SKILL_DIR=~/.claude/skills/${{ matrix.skill }} | |
| elif [ -d ~/.agents/skills/${{ matrix.skill }} ]; then | |
| SKILL_DIR=~/.agents/skills/${{ matrix.skill }} | |
| else | |
| # Last resort: search for it | |
| SKILL_DIR=$(find ~ -name "${{ matrix.skill }}" -type d 2>/dev/null | grep -E '(\.claude|\.agents)/skills' | head -1) | |
| fi | |
| if [ -z "$SKILL_DIR" ]; then | |
| echo "β Skill directory not found in any expected location" | |
| echo "This may indicate npx skills add failed to install" | |
| exit 1 | |
| fi | |
| echo "β Skill directory found: $SKILL_DIR" | |
| echo "π Contents:" | |
| ls -la "$SKILL_DIR" | |
| # Find and display SKILL.md content | |
| echo "" | |
| echo "π Searching for SKILL.md..." | |
| SKILL_FILE=$(find "$SKILL_DIR" -name "*.md" -type f | head -1) | |
| if [ -z "$SKILL_FILE" ]; then | |
| echo "β No .md files found in skill directory" | |
| exit 1 | |
| fi | |
| echo "β Found skill file: $SKILL_FILE" | |
| echo "π Skill content preview:" | |
| head -20 "$SKILL_FILE" | |
| # Verify references directory (if expected) | |
| echo "" | |
| if [ -d "$SKILL_DIR/references" ]; then | |
| echo "β references/ directory installed" | |
| echo "π Reference files:" | |
| ls -1 "$SKILL_DIR/references/" | |
| else | |
| echo "βΉοΈ references/ directory not found (may not be required)" | |
| fi | |
| echo "β Skill verification completed for ${{ matrix.skill }}" | |
| summary: | |
| runs-on: ubuntu-latest | |
| needs: test | |
| if: always() | |
| steps: | |
| - name: Check test results | |
| run: | | |
| echo "π Test Summary" | |
| echo "===============" | |
| if [ "${{ needs.test.result }}" = "success" ]; then | |
| echo "β All skill tests passed!" | |
| exit 0 | |
| else | |
| echo "β Some skill tests failed" | |
| exit 1 | |
| fi |