Files
runner-test/.gitea/workflows/ci.yml
T
pauljd 21f4b3d81c
Davidson CI / quality (push) Successful in 14s
Davidson CI / ai-review (push) Successful in 38s
Harden CI against untrusted pull requests
2026-09-08 16:59:06 +01:00

212 lines
5.8 KiB
YAML

name: Davidson CI
on:
push:
jobs:
quality:
runs-on: davidson-ci
steps:
- name: Checkout repository
uses: actions/checkout@v4
# -------------------------
# Project detection
# -------------------------
- name: Detect project
run: |
echo "=== Project detection ==="
PHP_COUNT=$(find . -type f -name "*.php" -not -path "./vendor/*" | wc -l)
JS_COUNT=$(find . -type f \( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \) -not -path "./node_modules/*" | wc -l)
CSS_COUNT=$(find . -type f -name "*.css" -not -path "./node_modules/*" | wc -l)
echo "PHP files: $PHP_COUNT"
echo "JS files: $JS_COUNT"
echo "CSS files: $CSS_COUNT"
# -------------------------
# PHP
# -------------------------
- name: PHP syntax
run: |
if find . -type f -name "*.php" -not -path "./vendor/*" | grep -q .; then
echo "PHP detected"
find . -type f -name "*.php" -not -path "./vendor/*" -print0 | xargs -0 -n1 php -l
else
echo "No PHP files - skipping"
fi
- name: Composer
run: |
if [ -f composer.json ]; then
composer validate --no-check-publish
if [ -f composer.lock ]; then
composer install --no-interaction --prefer-dist --no-progress
fi
else
echo "No composer.json - skipping"
fi
- name: PHPStan
run: |
if [ -x vendor/bin/phpstan ]; then
vendor/bin/phpstan analyse
else
echo "PHPStan not installed - skipping"
fi
- name: PHPUnit
run: |
if [ -x vendor/bin/phpunit ]; then
vendor/bin/phpunit
else
echo "PHPUnit not installed - skipping"
fi
# -------------------------
# JavaScript / frontend
# -------------------------
- name: Node dependencies
run: |
if [ -f package-lock.json ]; then
npm ci
elif [ -f package.json ]; then
echo "package.json found but no package-lock.json"
else
echo "No Node project - skipping"
fi
- name: JavaScript syntax
run: |
if find . -type f \( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \) -not -path "./node_modules/*" | grep -q .; then
echo "JavaScript detected"
find . -type f \( -name "*.js" -o -name "*.mjs" -o -name "*.cjs" \) \
-not -path "./node_modules/*" \
-print0 |
while IFS= read -r -d '' file; do
echo "Checking $file"
node --check "$file"
done
else
echo "No JavaScript files - skipping"
fi
- name: ESLint
run: |
if [ -f package.json ] && \
node -e "let p=require('./package.json'); process.exit(p.scripts?.lint ? 0 : 1)"
then
npm run lint
else
echo "No lint script - skipping"
fi
- name: JavaScript tests
run: |
if [ -f package.json ] && \
node -e "let p=require('./package.json'); process.exit(p.scripts?.test ? 0 : 1)"
then
npm test
else
echo "No JS test script - skipping"
fi
- name: Frontend build
run: |
if [ -f package.json ] && \
node -e "let p=require('./package.json'); process.exit(p.scripts?.build ? 0 : 1)"
then
npm run build
else
echo "No build script - skipping"
fi
- name: CSS lint
run: |
if [ -f package.json ] && \
node -e "let p=require('./package.json'); process.exit(p.scripts?.['lint:css'] ? 0 : 1)"
then
npm run lint:css
else
echo "No CSS lint script - skipping"
fi
# -------------------------
# Security
# -------------------------
- name: Composer security audit
run: |
if [ -f composer.lock ]; then
echo "Running Composer security audit..."
composer audit
else
echo "No composer.lock - skipping Composer audit"
fi
- name: npm security audit
run: |
if [ -f package-lock.json ]; then
echo "Running npm security audit..."
npm audit --audit-level=high
else
echo "No package-lock.json - skipping npm audit"
fi
- name: Semgrep security scan
run: |
echo "Running Semgrep..."
semgrep scan \
--config=p/security-audit \
--error \
--exclude=node_modules \
--exclude=vendor \
.
- name: Trivy vulnerability scan
run: |
echo "Running Trivy vulnerability scan..."
trivy fs \
--scanners vuln \
--severity HIGH,CRITICAL \
--exit-code 1 \
.
- name: Trivy secret scan
run: |
echo "Running Trivy secret scan..."
trivy fs \
--scanners secret \
--exit-code 1 \
.
- name: Complete
run: echo "Davidson CI completed successfully"
# -------------------------
# AI review
# -------------------------
ai-review:
needs: quality
runs-on: davidson-ai
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Davidson AI review
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
opencode run \
--agent davidson-review \
"Perform a complete Davidson CI review of this repository. Do not modify anything."