SkillOx GitHub Action
Audit every SKILL.md changed in a pull request. Findings post as inline annotations on the diff, a summary comment lands on the PR, and CI fails when any file drops below your team's minimum grade. Two lines of YAML to install.
Quick start
Drop this into .github/workflows/skillox.yml in your repo:
# .github/workflows/skillox.yml
name: SkillOx
on:
pull_request:
paths: ['**/SKILL.md']
permissions:
contents: read
pull-requests: write # for the per-PR audit comment
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: skillox/skillox-action@v1
with:
minimum-grade: B # A | B | C | D | FFrom the next pull request onward, every change touching a SKILL.md gets scanned. Reviewers see inline annotations on the offending lines, a summary table on the PR, and the workflow blocks merge when any file scores below the threshold.
Inputs
| Input | Default | What it does |
|---|---|---|
| paths | **/SKILL.md | Comma-separated globs. On PR events, intersected with the changed-files set so monorepo PRs only scan what actually moved. |
| minimum-grade | B | Lowest grade that won't fail CI. A | B | C | D | F. |
| api-base | https://api.skillox.io | Override for self-hosted or staging endpoints. |
| api-key | — | Optional Authorization: Bearer …. Lifts rate limits, unlocks Pro-tier features once API-key auth ships. |
| comment-on-pr | true | Set false if you want annotations + summary only, no PR comment. |
| fail-on-error | true | When true, scan errors (network, oversize) also fail CI. Set false to only fail on threshold violations. |
Outputs
results-json— full per-file results array. Feed it into downstream steps for custom reporting.failing-files— newline-separated paths of files below threshold. Empty when CI passes.worst-grade— worst grade observed across the scanned set. Useful for badges.
Common patterns
Only block on F-grade
Don't fail CI on D's — surface them as annotations only. Useful while ramping up scanner adoption:
- uses: skillox/skillox-action@v1
with:
minimum-grade: D # only F blocks CIMonorepo with skills under multiple directories
- uses: skillox/skillox-action@v1
with:
paths: 'apps/agents/**/SKILL.md,packages/skills/**/*.md'
minimum-grade: BPush to Slack on every non-A result
- id: audit
uses: skillox/skillox-action@v1
with:
minimum-grade: B
- if: always() && steps.audit.outputs.worst-grade != 'A'
uses: slackapi/slack-github-action@v2
with:
payload: |
{
"text": "SkillOx audit: worst grade ${{ steps.audit.outputs.worst-grade }} on ${{ github.event.pull_request.html_url }}"
}How it works
- On
pull_requestevents, queries the GitHub API for the changed-files set and intersects withpaths. Onpush/ manual / scheduled runs, walks the working tree. - Reads each file's content + POSTs them in a single
/scan/bulkcall (max 50 files). No content is persisted unless you opt in. - Per finding becomes a line-level
::warning::or::error::annotation on the diff. Per-file threshold violations become file-level annotations. - Workflow summary table + PR comment posted. The comment is updated in place on re-runs via a hidden marker, so iterative PRs don't accumulate comment spam.
- Exits non-zero when any file is below threshold (or, with
fail-on-error: true, when any scan errored out).
Source + bundle are Apache-2.0 under skillox/skillox-action. PRs welcome.