Make Forgejo lint CI fail fast when golangci-lint-action wedges #769

Closed
opened 2026-07-09 06:05:02 +00:00 by coilyco-ops · 2 comments
Member

Incident context from 2026-07-09, ward PR #766 / action run 1141:

Attempt 1 of the test job looked like golangci-lint was running for ~22 minutes, but the raw log shows two separate failures:

  • golangci/golangci-lint-action@v9 spent ~6m13s installing golangci-lint v2.12.2 because the GitHub release download hit Request timeout once, then retried and installed successfully.
  • the actual golangci-lint run completed in 2737ms and printed six lint findings at 2026-07-09T05:42:47Z.
  • after that, no log lines appeared until 2026-07-09T05:58:30Z, when the runner cancelled the attempt with context canceled and only then ran the post steps.

Attempt 2 on the same run finished normally in 28s and failed on the lint findings. After ward#767 landed, run 1142 passed in 34s.

Fix direction:

  • Stop depending on a long-lived Node action path for Forgejo lint if a static golangci-lint run step will do.
  • Prefer the dev-base image or a bounded direct install path so the linter binary is already present or install timeout is explicit.
  • Add a job/step timeout that makes this failure mode fail in minutes, not hang until a manual rerun or runner cancellation.
  • Keep .github/workflows/test.yml and .forgejo/workflows/test.yml mirror-safe per the existing workflow mirror rules.

Acceptance:

  • ward test workflow still runs vet, tests, and golangci-lint on push and PR.
  • a lint failure returns a failed check promptly without waiting for action cleanup/cache behavior.
  • ward exec lint and ward exec test pass locally.
  • docs/FEATURES.md only changes if the workflow capability materially changes; otherwise leave docs alone.
Incident context from 2026-07-09, ward PR #766 / action run 1141: Attempt 1 of the `test` job looked like `golangci-lint` was running for ~22 minutes, but the raw log shows two separate failures: * `golangci/golangci-lint-action@v9` spent ~6m13s installing `golangci-lint` v2.12.2 because the GitHub release download hit `Request timeout` once, then retried and installed successfully. * the actual `golangci-lint run` completed in 2737ms and printed six lint findings at 2026-07-09T05:42:47Z. * after that, no log lines appeared until 2026-07-09T05:58:30Z, when the runner cancelled the attempt with `context canceled` and only then ran the post steps. Attempt 2 on the same run finished normally in 28s and failed on the lint findings. After ward#767 landed, run 1142 passed in 34s. Fix direction: * Stop depending on a long-lived Node action path for Forgejo lint if a static `golangci-lint run` step will do. * Prefer the dev-base image or a bounded direct install path so the linter binary is already present or install timeout is explicit. * Add a job/step timeout that makes this failure mode fail in minutes, not hang until a manual rerun or runner cancellation. * Keep `.github/workflows/test.yml` and `.forgejo/workflows/test.yml` mirror-safe per the existing workflow mirror rules. Acceptance: * ward test workflow still runs vet, tests, and golangci-lint on push and PR. * a lint failure returns a failed check promptly without waiting for action cleanup/cache behavior. * `ward exec lint` and `ward exec test` pass locally. * docs/FEATURES.md only changes if the workflow capability materially changes; otherwise leave docs alone.
Author
Member

🔒 Reserved by ward agent --harness codex — container engineer-codex-ward-769 on host kais-macbook-pro-2.local is carrying this issue (reserved 2026-07-09T06:05:08Z). Concurrent ward agent runs are blocked until it finishes or the reservation goes stale (1h TTL); --force overrides.

Do not comment on or edit this issue to steer the run while it is reserved. The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a new issue, dispatched fresh — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494).

run seed context — what this run is carrying (ward#609)
  • Resolved: coilyco-flight-deck/ward#769 · branch issue-769 · harness codex · workflow pr
  • Run: engineer-codex-ward-769 · ward v0.474.0 · dispatched 2026-07-09T06:05:08Z
  • Comment thread: 0 included in the pre-flight read, 0 stripped (ward's own automated comments).

Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.474.0).

— Codex, via ward agent

<!-- ward-agent-reservation --> 🔒 Reserved by `ward agent --harness codex` — container `engineer-codex-ward-769` on host `kais-macbook-pro-2.local` is carrying this issue (reserved 2026-07-09T06:05:08Z). Concurrent `ward agent` runs are blocked until it finishes or the reservation goes stale (1h TTL); `--force` overrides. **Do not comment on or edit this issue to steer the run while it is reserved.** The engineer seeded the body once at launch and never re-reads it, so a comment or edit reaches only human readers, never the running engineer. A correction goes to a **new issue, dispatched fresh** — that is the only channel that reaches a run in flight. Where the forge supports it, ward locks this conversation to make that a road-block rather than a convention (ward#494). <details><summary>run seed context — what this run is carrying (ward#609)</summary> - **Resolved:** `coilyco-flight-deck/ward#769` · branch `issue-769` · harness `codex` · workflow `pr` - **Run:** `engineer-codex-ward-769` · ward `v0.474.0` · dispatched `2026-07-09T06:05:08Z` - **Comment thread:** 0 included in the pre-flight read, 0 stripped (ward's own automated comments). Static container doctrine and seed boilerplate are identical every run and omitted here (they ride ward v0.474.0). </details> <!-- ward-agent-signature --> — Codex, via `ward agent`
Author
Member

WARD-OUTCOME: done - replaced golangci-lint-action with direct golangci-lint run in the dev-base container and added explicit timeouts
workflow: pr; review summary: review gate skipped by --skip-review / --no-review-gate

This was straightforward once the workflow mirror rules were checked. The only friction was ward needing a writable HOME for its audit log in this container. Confidence is high because the repo verbs passed locally and the mirror check stayed clean.

WARD-OUTCOME: done - replaced golangci-lint-action with direct golangci-lint run in the dev-base container and added explicit timeouts workflow: pr; review summary: review gate skipped by --skip-review / --no-review-gate This was straightforward once the workflow mirror rules were checked. The only friction was ward needing a writable HOME for its audit log in this container. Confidence is high because the repo verbs passed locally and the mirror check stayed clean.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-flight-deck/ward#769
No description provided.