[CI] cd-develop run flipped to failure ~30 min AFTER the job succeeds (act_runner v0.2.11 / Gitea status-reconciliation) — NOT the smoke window #12

Open
opened 2026-07-08 17:00:37 -04:00 by hiveiq · 3 comments
Owner

cd-develop smoke step false-fails after a successful deploy

Symptom: run #6 (task 1738, sha 11d6369, from PR #11) is marked failure, but the deploy actually succeeded — guide.bcos.dev serves the new content (QDS_ADMIN correctly removed from all modules) and GET /guide/actuator/health returns 200 {"status":"UP"}.

Cause: the Smoke — guide backend healthy step polls health for only 60 s (for i in $(seq 1 12) × sleep 5). The step runs immediately after docker compose up -d restarts the Spring Boot backend, which usually needs longer than 60 s to warm up and report healthy. The window expires → exit 1 → job fails, even though the deploy is fine. (Runtime was also ~32 min total — a slow runner build/push eats into the budget.)

This is the same class of false-failure that #9 fixed for the Slack notify step, one step earlier in the job.

Fix: widen the smoke window to ~5 min (e.g. 30 × 10 s) and echo attempts for observability. No behavioural change to the deploy itself.

Impact: cosmetic today (deploys work), but a permanently-red cd-develop badge trains people to ignore it and hides real deploy failures.

## `cd-develop` smoke step false-fails after a successful deploy **Symptom:** run #6 (task 1738, sha `11d6369`, from PR #11) is marked **failure**, but the deploy actually succeeded — guide.bcos.dev serves the new content (`QDS_ADMIN` correctly removed from all modules) and `GET /guide/actuator/health` returns `200 {"status":"UP"}`. **Cause:** the `Smoke — guide backend healthy` step polls health for only **60 s** (`for i in $(seq 1 12)` × `sleep 5`). The step runs immediately after `docker compose up -d` restarts the Spring Boot backend, which usually needs **longer than 60 s** to warm up and report healthy. The window expires → `exit 1` → job fails, even though the deploy is fine. (Runtime was also ~32 min total — a slow runner build/push eats into the budget.) This is the same class of false-failure that #9 fixed for the Slack notify step, one step earlier in the job. **Fix:** widen the smoke window to ~5 min (e.g. 30 × 10 s) and echo attempts for observability. No behavioural change to the deploy itself. **Impact:** cosmetic today (deploys work), but a permanently-red `cd-develop` badge trains people to ignore it and hides real deploy failures.
hiveiq self-assigned this 2026-07-08 17:00:37 -04:00
hiveiq added the Testing label 2026-07-08 17:01:16 -04:00
hiveiq changed title from [CI] cd-develop smoke health-check window too short — false 'deploy FAILED' after successful deploy to [CI] cd-develop run flipped to `failure` ~30 min AFTER the job succeeds (act_runner v0.2.11 / Gitea status-reconciliation) — NOT the smoke window 2026-07-08 18:12:52 -04:00
hiveiq reopened this issue 2026-07-08 18:12:52 -04:00
Author
Owner

Correction — root cause is NOT the smoke window

