Skip to content

Health check

Health check #65

Workflow file for this run

# Persistent scheduled checks that survive across Claude sessions. Mirrors the
# in-session crons (build regression, code-debt audit, community signal) but
# runs in GitHub Actions so it keeps going indefinitely. Outputs a job summary
# that's visible in the Actions tab — no notifications unless something is
# wrong (job fails on regressions).
#
# Cadence is staggered so jobs don't all run at the same minute (avoids the
# universal :00 cron-storm pattern).
name: Health check
on:
schedule:
# Daily build smoke at 07:17 UTC (~08:17 / 09:17 Berlin depending on DST).
- cron: "17 7 * * *"
# Weekly code-debt audit on Mondays at 14:23 UTC.
- cron: "23 14 * * 1"
workflow_dispatch:
permissions:
contents: read
issues: read
pull-requests: read
concurrency:
group: health-check
cancel-in-progress: false
jobs:
build-smoke:
# Fires daily AND on Mondays AND on manual dispatch.
name: Daily build smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install Cortex packages
run: |
python -m pip install --upgrade pip
pip install -e packages/cortex-core
pip install -e packages/cortex-cli
- name: Build extreme
id: build
run: |
mkdir -p /tmp/health
cortex build -c examples/extreme.yml -o /tmp/health/ | tee /tmp/build.log
MAIN=$(ls -1 /tmp/health/*.svg 2>/dev/null | wc -l)
VARIANTS=$(ls -1 /tmp/health/variants/*.svg 2>/dev/null | wc -l)
echo "main=$MAIN" >> $GITHUB_OUTPUT
echo "variants=$VARIANTS" >> $GITHUB_OUTPUT
- name: Verify XML well-formedness
run: |
python -c "
import xml.etree.ElementTree as ET, glob
files = glob.glob('/tmp/health/**/*.svg', recursive=True)
failed = []
for f in files:
try:
ET.parse(f)
except Exception as e:
failed.append((f, str(e)))
if failed:
for f, e in failed:
print(f'BAD: {f}: {e}')
raise SystemExit(1)
print(f'All {len(files)} SVGs parse cleanly')
"
- name: Compare sizes against committed examples/rendered/extreme
run: |
set +e
DELTAS=""
for f in /tmp/health/*.svg /tmp/health/variants/*.svg; do
name=$(basename "$f")
dir=$(dirname "$f" | sed 's|/tmp/health|examples/rendered/extreme|')
committed="$dir/$name"
[ ! -f "$committed" ] && continue
new_size=$(stat -c%s "$f")
old_size=$(stat -c%s "$committed")
if [ "$old_size" -eq 0 ]; then continue; fi
pct=$(awk "BEGIN { printf \"%.0f\", ($new_size - $old_size) * 100 / $old_size }")
if [ "$pct" -gt 20 ] || [ "$pct" -lt -30 ]; then
DELTAS="$DELTAS\n- \`$name\`: ${pct}% (${old_size}B -> ${new_size}B)"
fi
done
{
echo "## Daily build smoke"
echo ""
echo "**Built:** ${{ steps.build.outputs.main }} main + ${{ steps.build.outputs.variants }} variant SVGs"
echo ""
if [ -n "$DELTAS" ]; then
echo "### Size deltas > ±20-30%"
echo -e "$DELTAS"
else
echo "All file sizes within ±20% of committed baseline."
fi
} >> $GITHUB_STEP_SUMMARY
code-debt-audit:
# Only runs on the Monday cron and manual dispatch — daily would be noise.
name: Weekly code-debt audit
if: github.event.schedule == '23 14 * * 1' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install for test enumeration
run: |
python -m pip install --upgrade pip
pip install -e packages/cortex-core
pip install -e packages/cortex-cli
pip install pytest
- name: Audit
run: |
{
echo "## Weekly code-debt audit"
echo ""
echo "### TODO / FIXME markers"
COUNT=$(grep -rn "TODO\|FIXME\|XXX\|HACK" packages/ --include="*.py" 2>/dev/null | wc -l)
echo "**Total: $COUNT**"
if [ "$COUNT" -gt 0 ]; then
echo ""
echo '```'
grep -rn "TODO\|FIXME\|XXX\|HACK" packages/ --include="*.py" 2>/dev/null | head -20
echo '```'
fi
echo ""
echo "### Skipped tests"
SKIPPED=$(grep -rn "@pytest.mark.skip\|pytest.skip\|skipif" packages/ --include="*.py" 2>/dev/null | wc -l)
echo "**Total: $SKIPPED** $([ $SKIPPED -gt 0 ] && echo '⚠️ hides regressions — investigate')"
echo ""
echo "### Test count"
TESTS=$(python -m pytest packages/ --co -q 2>&1 | grep "tests collected" | head -1)
echo "$TESTS"
echo ""
echo "### Largest builders (>500 lines)"
echo ""
echo '```'
for f in packages/cortex-core/cortex/builders/*.py; do
lines=$(wc -l < "$f")
if [ "$lines" -gt 500 ]; then
echo "$lines $f"
fi
done | sort -rn | head -5
echo '```'
echo ""
echo "### Total widget builders"
BUILDERS=$(ls packages/cortex-core/cortex/builders/*.py | grep -v __init__ | wc -l)
echo "$BUILDERS builder modules currently shipped"
} >> $GITHUB_STEP_SUMMARY
community-signal:
# Same Monday cadence as debt audit — surfaces external activity.
name: Weekly community signal
if: github.event.schedule == '23 14 * * 1' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Survey issues + PRs
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
{
echo "## Weekly community signal"
echo ""
STARS=$(gh api repos/${{ github.repository }} --jq .stargazers_count)
FORKS=$(gh api repos/${{ github.repository }} --jq .forks_count)
WATCHERS=$(gh api repos/${{ github.repository }} --jq .watchers_count)
echo "**Stars:** $STARS &nbsp;·&nbsp; **Forks:** $FORKS &nbsp;·&nbsp; **Watchers:** $WATCHERS"
echo ""
echo "### Recent open issues (last 10)"
gh issue list --state open --limit 10 --json number,title,createdAt,author \
--jq '.[] | "- #\(.number) \(.title) — @\(.author.login) (\(.createdAt[:10]))"' \
|| echo "(none)"
echo ""
echo "### Recent PRs from external authors"
OWNER="${{ github.repository_owner }}"
gh pr list --state all --limit 20 --json number,title,author,state,createdAt \
--jq ".[] | select(.author.login != \"$OWNER\") | \"- #\\(.number) [\\(.state)] \\(.title) — @\\(.author.login)\"" \
|| echo "(none — only first-party PRs)"
} >> $GITHUB_STEP_SUMMARY