Skip to main content

Recipe: CI/CD Skill Validation

Audit and sync skills automatically in your CI pipeline.

Scenario​

You have a team skill repository and want to ensure every PR:

  • Passes security audit (no prompt injection, credential theft, etc.)
  • Validates SKILL.md format
  • Syncs without errors

Solution​

GitHub Actions (with setup-skillshare)​

The setup-skillshare action handles installation, initialization, and optional security auditing in one step.

name: Skill Validation
on:
pull_request:
paths:
- 'skills/**'

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: runkids/setup-skillshare@v1
with:
source: ./skills
audit: true
audit-threshold: high
- run: skillshare sync --dry-run

GitHub Actions with SARIF Upload​

To get inline PR annotations via GitHub Code Scanning, use SARIF output. When audit-output is set, the action saves the results and records the exit code instead of failing, so the SARIF file can still be uploaded. Add a final step that fails the job on findings:

name: Skill Security Scan
on:
pull_request:
paths: ['skills/**']
push:
branches: [main]

jobs:
validate:
runs-on: ubuntu-latest
permissions:
security-events: write
steps:
- uses: actions/checkout@v4
- uses: runkids/setup-skillshare@v1
id: skillshare
with:
source: ./skills
audit: true
audit-threshold: high
audit-format: sarif
audit-output: results.sarif

- name: Upload SARIF to Code Scanning
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
category: skillshare-audit

- run: skillshare sync --dry-run

- name: Fail on audit findings
if: steps.skillshare.outputs.audit-exit-code != '0'
run: exit 1

Without the action (manual setup)​

If you prefer not to use the action, you can install skillshare directly:

jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: |
curl -fsSL https://raw.githubusercontent.com/runkids/skillshare/main/install.sh | sh
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
- run: skillshare init --no-copy --all-targets --no-git --no-skill --source ./skills
- run: skillshare audit --threshold high --format json
- run: skillshare sync --dry-run

GitLab CI​

Create .gitlab-ci.yml:

skill-validation:
image: ghcr.io/runkids/skillshare-ci:latest
stage: test
script:
- skillshare init
- skillshare install . --into ci-check
- skillshare audit --threshold high --format json
- skillshare sync --dry-run
rules:
- changes:
- skills/**/*

Using the CI Docker Image​

For faster pipeline startup, use the pre-built CI image:

# GitHub Actions
jobs:
validate:
runs-on: ubuntu-latest
container:
image: ghcr.io/runkids/skillshare-ci:latest
steps:
- uses: actions/checkout@v4
- run: skillshare init && skillshare audit --format json

Output Formats​

The audit command supports multiple output formats for different CI/CD integration needs.

Exit Codes​

# Block deployment if any skill has findings at or above threshold
skillshare audit --threshold high
echo $? # 0 = clean, 1 = findings found

SARIF Output​

SARIF (Static Analysis Results Interchange Format) is an OASIS standard consumed by GitHub Code Scanning, VS Code SARIF Viewer, Azure DevOps, SonarQube, and other static analysis tools.

skillshare audit --format sarif              # Output to stdout
skillshare audit --format sarif > results.sarif # Save to file

The SARIF output includes:

  • Tool metadata — tool name (skillshare), version, and information URI
  • Rules — deduplicated rule descriptors with security-severity scores
  • Results — each finding mapped to a SARIF result with file location and severity level

Severity mapping to SARIF levels:

skillshare SeveritySARIF Levelsecurity-severity
CRITICALerror9.0
HIGHerror7.0
MEDIUMwarning4.0
LOWnote2.0
INFOnote0.5

Markdown Report​

Generate a self-contained Markdown report suitable for pasting into GitHub Issues, Pull Requests, or documentation:

skillshare audit --format markdown               # Print to stdout
skillshare audit --format markdown > report.md # Save to file
skillshare audit -p --format markdown > report.md # Project mode

The report includes:

  • Header — scanned count, mode, and threshold
  • Summary table — passed/warning/failed counts, severity breakdown, risk score, analyzability
  • Findings — per-skill tables with severity, pattern, message, and location; collapsible snippets
  • Clean Skills — comma-separated list of skills with no findings

JSON Output with jq​

# List all skills with CRITICAL findings
skillshare audit --json | jq '[.skills[] | select(.findings[] | .severity == "CRITICAL")]'

# Extract risk scores for all skills
skillshare audit --json | jq '.skills[] | {name: .skillName, score: .riskScore, label: .riskLabel}'

# Count findings by severity
skillshare audit --json | jq '[.skills[].findings[].severity] | group_by(.) | map({(.[0]): length}) | add'

Verification​

  • PR check passes: audit exits 0 (no findings at/above threshold)
  • Audit JSON output can be parsed by downstream tools
  • SARIF upload shows findings as inline annotations on PR diffs
  • Sync dry-run shows expected symlink operations

Variations​

  • Block on HIGH severity: Add --threshold HIGH (or -T HIGH) to audit — any HIGH+ finding exits non-zero
  • SARIF for Code Scanning: Use --format sarif with github/codeql-action/upload-sarif@v3 for inline PR annotations
  • Parallel validation: Run audit and sync in separate CI jobs for faster feedback
  • Scheduled audits: Run nightly to catch newly detected patterns in existing skills