Reopening. The smoke-window theory (fixed in PR #13, merged) was a misdiagnosis. Job logs for run #7 (983037e, job 1771) prove the job actually succeeds — Gitea just mislabels the run ~30 min later.

Evidence — run #7, runner dlx-hiveiq-runner-01 (act_runner v0.2.11), UTC

Time Event
21:13:28 Runner picks up task
21:14:12 Deploy to bcos.dev
21:14:19 Smoke attempt 1 → health=502 (backend restarting)
21:14:30 Smoke attempt 2 → guide healthy
21:14:30 Slack notify HTTP 200 — green card posted
21:14:33 🏁 Job succeeded — all steps green
21:45:11 Gitea flips the run to failure31 min after the job finished

Job wall-time: ~65 s, fully green. Same pattern on run #6 (#11): job done fast, run marked failed ~32 min later.

Real cause

Gitea ↔ act_runner status-reconciliation failure: the runner completes and reports success, but Gitea never records the final status and eventually times the run out to failure (zombie/abandoned-task timeout). act_runner v0.2.11 is old; likely fixed by upgrading the runner and/or tuning Gitea [actions] ZOMBIE_TASK_TIMEOUT / ENDLESS_TASK_TIMEOUT.

Notes

  • Deploys are healthy — content live on guide.bcos.dev, backend 200 UP. Only the badge lies.
  • PR #13 (wider smoke) is harmless and stays — it did catch a real 502→recover on attempt 1 — but it does not fix this.
  • Runner + Gitea live on the DLX lab network (dlx-hiveiq-runner-01, Gitea 192.168.200.226) → owned by dlx-claude. Handoff email sent to dlx-claude for runner/Gitea investigation.
## Correction — root cause is NOT the smoke window Reopening. The smoke-window theory (fixed in PR #13, merged) was a **misdiagnosis**. Job logs for run #7 (`983037e`, job 1771) prove the job actually **succeeds** — Gitea just mislabels the run ~30 min later. ### Evidence — run #7, runner `dlx-hiveiq-runner-01` (act_runner **v0.2.11**), UTC | Time | Event | |---|---| | 21:13:28 | Runner picks up task | | 21:14:12 | Deploy to bcos.dev ✅ | | 21:14:19 | Smoke attempt 1 → `health=502` (backend restarting) | | 21:14:30 | Smoke attempt 2 → `guide healthy` ✅ | | 21:14:30 | Slack notify **HTTP 200** — green card posted | | 21:14:33 | **`🏁 Job succeeded`** — all steps green | | **21:45:11** | **Gitea flips the run to `failure`** — **31 min after** the job finished | Job wall-time: **~65 s**, fully green. Same pattern on run #6 (#11): job done fast, run marked failed ~32 min later. ### Real cause Gitea ↔ act_runner **status-reconciliation failure**: the runner completes and reports success, but Gitea never records the final status and eventually times the run out to `failure` (zombie/abandoned-task timeout). act_runner **v0.2.11** is old; likely fixed by upgrading the runner and/or tuning Gitea `[actions]` `ZOMBIE_TASK_TIMEOUT` / `ENDLESS_TASK_TIMEOUT`. ### Notes - **Deploys are healthy** — content live on guide.bcos.dev, backend `200 UP`. Only the badge lies. - PR #13 (wider smoke) is harmless and stays — it did catch a real 502→recover on attempt 1 — but it does **not** fix this. - **Runner + Gitea live on the DLX lab network** (`dlx-hiveiq-runner-01`, Gitea `192.168.200.226`) → owned by dlx-claude. Handoff email sent to dlx-claude for runner/Gitea investigation.
Author
Owner

Root cause found & fixed (dlx-claude, Gitea side / CT226)

Not act_runner — a Gitea MySQL connection-pool bug, fleet-wide (not guide-specific).

Mechanism: Gitea's pool CONN_MAX_LIFETIME=3h outlived MySQL's wait_timeout=600s. MySQL server-side-killed idle connections after 10 min; Gitea's Go pool kept handing out the dead ones, so writes on them silently failed (connection reset by peer / broken pipe). When the dead write was a task's final-status UPDATE, the task stuck at Running until the 30 m ZOMBIE_TASK_TIMEOUT watchdog force-failed it as stale — exactly our ~31-32 min pattern on runs #6/#7. The same failed write also lost the task's log transfer.

Confirmed via Gitea journalctl for run #7 (task 1739): act_runner logs clean; MySQL connection reset by peer at 17:20:11 mid-run; clear_tasks.go force-failed at 17:45:11 (= pickup + ZOMBIE_TASK_TIMEOUT). Same daily zombie-kill hit claims, mgmt, devices, auth, recon since ~Jul 5.

Fix applied (with Johannes's go-ahead): CONN_MAX_LIFETIME=5m in /etc/gitea/app.ini on CT226 (below MySQL's 10 min wait_timeout, so the pool recycles proactively). app.ini backed up, gitea restarted, HTTP 200 verified. act_runner v0.2.11 unchanged.

Status: monitoring the next cd-develop runs to confirm the false-red is gone. Applying Verify Fix. PR #13 (wider smoke) stays as a harmless robustness win but was not the cause.

## Root cause found & fixed (dlx-claude, Gitea side / CT226) Not act_runner — a **Gitea MySQL connection-pool bug**, fleet-wide (not guide-specific). **Mechanism:** Gitea's pool `CONN_MAX_LIFETIME=3h` outlived MySQL's `wait_timeout=600s`. MySQL server-side-killed idle connections after 10 min; Gitea's Go pool kept handing out the dead ones, so writes on them silently failed (`connection reset by peer` / `broken pipe`). When the dead write was a task's **final-status UPDATE**, the task stuck at `Running` until the **30 m `ZOMBIE_TASK_TIMEOUT`** watchdog force-failed it as stale — exactly our ~31-32 min pattern on runs #6/#7. The same failed write also lost the task's log transfer. **Confirmed** via Gitea `journalctl` for run #7 (task 1739): act_runner logs clean; MySQL `connection reset by peer` at 17:20:11 mid-run; `clear_tasks.go` force-failed at 17:45:11 (= pickup + `ZOMBIE_TASK_TIMEOUT`). Same daily zombie-kill hit claims, mgmt, devices, auth, recon since ~Jul 5. **Fix applied** (with Johannes's go-ahead): `CONN_MAX_LIFETIME=5m` in `/etc/gitea/app.ini` on CT226 (below MySQL's 10 min `wait_timeout`, so the pool recycles proactively). app.ini backed up, gitea restarted, HTTP 200 verified. act_runner v0.2.11 unchanged. **Status:** monitoring the next cd-develop runs to confirm the false-red is gone. Applying `Verify Fix`. PR #13 (wider smoke) stays as a harmless robustness win but was not the cause.
hiveiq added the Verify Fix label 2026-07-08 18:28:00 -04:00
Author
Owner

Verified — fix confirmed

Re-ran the exact failing run (same commit 983037e) after the CT226 CONN_MAX_LIFETIME=5m fix:

Run Runtime Result
Before fix 31.7 min 🔴 failure (30 min zombie-timeout)
After fix (re-run) 1.0 min success

Same commit, same workflow — the only variable changed is the Gitea MySQL pool lifetime. The run now records its final status in ~1 min instead of hanging until the watchdog kills it. False-red is gone.

Deploys were healthy throughout; this was badge-only. Leaving open for the team to close per process.

## ✅ Verified — fix confirmed Re-ran the exact failing run (same commit `983037e`) after the CT226 `CONN_MAX_LIFETIME=5m` fix: | Run | Runtime | Result | |---|---|---| | Before fix | **31.7 min** | 🔴 failure (30 min zombie-timeout) | | After fix (re-run) | **1.0 min** | ✅ **success** | Same commit, same workflow — the only variable changed is the Gitea MySQL pool lifetime. The run now records its final status in ~1 min instead of hanging until the watchdog kills it. False-red is gone. Deploys were healthy throughout; this was badge-only. Leaving open for the team to close per process.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hiveiq-src/hiveops-guide#12