From 9f2e8ee9fe3e872d090a5c908ac662be9486e4bd Mon Sep 17 00:00:00 2001 From: Nicolas Varrot Date: Sat, 14 Feb 2026 04:44:06 +0000 Subject: [PATCH] ci: add failure webhook to notify OpenClaw agent for auto-fix When CI fails on main, posts failure details to OpenClaw webhook which spawns an isolated agent to diagnose and fix the issue. Webhook URL and token stored as GitHub secrets (no hardcoded URLs). --- .github/workflows/ci.yml | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2d822db..2f9d808 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,3 +53,57 @@ jobs: du -sh dist/ >> $GITHUB_STEP_SUMMARY find dist/assets -name '*.js' -exec du -sh {} \; | sort -rh >> $GITHUB_STEP_SUMMARY echo '```' >> $GITHUB_STEP_SUMMARY + + notify-failure: + needs: build + if: failure() && github.ref == 'refs/heads/main' + runs-on: ubuntu-latest + steps: + - name: Collect failure info + id: failure-info + run: | + # Fetch failed job logs via GitHub API + RUN_ID=${{ github.run_id }} + REPO=${{ github.repository }} + + # Get failed jobs + JOBS=$(curl -s -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + "https://api.github.com/repos/${REPO}/actions/runs/${RUN_ID}/jobs") + + # Extract failed steps + FAILED=$(echo "$JOBS" | python3 -c " + import json, sys + data = json.load(sys.stdin) + for job in data.get('jobs', []): + if job['conclusion'] == 'failure': + for step in job.get('steps', []): + if step['conclusion'] == 'failure': + print(f\"Job: {job['name']} | Step: {step['name']}\") + " 2>/dev/null || echo "Could not parse jobs") + + echo "failed_steps<> $GITHUB_OUTPUT + echo "$FAILED" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Notify agent webhook + if: env.OPENCLAW_WEBHOOK_URL != '' + env: + OPENCLAW_WEBHOOK_URL: ${{ secrets.OPENCLAW_WEBHOOK_URL }} + OPENCLAW_WEBHOOK_TOKEN: ${{ secrets.OPENCLAW_WEBHOOK_TOKEN }} + run: | + PAYLOAD=$(cat <