Add consumes field for skill ecosystem #63
Workflow file for this run
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 Skills | |
| on: | |
| pull_request: | |
| types: [opened, synchronize, reopened, edited] | |
| branches: [main] | |
| jobs: | |
| validate: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| # --- Attestation (only for fork PRs that touch skills/) --- | |
| - name: Check for skill changes | |
| id: skill-changes | |
| run: | | |
| CHANGED=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.sha }}) | |
| echo "Changed files:" | |
| echo "$CHANGED" | |
| if echo "$CHANGED" | grep -q '^skills/'; then | |
| echo "skills_changed=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "skills_changed=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Check contributor attestation | |
| if: steps.skill-changes.outputs.skills_changed == 'true' && github.event.pull_request.head.repo.fork == true | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| # Use GitHub API to get the PR body -- more reliable than the event payload | |
| PR_BODY=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }} --jq '.body // ""') | |
| # Check for a checked attestation checkbox (permissive match) | |
| if echo "$PR_BODY" | grep -qiE '\-\s*\[[xX]\]\s.*agree.*Terms of Service.*Privacy Policy'; then | |
| echo "Contributor attestation confirmed." | |
| else | |
| echo "::error::Contributor attestation required. Check the attestation checkbox in your PR description." | |
| echo "" | |
| echo "If you don't see one, copy this into your PR body:" | |
| echo "" | |
| echo "## Contributor Attestation" | |
| echo "" | |
| echo '- [ ] I agree to the [Terms of Service](https://skillshelf.ai/terms/) and [Privacy Policy](https://skillshelf.ai/privacy/), and I understand that if my submission is accepted it will be published under the [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) license. I confirm I have the rights to submit this content and it does not include confidential information or personal data.' | |
| echo "" | |
| echo "Then check the box by changing [ ] to [x]." | |
| exit 1 | |
| fi | |
| # For web submissions, verify receipt block (advisory, not blocking) | |
| if echo "$PR_BODY" | grep -q '<!-- skillshelf-consent'; then | |
| echo "Web submission receipt block found." | |
| missing="" | |
| echo "$PR_BODY" | grep -q 'submitted_via=web' || missing="$missing submitted_via" | |
| echo "$PR_BODY" | grep -q 'tos=' || missing="$missing tos" | |
| echo "$PR_BODY" | grep -q 'privacy=' || missing="$missing privacy" | |
| echo "$PR_BODY" | grep -q 'file_sha256=' || missing="$missing file_sha256" | |
| echo "$PR_BODY" | grep -q 'ts=' || missing="$missing ts" | |
| if [ -n "$missing" ]; then | |
| echo "::warning::Receipt block missing fields:$missing — may indicate a tampered receipt." | |
| else | |
| echo "Receipt block verified — all required fields present." | |
| fi | |
| fi | |
| - name: Skip attestation — maintainer edit | |
| if: steps.skill-changes.outputs.skills_changed == 'true' && github.event.pull_request.head.repo.fork != true | |
| run: echo "Skill changes from repo branch — attestation not required for maintainers." | |
| - name: Skip attestation — no skill changes | |
| if: steps.skill-changes.outputs.skills_changed != 'true' | |
| run: echo "No skills/ changes detected — attestation not required." | |
| # --- Skill validation --- | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.12" | |
| - name: Install dependencies | |
| run: pip install skills-ref pyyaml | |
| - name: Discover skill directories | |
| id: discover | |
| run: | | |
| if [ ! -d "skills" ]; then | |
| echo "No skills/ directory found. Nothing to validate." | |
| echo "skills_found=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| SKILL_DIRS="" | |
| for dir in skills/*/; do | |
| if [ -f "${dir}SKILL.md" ]; then | |
| SKILL_DIRS="${SKILL_DIRS} ${dir%/}" | |
| fi | |
| done | |
| if [ -z "$SKILL_DIRS" ]; then | |
| echo "No skills found in skills/. Nothing to validate." | |
| echo "skills_found=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Found skills:$SKILL_DIRS" | |
| echo "skills_found=true" >> "$GITHUB_OUTPUT" | |
| echo "skill_dirs=$SKILL_DIRS" >> "$GITHUB_OUTPUT" | |
| - name: Validate against open standard (skills-ref) | |
| if: steps.discover.outputs.skills_found == 'true' | |
| run: | | |
| EXIT_CODE=0 | |
| for dir in ${{ steps.discover.outputs.skill_dirs }}; do | |
| echo "--- Validating $dir (open standard) ---" | |
| if ! agentskills validate "$dir"; then | |
| EXIT_CODE=1 | |
| fi | |
| done | |
| exit $EXIT_CODE | |
| - name: Validate SkillShelf metadata | |
| if: steps.discover.outputs.skills_found == 'true' | |
| run: | | |
| python scripts/validate_skillshelf_metadata.py ${{ steps.discover.outputs.skill_dirs }} |