Files
trailofbits-skills/.github/workflows/validate.yml
T
William Tan f09e5c729a Remove legacy codex compatiblity scripts/shims. (#173)
* Remove legacy codex compatiblity scripts/shims.

Codex supports claude plugins so this shouldn't be necessary.
Add a script to test the plugin loadablility in both claude and codex

* fix: resolve code review findings for PR #173

Review findings addressed (4 reviewers: pr-review-toolkit agents,
Codex gpt-5.3-codex, direct diff review):

P2 fixed:
- Bump versions for the 5 substantively changed plugins in both
  plugin.json and marketplace.json (gh-cli 1.5.0 new skill,
  claude-in-chrome-troubleshooting 1.1.0 skill rename,
  modern-python 1.5.1 / skill-improver 1.0.3 hooks change,
  zeroize-audit 0.1.1 MCP config relocation) so clients pick up
  the changes
- README Codex install: replace unpasteable /plugins slash-command
  block with verified CLI syntax (codex plugin marketplace add)
- check_claude_loadability: parse_json_output now fails fast with
  command context on empty CLI output instead of returning None
- check_codex_loadability: surface skipped RPC error messages in
  timeout failures instead of a bare TimeoutError

P3 fixed:
- Both checkers: error out when marketplace.json lists no plugins
  instead of passing vacuously

Dismissed:
- @latest CLI installs in validate.yml: deliberate; the check
  validates against the clients users actually run
- select.select portability: CI-only script on ubuntu-latest
- Divergent mcpServers validation between checkers: intentional;
  the Codex checker enforces the repo's .mcp.json convention

Verified: ruff, prek, validate_plugin_metadata.py, and both
loadability checks pass end-to-end (39 plugins, 74 skills, 2 MCP
servers load in Claude Code and Codex)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Dan Guido <dan@trailofbits.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 12:18:09 -04:00

110 lines
3.8 KiB
YAML

name: Validate
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
validate:
name: Validate plugins and skills
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false
- name: Validate SKILL.md frontmatter
run: |
echo "Checking SKILL.md frontmatter..."
python3 -c "
import os
import re
import sys
errors = []
skill_count = 0
for root, dirs, files in os.walk('plugins'):
for f in files:
if f == 'SKILL.md':
path = os.path.join(root, f)
skill_count += 1
with open(path) as fp:
content = fp.read()
# Check for frontmatter
if not content.startswith('---'):
errors.append(f'{path}: missing YAML frontmatter')
continue
# Extract frontmatter
match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL)
if not match:
errors.append(f'{path}: malformed frontmatter')
continue
frontmatter = match.group(1)
# Check for required fields
if 'name:' not in frontmatter:
errors.append(f'{path}: missing \"name\" in frontmatter')
if 'description:' not in frontmatter:
errors.append(f'{path}: missing \"description\" in frontmatter')
if errors:
for e in errors:
print(f'ERROR: {e}', file=sys.stderr)
sys.exit(1)
print(f'All {skill_count} SKILL.md files have valid frontmatter')
"
- name: Check for hardcoded paths
run: |
echo "Checking for hardcoded user paths..."
# Exclude /path/to (example paths) and /home/vscode (standard devcontainer user)
if grep -rPn '(?<![a-zA-Z])(/home/[a-z]|/Users/[A-Z])' plugins/ --include='*.md' --include='*.py' --include='*.json' | grep -v '/path/to' | grep -v '/home/vscode'; then
echo "ERROR: Found hardcoded user paths (see above)"
exit 1
fi
echo "No hardcoded user paths found"
- name: Check for personal emails
run: |
echo "Checking for personal emails..."
if grep -r '@trailofbits.com' . --include='*.json' --include='*.toml' | grep -v 'opensource@trailofbits.com' | grep -v '.git'; then
echo "ERROR: Found personal emails (should use opensource@trailofbits.com)"
exit 1
fi
echo "No personal emails found"
- name: Validate plugin metadata
run: python3 .github/scripts/validate_plugin_metadata.py
- name: Install Claude Code CLI
run: |
npm install --global --prefix "$RUNNER_TEMP/claude-cli" @anthropic-ai/claude-code@latest
echo "$RUNNER_TEMP/claude-cli/bin" >> "$GITHUB_PATH"
"$RUNNER_TEMP/claude-cli/bin/claude" --version
- name: Check Claude loadability
run: python3 .github/scripts/check_claude_loadability.py
- name: Install Codex CLI
run: |
npm install --global --prefix "$RUNNER_TEMP/codex-cli" @openai/codex@latest
echo "$RUNNER_TEMP/codex-cli/bin" >> "$GITHUB_PATH"
"$RUNNER_TEMP/codex-cli/bin/codex" --version
- name: Check Codex loadability
run: python3 .github/scripts/check_codex_loadability.py