Skip to content

Commit 89f29a1

Browse files
Testclaude
andcommitted
feat(ci): enable Hypatia scanning
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
1 parent 0ad001a commit 89f29a1

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

.github/workflows/hypatia-scan.yml

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# SPDX-License-Identifier: PMPL-1.0-or-later
2+
# Hypatia Neurosymbolic CI/CD Security Scan
3+
name: Hypatia Security Scan
4+
5+
on:
6+
push:
7+
branches: [ main, master, develop ]
8+
pull_request:
9+
branches: [ main, master ]
10+
schedule:
11+
- cron: '0 0 * * 0' # Weekly on Sunday
12+
workflow_dispatch:
13+
14+
permissions: read-all
15+
16+
jobs:
17+
scan:
18+
name: Hypatia Neurosymbolic Analysis
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
24+
with:
25+
fetch-depth: 0 # Full history for better pattern analysis
26+
27+
- name: Setup Elixir for Hypatia scanner
28+
uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2
29+
with:
30+
elixir-version: '1.19.4'
31+
otp-version: '28.3'
32+
33+
- name: Clone Hypatia
34+
run: |
35+
if [ ! -d "$HOME/hypatia" ]; then
36+
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
37+
fi
38+
39+
- name: Build Hypatia scanner (if needed)
40+
working-directory: ${{ env.HOME }}/hypatia
41+
run: |
42+
if [ ! -f hypatia-v2 ]; then
43+
echo "Building hypatia-v2 scanner..."
44+
cd scanner
45+
mix deps.get
46+
mix escript.build
47+
mv hypatia ../hypatia-v2
48+
fi
49+
50+
- name: Run Hypatia scan
51+
id: scan
52+
run: |
53+
echo "Scanning repository: ${{ github.repository }}"
54+
55+
# Run scanner
56+
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json
57+
58+
# Count findings
59+
FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0)
60+
echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT
61+
62+
# Extract severity counts
63+
CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json)
64+
HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json)
65+
MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json)
66+
67+
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
68+
echo "high=$HIGH" >> $GITHUB_OUTPUT
69+
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
70+
71+
echo "## Hypatia Scan Results" >> $GITHUB_STEP_SUMMARY
72+
echo "- Total findings: $FINDING_COUNT" >> $GITHUB_STEP_SUMMARY
73+
echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
74+
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
75+
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
76+
77+
- name: Upload findings artifact
78+
uses: actions/upload-artifact@65c79d7f54e76e4e3c7a8f34db0f4ac8b515c478 # v4
79+
with:
80+
name: hypatia-findings
81+
path: hypatia-findings.json
82+
retention-days: 90
83+
84+
- name: Submit findings to gitbot-fleet (Phase 2)
85+
if: steps.scan.outputs.findings_count > 0
86+
env:
87+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
88+
GITHUB_REPOSITORY: ${{ github.repository }}
89+
GITHUB_SHA: ${{ github.sha }}
90+
run: |
91+
echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."
92+
93+
# Clone gitbot-fleet to temp directory
94+
FLEET_DIR="/tmp/gitbot-fleet-$$"
95+
git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"
96+
97+
# Run submission script
98+
bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json
99+
100+
# Cleanup
101+
rm -rf "$FLEET_DIR"
102+
103+
echo "✅ Finding submission complete"
104+
105+
- name: Check for critical issues
106+
if: steps.scan.outputs.critical > 0
107+
run: |
108+
echo "⚠️ Critical security issues found!"
109+
echo "Review hypatia-findings.json for details"
110+
# Don't fail the build yet - just warn
111+
# exit 1
112+
113+
- name: Generate scan report
114+
run: |
115+
cat << EOF > hypatia-report.md
116+
# Hypatia Security Scan Report
117+
118+
**Repository:** ${{ github.repository }}
119+
**Scan Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
120+
**Commit:** ${{ github.sha }}
121+
122+
## Summary
123+
124+
| Severity | Count |
125+
|----------|-------|
126+
| Critical | ${{ steps.scan.outputs.critical }} |
127+
| High | ${{ steps.scan.outputs.high }} |
128+
| Medium | ${{ steps.scan.outputs.medium }} |
129+
| **Total**| ${{ steps.scan.outputs.findings_count }} |
130+
131+
## Next Steps
132+
133+
1. Review findings in the artifact: hypatia-findings.json
134+
2. Auto-fixable issues will be addressed by robot-repo-automaton (Phase 3)
135+
3. Manual review required for complex issues
136+
137+
## Learning
138+
139+
These findings feed Hypatia's learning engine to improve future rules.
140+
141+
---
142+
*Powered by [Hypatia](https://github.com/hyperpolymath/hypatia) - Neurosymbolic CI/CD Intelligence*
143+
EOF
144+
145+
cat hypatia-report.md >> $GITHUB_STEP_SUMMARY
146+
147+
- name: Comment on PR with findings
148+
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
149+
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
150+
with:
151+
script: |
152+
const fs = require('fs');
153+
const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));
154+
155+
const critical = findings.filter(f => f.severity === 'critical').length;
156+
const high = findings.filter(f => f.severity === 'high').length;
157+
158+
let comment = `## 🔍 Hypatia Security Scan\n\n`;
159+
comment += `**Findings:** ${findings.length} issues detected\n\n`;
160+
comment += `| Severity | Count |\n|----------|-------|\n`;
161+
comment += `| 🔴 Critical | ${critical} |\n`;
162+
comment += `| 🟠 High | ${high} |\n`;
163+
comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;
164+
165+
if (critical > 0) {
166+
comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
167+
}
168+
169+
comment += `<details><summary>View findings</summary>\n\n`;
170+
comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
171+
comment += `</details>\n\n`;
172+
comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;
173+
174+
github.rest.issues.createComment({
175+
owner: context.repo.owner,
176+
repo: context.repo.repo,
177+
issue_number: context.issue.number,
178+
body: comment
179+
});

0 commit comments

Comments
 (0)