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:
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
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
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
- 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-severityscores - Results — each finding mapped to a SARIF result with file location and severity level
Severity mapping to SARIF levels:
| skillshare Severity | SARIF Level | security-severity |
|---|---|---|
| CRITICAL | error | 9.0 |
| HIGH | error | 7.0 |
| MEDIUM | warning | 4.0 |
| LOW | note | 2.0 |
| INFO | note | 0.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) toaudit— any HIGH+ finding exits non-zero - SARIF for Code Scanning: Use
--format sarifwithgithub/codeql-action/upload-sarif@v3for 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
Related
- Security audit guide
auditcommand referenceaudit rulesreference- Audit Engine — How the engine works
- Docker sandbox guide