mirror of
https://github.com/msitarzewski/agency-agents
synced 2026-04-25 03:08:24 +00:00
Add CI workflow to validate agent file format
Adds a lint script and GitHub Actions workflow that checks agent markdown files for required YAML frontmatter fields (name, description, color) and recommends standard sections. Only changed files in PRs are validated to avoid blocking on pre-existing issues.
This commit is contained in:
parent
53feda4d4e
commit
976c08e4c3
44
.github/workflows/lint-agents.yml
vendored
Normal file
44
.github/workflows/lint-agents.yml
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
name: Lint Agent Files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'design/**'
|
||||
- 'engineering/**'
|
||||
- 'marketing/**'
|
||||
- 'product/**'
|
||||
- 'project-management/**'
|
||||
- 'testing/**'
|
||||
- 'support/**'
|
||||
- 'spatial-computing/**'
|
||||
- 'specialized/**'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Validate agent frontmatter and structure
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed agent files
|
||||
id: changed
|
||||
run: |
|
||||
FILES=$(git diff --name-only --diff-filter=ACMR origin/${{ github.base_ref }}...HEAD -- \
|
||||
'design/*.md' 'engineering/*.md' 'marketing/*.md' 'product/*.md' \
|
||||
'project-management/*.md' 'testing/*.md' 'support/*.md' \
|
||||
'spatial-computing/*.md' 'specialized/*.md')
|
||||
echo "files=$FILES" >> "$GITHUB_OUTPUT"
|
||||
if [ -z "$FILES" ]; then
|
||||
echo "No agent files changed."
|
||||
else
|
||||
echo "Changed files:"
|
||||
echo "$FILES"
|
||||
fi
|
||||
|
||||
- name: Run agent linter
|
||||
if: steps.changed.outputs.files != ''
|
||||
run: |
|
||||
chmod +x scripts/lint-agents.sh
|
||||
./scripts/lint-agents.sh ${{ steps.changed.outputs.files }}
|
||||
114
scripts/lint-agents.sh
Executable file
114
scripts/lint-agents.sh
Executable file
@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Validates agent markdown files:
|
||||
# 1. YAML frontmatter must exist with name, description, color (ERROR)
|
||||
# 2. Recommended sections checked but only warned (WARN)
|
||||
# 3. File must have meaningful content
|
||||
#
|
||||
# Usage: ./scripts/lint-agents.sh [file ...]
|
||||
# If no files given, scans all agent directories.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
AGENT_DIRS=(
|
||||
design
|
||||
engineering
|
||||
marketing
|
||||
product
|
||||
project-management
|
||||
testing
|
||||
support
|
||||
spatial-computing
|
||||
specialized
|
||||
)
|
||||
|
||||
REQUIRED_FRONTMATTER=("name" "description" "color")
|
||||
RECOMMENDED_SECTIONS=("Identity" "Core Mission" "Critical Rules")
|
||||
|
||||
errors=0
|
||||
warnings=0
|
||||
|
||||
lint_file() {
|
||||
local file="$1"
|
||||
|
||||
# 1. Check frontmatter delimiters
|
||||
local first_line
|
||||
first_line=$(head -1 "$file")
|
||||
if [[ "$first_line" != "---" ]]; then
|
||||
echo "ERROR $file: missing frontmatter opening ---"
|
||||
((errors++))
|
||||
return
|
||||
fi
|
||||
|
||||
# Extract frontmatter (between first and second ---)
|
||||
local frontmatter
|
||||
frontmatter=$(awk 'NR==1{next} /^---$/{exit} {print}' "$file")
|
||||
|
||||
if [[ -z "$frontmatter" ]]; then
|
||||
echo "ERROR $file: empty or malformed frontmatter"
|
||||
((errors++))
|
||||
return
|
||||
fi
|
||||
|
||||
# 2. Check required frontmatter fields
|
||||
for field in "${REQUIRED_FRONTMATTER[@]}"; do
|
||||
if ! echo "$frontmatter" | grep -qE "^${field}:"; then
|
||||
echo "ERROR $file: missing frontmatter field '${field}'"
|
||||
((errors++))
|
||||
fi
|
||||
done
|
||||
|
||||
# 3. Check recommended sections (warn only)
|
||||
local body
|
||||
body=$(awk 'BEGIN{n=0} /^---$/{n++; next} n>=2{print}' "$file")
|
||||
|
||||
for section in "${RECOMMENDED_SECTIONS[@]}"; do
|
||||
if ! echo "$body" | grep -qi "$section"; then
|
||||
echo "WARN $file: missing recommended section '${section}'"
|
||||
((warnings++))
|
||||
fi
|
||||
done
|
||||
|
||||
# 4. Check file has meaningful content
|
||||
if [[ $(echo "$body" | wc -w) -lt 50 ]]; then
|
||||
echo "WARN $file: body seems very short (< 50 words)"
|
||||
((warnings++))
|
||||
fi
|
||||
}
|
||||
|
||||
# Collect files to lint
|
||||
files=()
|
||||
if [[ $# -gt 0 ]]; then
|
||||
files=("$@")
|
||||
else
|
||||
for dir in "${AGENT_DIRS[@]}"; do
|
||||
if [[ -d "$dir" ]]; then
|
||||
while IFS= read -r f; do
|
||||
files+=("$f")
|
||||
done < <(find "$dir" -maxdepth 1 -name "*.md" -type f | sort)
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ ${#files[@]} -eq 0 ]]; then
|
||||
echo "No agent files found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Linting ${#files[@]} agent files..."
|
||||
echo ""
|
||||
|
||||
for file in "${files[@]}"; do
|
||||
lint_file "$file"
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Results: ${errors} error(s), ${warnings} warning(s) in ${#files[@]} files."
|
||||
|
||||
if [[ $errors -gt 0 ]]; then
|
||||
echo "FAILED: fix the errors above before merging."
|
||||
exit 1
|
||||
else
|
||||
echo "PASSED"
|
||||
exit 0
|
||||
fi
|
||||
Loading…
x
Reference in New Issue
Block a user