Skip to content

Commit 0293d8a

Browse files
ci: fix two always-red security gates (CodeQL, Hypatia) (#10)
Both checks failed on every PR for reasons unrelated to PR content: - codeql.yml analyzes `javascript-typescript`, but this repo is a declarative grammar extension with zero JS/TS sources, so CodeQL always errored with "no code found". Add a detection step that skips Init + Analyze when no JS/TS is present; the workflow stays in place and reactivates automatically if JS/TS is ever added. - hypatia-scan.yml assumed an obsolete upstream layout (`cd scanner && mix escript.build`); upstream hyperpolymath/hypatia was refactored to shell entrypoints with no scanner/ dir, so the build step failed ~12s in. Align it to the resilient pattern already proven green in static-analysis-gate.yml: continue-on-error on setup/build, tolerant clone, mix.exs guard, JSON sanitization, stub findings when the scanner is unavailable, and continue-on-error on the external gitbot-fleet submission. Non-blocking-on-findings behavior is preserved. https://claude.ai/code/session_0111iLmV7VFMTFGigST1M1cb Co-authored-by: Claude <noreply@anthropic.com>
1 parent e608603 commit 0293d8a

2 files changed

Lines changed: 63 additions & 23 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,32 @@ jobs:
2929
- name: Checkout
3030
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
3131

32+
# This repo is a declarative grammar extension with no JS/TS sources.
33+
# CodeQL errors out ("no code found") when there is nothing to scan,
34+
# so detect presence first and skip cleanly when absent. The step
35+
# stays here so analysis activates automatically if JS/TS is added.
36+
- name: Detect JavaScript/TypeScript sources
37+
id: detect
38+
run: |
39+
if find . -path ./.git -prune -o -type f \
40+
\( -name '*.ts' -o -name '*.tsx' -o -name '*.js' \
41+
-o -name '*.jsx' -o -name '*.mjs' -o -name '*.cjs' \) \
42+
-print | grep -q .; then
43+
echo "present=true" >> "$GITHUB_OUTPUT"
44+
else
45+
echo "present=false" >> "$GITHUB_OUTPUT"
46+
echo "::notice::No JavaScript/TypeScript sources found — skipping CodeQL analysis."
47+
fi
48+
3249
- name: Initialize CodeQL
50+
if: steps.detect.outputs.present == 'true'
3351
uses: github/codeql-action/init@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
3452
with:
3553
languages: ${{ matrix.language }}
3654
build-mode: ${{ matrix.build-mode }}
3755

3856
- name: Perform CodeQL Analysis
57+
if: steps.detect.outputs.present == 'true'
3958
uses: github/codeql-action/analyze@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1
4059
with:
4160
category: "/language:${{ matrix.language }}"

.github/workflows/hypatia-scan.yml

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -29,45 +29,55 @@ jobs:
2929
fetch-depth: 0 # Full history for better pattern analysis
3030

3131
- name: Setup Elixir for Hypatia scanner
32+
id: beam
33+
continue-on-error: true
3234
uses: erlef/setup-beam@e6d7c94229049569db56a7ad5a540c051a010af9 # v1.18.2
3335
with:
3436
elixir-version: '1.19.4'
3537
otp-version: '28.3'
3638

37-
- name: Clone Hypatia
39+
# Upstream hyperpolymath/hypatia was refactored to shell entrypoints;
40+
# it no longer has a scanner/ subdir. Build the escript at the repo
41+
# root only if no prebuilt binary exists, and never hard-fail on a
42+
# missing/unbuildable scanner — mirrors the resilient pattern in
43+
# static-analysis-gate.yml so a tooling outage cannot block merges.
44+
- name: Clone and build Hypatia
45+
id: build
46+
continue-on-error: true
3847
run: |
39-
if [ ! -d "$HOME/hypatia" ]; then
40-
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia"
41-
fi
42-
43-
- name: Build Hypatia scanner (if needed)
44-
working-directory: ${{ env.HOME }}/hypatia
45-
run: |
46-
if [ ! -f hypatia-v2 ]; then
47-
echo "Building hypatia-v2 scanner..."
48-
cd scanner
49-
mix deps.get
50-
mix escript.build
51-
mv hypatia ../hypatia-v2
48+
git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia" 2>/dev/null || true
49+
if [ -f "$HOME/hypatia/mix.exs" ]; then
50+
cd "$HOME/hypatia"
51+
if [ ! -f hypatia ] && [ ! -f hypatia-v2 ]; then
52+
mix deps.get
53+
mix escript.build
54+
fi
55+
echo "ready=true" >> "$GITHUB_OUTPUT"
56+
else
57+
echo "::notice::Hypatia scanner not available — skipping scan"
58+
echo "ready=false" >> "$GITHUB_OUTPUT"
5259
fi
5360
5461
- name: Run Hypatia scan
5562
id: scan
63+
if: steps.build.outputs.ready == 'true'
5664
run: |
5765
echo "Scanning repository: ${{ github.repository }}"
66+
set +e
67+
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json 2>&1
68+
set -e
5869
59-
# Run scanner
60-
HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json
70+
# Sanitize: ensure valid JSON array even if the scanner errored.
71+
if [ ! -s hypatia-findings.json ] || ! jq empty hypatia-findings.json 2>/dev/null; then
72+
echo "[]" > hypatia-findings.json
73+
fi
6174
62-
# Count findings
6375
FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0)
64-
echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT
65-
66-
# Extract severity counts
67-
CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json)
68-
HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json)
69-
MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json)
76+
CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json 2>/dev/null || echo 0)
77+
HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json 2>/dev/null || echo 0)
78+
MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json 2>/dev/null || echo 0)
7079
80+
echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT
7181
echo "critical=$CRITICAL" >> $GITHUB_OUTPUT
7282
echo "high=$HIGH" >> $GITHUB_OUTPUT
7383
echo "medium=$MEDIUM" >> $GITHUB_OUTPUT
@@ -78,6 +88,16 @@ jobs:
7888
echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY
7989
echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY
8090
91+
- name: Create stub findings (when Hypatia unavailable)
92+
if: steps.build.outputs.ready != 'true'
93+
run: |
94+
echo "[]" > hypatia-findings.json
95+
{
96+
echo "## Hypatia Scan"
97+
echo ""
98+
echo "Skipped: Hypatia scanner not available in this environment."
99+
} >> "$GITHUB_STEP_SUMMARY"
100+
81101
- name: Upload findings artifact
82102
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
83103
with:
@@ -87,6 +107,7 @@ jobs:
87107

88108
- name: Submit findings to gitbot-fleet (Phase 2)
89109
if: steps.scan.outputs.findings_count > 0
110+
continue-on-error: true # external service; never block on its outage
90111
env:
91112
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92113
GITHUB_REPOSITORY: ${{ github.repository }}

0 commit comments

Comments
 (0)