Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/scripts/validate-skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/bin/bash
# Validates all skill directories changed in a pull request.
#
# Usage: validate-skills.sh <base-ref>
# base-ref The base branch name to diff against (e.g. "main").
# When omitted or when the remote is unavailable, all skills are validated.
#
# Exit codes:
# 0 All validated skills passed.
# 1 One or more skills failed validation.

# -e is intentionally omitted: all error paths are handled explicitly,
# so abort-on-error would conflict with the || FAILED=1 accumulator pattern.
set -uo pipefail

BASE_REF="${1:-}"

# Find unique skill directories containing files changed in this PR.
# The three-dot diff requires fetch-depth: 0 and a properly configured remote,
# which is always the case on GitHub Actions but may not be in local act runs.
changed_skills=()
if [ -n "$BASE_REF" ]; then
mapfile -t changed_skills < <(git diff --name-only "origin/${BASE_REF}...HEAD" -- skills/ \
2>/dev/null \
| cut -d'/' -f2 \
| sort -u \
| grep -v '^$')
Comment on lines +14 to +27
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script uses mapfile, which is not available in the default macOS /bin/bash (3.2). Since the shebang is #!/bin/bash and the comments mention local usage (e.g., act runs), running it locally on macOS will fail. Either avoid mapfile (e.g., use a while IFS= read -r loop) or explicitly require Bash >= 4 (and consider #!/usr/bin/env bash).

Copilot uses AI. Check for mistakes.
fi

if [ "${#changed_skills[@]}" -eq 0 ]; then
# Fallback: validate all skill directories (e.g. when git remote is unavailable
# in local act testing, or when a PR only deletes files with no remaining dirs).
echo "Could not determine changed skills from git diff; validating all skills."
mapfile -t changed_skills < <(find skills -mindepth 1 -maxdepth 1 -type d -exec basename {} \; | sort -u)
fi

if [ "${#changed_skills[@]}" -eq 0 ]; then
echo "No skill directories found, skipping validation."
exit 0
fi

FAILED=0
for skill in "${changed_skills[@]}"; do
# Skip skills whose directories were deleted in this PR.
if [ ! -d "skills/$skill" ]; then
echo "Skipping deleted skill: $skill"
continue
fi

# Run validation with markdown output so the result is written to the job
# summary in one pass. --emit-annotations works with any output format, so
# inline PR annotations are still emitted alongside the markdown report.
# We use process substitution to:
# 1. Send all output (including ::error commands) to stdout for GitHub Actions
# 2. Filter out ::error/::warning/::notice lines before writing to the summary
skill-validator check --strict --emit-annotations -o markdown "skills/$skill/" \
| tee >(grep -v '^::' >> "${GITHUB_STEP_SUMMARY:-/dev/null}") || FAILED=1
done

if [ $FAILED -ne 0 ]; then
echo ""
echo "❌ Skill validation failed!"
echo ""
echo "📋 See the Job Summary for detailed validation results:"
echo " https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The failure message always prints a GitHub Actions run URL using $GITHUB_REPOSITORY and $GITHUB_RUN_ID. When this script is run outside Actions, those env vars will be unset and the URL will be malformed. Consider only printing the URL when GITHUB_ACTIONS is set (or when both variables are non-empty).

Suggested change
echo " https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
if [ -n "${GITHUB_ACTIONS:-}" ] && [ -n "${GITHUB_REPOSITORY:-}" ] && [ -n "${GITHUB_RUN_ID:-}" ]; then
echo " https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
fi

Copilot uses AI. Check for mistakes.
echo ""
fi

exit $FAILED

9 changes: 7 additions & 2 deletions .github/workflows/validate-skills.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ name: Validate Skills

on:
pull_request:
paths:
- "skills/**"
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With pull_request.paths limited to skills/**, this workflow will not run when only the validation script or workflow definition changes. That can allow CI-breaking changes to merge without being exercised. Consider including .github/workflows/validate-skills.yml and .github/scripts/validate-skills.sh in the paths filter (or removing the filter).

Suggested change
- "skills/**"
- "skills/**"
- ".github/workflows/validate-skills.yml"
- ".github/scripts/validate-skills.sh"

Copilot uses AI. Check for mistakes.

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
# Full history is needed so git diff can compare against the base branch
fetch-depth: 0

- name: Set up Go
uses: actions/setup-go@v6
Expand All @@ -18,5 +23,5 @@ jobs:
- name: Install skill-validator
run: go install github.com/agent-ecosystem/skill-validator/cmd/skill-validator@latest

- name: Validate all skills
run: bash tools/validate-skills.sh
- name: Validate changed skills
run: bash .github/scripts/validate-skills.sh "${{ github.base_ref }}"
23 changes: 0 additions & 23 deletions CONTRIBUTING.md

This file was deleted.

60 changes: 0 additions & 60 deletions tools/validate-skills.sh

This file was deleted.