Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 52 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,58 @@
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Checkout
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1

- name: Set up OCaml ${{ matrix.ocaml-version }}
uses: ocaml/setup-ocaml@7c185f622998a008ba1b296d2d7c64e235629c23 # v3.6.1
with:
ocaml-compiler: ${{ matrix.ocaml-version }}
dune-cache: true

- name: Install dependencies
run: opam install . --deps-only --with-test -y
working-directory: engines/rescript-wasm

- name: Build with strict warnings
run: |
opam exec -- dune build --force
working-directory: engines/rescript-wasm

- name: Run all tests (must pass)
run: |
opam exec -- dune test
echo "All tests passed successfully"
working-directory: engines/rescript-wasm

- name: Generate sample WAT
run: |
opam exec -- dune exec rescript_wasm -- add > add.wat
opam exec -- dune exec rescript_wasm -- max > max.wat
opam exec -- dune exec rescript_wasm -- square > square.wat
opam exec -- dune exec rescript_wasm -- combined > combined.wat
echo "=== add.wat ==="
cat add.wat
working-directory: engines/rescript-wasm

- name: Install wasm-tools
if: runner.os == 'Linux'
run: |
curl -L https://github.com/bytecodealliance/wasm-tools/releases/download/v1.219.1/wasm-tools-1.219.1-x86_64-linux.tar.gz | tar xz

Check warning on line 57 in .github/workflows/ci.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Not enforcing HTTPS here might allow for redirections to insecure websites. Make sure it is safe here.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_poly-ssg2&issues=AaGtOiSOxODS9S9qgG1X&open=AaGtOiSOxODS9S9qgG1X&pullRequest=1
sudo mv wasm-tools-1.219.1-x86_64-linux/wasm-tools /usr/local/bin/

- name: Validate WAT output (strict)
if: runner.os == 'Linux'
run: |
# Validate all generated WAT files
for wat in add.wat max.wat square.wat combined.wat; do
echo "Validating $wat..."
wasm-tools validate --features gc "$wat" || echo "Note: WAT validation requires WASM-GC support"
done
working-directory: engines/rescript-wasm

- name: Upload WAT artifacts
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v4
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
fetch-depth: 0
Expand Down
174 changes: 162 additions & 12 deletions .github/workflows/hypatia-scan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,165 @@ permissions:
contents: read
jobs:
scan:
uses: metadatastician/standards/.github/workflows/hypatia-scan-reusable.yml@d3e4b485a2af90c92a8e18af0888cd19cb132cd9
permissions:
actions: read
contents: read
security-events: write
with:
# The canonical grid reports all evidence and unavailable integrations.
# No broad path exclusions or caller-local scanner implementation.
scope-excludes: ''
report-backs-artifact: ''
secrets:
HYPATIA_SCAN_PAT: ${{ secrets.HYPATIA_SCAN_PAT }}
name: Hypatia Neurosymbolic Analysis
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4
with:
fetch-depth: 0 # Full history for better pattern analysis

- name: Setup Elixir for Hypatia scanner
uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2
with:
elixir-version: '1.19.4'
otp-version: '28.3'

- name: Clone Hypatia
run: |
if [ ! -d "$HOME/hypatia" ]; then
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
fi

- name: Build Hypatia scanner (if needed)
working-directory: ${{ env.HOME }}/hypatia
run: |
if [ ! -f hypatia-v2 ]; then
echo "Building hypatia-v2 scanner..."
cd scanner
mix deps.get
mix escript.build
mv hypatia ../hypatia-v2
fi

- name: Run Hypatia scan
id: scan
run: |
echo "Scanning repository: ${{ github.repository }}"

# Run scanner
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json

# Count findings
FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0)
echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT

# Extract severity counts
CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json)
HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json)
MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json)

echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
echo "high=$HIGH" >> $GITHUB_OUTPUT
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT

echo "## Hypatia Scan Results" >> $GITHUB_STEP_SUMMARY
echo "- Total findings: $FINDING_COUNT" >> $GITHUB_STEP_SUMMARY
echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY

- name: Upload findings artifact
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v4
with:
name: hypatia-findings
path: hypatia-findings.json
retention-days: 90

- name: Submit findings to gitbot-fleet (Phase 2)
if: steps.scan.outputs.findings_count > 0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
GITHUB_SHA: ${{ github.sha }}
run: |
echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..."

# Clone gitbot-fleet to temp directory
FLEET_DIR="/tmp/gitbot-fleet-$$"
git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"

# Run submission script
bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json

# Cleanup
rm -rf "$FLEET_DIR"

echo "✅ Finding submission complete"

- name: Check for critical issues
if: steps.scan.outputs.critical > 0
run: |
echo "⚠️ Critical security issues found!"
echo "Review hypatia-findings.json for details"
# Don't fail the build yet - just warn
# exit 1

- name: Generate scan report
run: |
cat << EOF > hypatia-report.md
# Hypatia Security Scan Report

**Repository:** ${{ github.repository }}
**Scan Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC")
**Commit:** ${{ github.sha }}

## Summary

| Severity | Count |
|----------|-------|
| Critical | ${{ steps.scan.outputs.critical }} |
| High | ${{ steps.scan.outputs.high }} |
| Medium | ${{ steps.scan.outputs.medium }} |
| **Total**| ${{ steps.scan.outputs.findings_count }} |

## Next Steps

1. Review findings in the artifact: hypatia-findings.json
2. Auto-fixable issues will be addressed by robot-repo-automaton (Phase 3)
3. Manual review required for complex issues

## Learning

These findings feed Hypatia's learning engine to improve future rules.

---
*Powered by [Hypatia](https://github.com/hyperpolymath/hypatia) - Neurosymbolic CI/CD Intelligence*
EOF

cat hypatia-report.md >> $GITHUB_STEP_SUMMARY

- name: Comment on PR with findings
if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
with:
script: |
const fs = require('fs');
const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));

const critical = findings.filter(f => f.severity === 'critical').length;
const high = findings.filter(f => f.severity === 'high').length;

let comment = `## 🔍 Hypatia Security Scan\n\n`;
comment += `**Findings:** ${findings.length} issues detected\n\n`;
comment += `| Severity | Count |\n|----------|-------|\n`;
comment += `| 🔴 Critical | ${critical} |\n`;
comment += `| 🟠 High | ${high} |\n`;
comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`;

if (critical > 0) {
comment += `⚠️ **Action Required:** Critical security issues found!\n\n`;
}

comment += `<details><summary>View findings</summary>\n\n`;
comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`;
comment += `</details>\n\n`;
comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;

github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: comment
});
Loading