chore(main): release 2.4.0 (#201) #929
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: Validate Claude Code Plugin | |
| on: | |
| push: | |
| branches: ["**"] | |
| pull_request: | |
| branches: [main] | |
| permissions: | |
| contents: read | |
| jobs: | |
| validate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Setup Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: '1.26' | |
| - name: Install cclint | |
| run: | | |
| # Pin to specific commit for reproducibility | |
| go install github.com/dotcommander/cclint@latest | |
| echo "$HOME/go/bin" >> $GITHUB_PATH | |
| - name: Validate plugin structure | |
| run: | | |
| # Validate all plugins with .claude-plugin/plugin.json | |
| for plugin_dir in */; do | |
| plugin_name="${plugin_dir%/}" | |
| if [ -f "$plugin_dir.claude-plugin/plugin.json" ]; then | |
| # Skip plugins with no skills/commands/agents (hooks-only plugins have nothing for cclint to lint) | |
| plugin_json="$plugin_dir.claude-plugin/plugin.json" | |
| has_lintable=$(jq -r '(.skills//[])+(.commands//[])+(.agents//[])|length' "$plugin_json" 2>/dev/null || echo "0") | |
| if [ "$has_lintable" -eq 0 ]; then | |
| echo "Skipping $plugin_name plugin (hooks-only, no skills/commands/agents to lint)" | |
| continue | |
| fi | |
| echo "Validating $plugin_name plugin..." | |
| $HOME/go/bin/cclint "$plugin_name" | |
| fi | |
| done | |
| - name: Validate marketplace.json | |
| run: | | |
| echo "Validating marketplace configuration..." | |
| if [ -f ".claude-plugin/marketplace.json" ]; then | |
| jq empty .claude-plugin/marketplace.json | |
| fi | |
| - name: Setup Python | |
| uses: actions/setup-python@v6 | |
| with: | |
| python-version: '3.14' | |
| - name: Install check-jsonschema | |
| run: pip install check-jsonschema | |
| - name: Validate plugin.json schemas | |
| run: | | |
| # Validate all plugin.json files against the schema | |
| for plugin_dir in */; do | |
| plugin_name="${plugin_dir%/}" | |
| if [ -f "$plugin_dir.claude-plugin/plugin.json" ]; then | |
| echo "Schema validating $plugin_name plugin.json..." | |
| check-jsonschema --schemafile schemas/plugin.schema.json "$plugin_dir.claude-plugin/plugin.json" | |
| fi | |
| done | |
| - name: Validate hook scripts | |
| run: | | |
| echo "Checking hook scripts..." | |
| find . -name "*.py" -path "*/scripts/*" | while read -r script; do | |
| if [ -f "$script" ]; then | |
| echo "Validating Python syntax: $script" | |
| python3 -m py_compile "$script" | |
| echo "Checking executable permission: $script" | |
| if [ ! -x "$script" ]; then | |
| echo "ERROR: $script is not executable" | |
| exit 1 | |
| fi | |
| fi | |
| done | |
| find . -name "*.sh" -path "*/scripts/*" | while read -r script; do | |
| if [ -f "$script" ]; then | |
| echo "Validating Bash syntax: $script" | |
| bash -n "$script" | |
| echo "Checking executable permission: $script" | |
| if [ ! -x "$script" ]; then | |
| echo "ERROR: $script is not executable" | |
| exit 1 | |
| fi | |
| fi | |
| done | |
| - name: Validate JSON files | |
| run: | | |
| echo "Validating JSON syntax..." | |
| find . -name "*.json" ! -path "*/node_modules/*" | while read -r json_file; do | |
| echo "Checking $json_file" | |
| jq empty "$json_file" | |
| done | |
| - name: Install bats-core | |
| run: sudo npm install -g bats | |
| - name: Run tests | |
| run: | | |
| echo "Running bats tests via shared script..." | |
| ./scripts/run-tests.sh | |
| echo "Running Python tests..." | |
| find . -name "test_*.py" -o -name "*_test.py" | while read -r test; do | |
| if [ -f "$test" ]; then | |
| echo "Running: $test" | |
| python3 "$test" | |
| fi | |
| done |