Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
Commitc424421unknown_key

feat(deploy): post failure diagnostics to GitHub Actions summary

feat(deploy): post failure diagnostics to GitHub Actions summary

Previously the 'Capture failure context' step ran but its output was
buried in the raw log. Now it also writes to the workflow Summary tab
so the owner sees systemd status + journal + caddy validate + port
listener + local /healthz directly in the Actions UI without SSH'ing.

Also added a 'port 3000 listener' check to spot EADDRINUSE crash-loops.
Claude committed on May 3, 2026Parent: ad6af41
1 file changed+328c424421e0d14ffd7e00d49da9c5b8b0cb7295240
1 changed file+32−8
Modified.github/workflows/vultr-deploy.yml+32−8View fileUnifiedSplit
108108 sleep 5
109109 systemctl status gluecron --no-pager | head -20
110110
111 # ─── 5. AI failure diagnosis (only on failure, only if ANTHROPIC set) ─
111 # ─── 5. Failure diagnostics — captured into a file for summary + AI ──
112112 - name: Capture failure context
113113 if: failure()
114114 id: ctx
120120 script_stop: false
121121 script: |
122122 echo "===== systemd status ====="
123 systemctl status gluecron --no-pager 2>&1 | head -30 || true
124 echo "===== last 100 journal lines ====="
125 journalctl -u gluecron -n 100 --no-pager 2>&1 || true
126 echo "===== caddy reload check ====="
127 caddy validate --config /etc/caddy/Caddyfile 2>&1 || true
128 echo "===== /healthz from box ====="
129 curl -s -w "HTTP %{http_code}\n" http://localhost:3000/healthz 2>&1 || true
123 systemctl status gluecron --no-pager 2>&1 | head -40 || true
124 echo ""
125 echo "===== last 80 journal lines (gluecron) ====="
126 journalctl -u gluecron -n 80 --no-pager --output=cat 2>&1 || true
127 echo ""
128 echo "===== caddy validate ====="
129 caddy validate --config /etc/caddy/Caddyfile 2>&1 | head -20 || true
130 echo ""
131 echo "===== /healthz from inside box ====="
132 curl -s -w "\nHTTP %{http_code}\n" http://localhost:3000/healthz 2>&1 || true
133 echo ""
134 echo "===== port 3000 listener ====="
135 ss -tlnp 2>&1 | grep ':3000' || echo '(nothing listening on :3000)'
136
137 # Always post the captured diagnostics to the workflow summary so the
138 # owner can read what broke without SSH'ing or grepping log files.
139 - name: Post diagnostics to summary
140 if: failure() && steps.ctx.outputs.stdout != ''
141 env:
142 DIAG: ${{ steps.ctx.outputs.stdout }}
143 run: |
144 {
145 echo "## ❌ Deploy failed — diagnostics"
146 echo ""
147 echo "**Commit:** \`${GITHUB_SHA:0:7}\` — ${GITHUB_EVENT_HEAD_COMMIT_MESSAGE:-${GITHUB_SHA:0:7}}"
148 echo "**Run:** [#${GITHUB_RUN_ID}](${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID})"
149 echo ""
150 echo '```'
151 echo "$DIAG"
152 echo '```'
153 } >> $GITHUB_STEP_SUMMARY
130154
131155 - name: AI root-cause analysis (Claude)
132156 if: failure() && env.ANTHROPIC_API_KEY != ''
133157