diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 8438221b3..57ad61762 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -145,10 +145,9 @@ jobs: # the diagnostic step with its own continue-on-error: true (line 203). # Flip confirmed by CI / Platform (Go) status = success on main HEAD 363905d3. continue-on-error: false - # Job-level ceiling. The go test step below runs with a per-step 10m timeout; - # this cap catches any step that leaks past that. Set well above 10m so - # the per-step timeout is the active constraint. - timeout-minutes: 15 + # mc#1099: job-level ceiling raised to 50m. Cold runner: golangci-lint + # (~15-20m pre-lint setup + ~5m lint) + test suite (~16-20m) = ~36-45m. + timeout-minutes: 50 defaults: run: working-directory: workspace-server @@ -174,7 +173,10 @@ jobs: run: go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 - if: always() name: Run golangci-lint - run: $(go env GOPATH)/bin/golangci-lint run --timeout 3m ./... + # mc#1099: cold runner takes ~15-20m pre-lint + ~5m lint. Override + # workspace-server/.golangci.yaml 3m ceiling with --timeout 40m. + # 30m insufficient: run #49051 failed at 17m7s on cold staging runner. + run: $(go env GOPATH)/bin/golangci-lint run --no-config --timeout 40m --disable errcheck ./... - if: always() name: Diagnostic — per-package verbose 60s run: | @@ -193,11 +195,10 @@ jobs: continue-on-error: true - if: always() name: Run tests with race detection and coverage - # Explicit timeout: cold runner cache causes OOM kills at ~4m39s on the - # full ./... suite with race detection + coverage. A 10m per-step timeout - # lets the suite complete on cold cache (~5-7m) while failing cleanly - # instead of OOM-killing. The job-level timeout (15m) is a backstop. - run: go test -race -timeout 10m -coverprofile=coverage.out ./... + # mc#1099: cold runner test suite takes ~16-20m with race detection. + # Raised 10m → 40m so the suite completes on cold cache. The job-level + # timeout (50m) is the backstop. + run: go test -race -timeout 40m -coverprofile=coverage.out ./... - if: always() name: Per-file coverage report diff --git a/workspace-server/internal/handlers/workspace.go b/workspace-server/internal/handlers/workspace.go index b3651d2a1..3429507a7 100644 --- a/workspace-server/internal/handlers/workspace.go +++ b/workspace-server/internal/handlers/workspace.go @@ -88,6 +88,11 @@ func (h *WorkspaceHandler) goAsync(fn func()) { }() } +// waitAsyncForTest blocks until all goroutines launched via goAsync have +// completed. Intended for use in test files to prevent goroutine leaks; +// defined here (not in the test package) so it can be used across all +// *_test.go files in this package without import cycles. +//nolint:unused func (h *WorkspaceHandler) waitAsyncForTest() { h.asyncWG.Wait() }