From ebb875af5eaf207e55895a8e02be4bbe8720ca48 Mon Sep 17 00:00:00 2001 From: Todd Hebebrand Date: Tue, 14 Jul 2026 18:49:04 -0600 Subject: [PATCH 1/2] ci(agent): gate Go vet + lint, race the full agent tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `lint` job is JS/TS + compose guards only — the Go agent was never vet/lint-gated in CI (golangci-lint lived only in agent/Makefile), and `test-agent` runs CGO-off so the race detector never ran on the broad tree. - lint-agent: `go vet ./...` (hard gate; tree is already vet-clean) + golangci-lint in new-issues-only mode (--new-from-rev) so the pre-existing backlog (incl. ~20 unformatted files) does not block PRs. - test-agent-race: `go test -race ./...` across the whole linux-buildable agent tree (~80s) so new concurrency-heavy packages are covered without a hand-maintained list. - agent/.golangci.yml: golangci-lint v2 config (standard linters + gofmt). Verified locally: go vet clean, go test -race ./... green (81s), golangci-lint --new-from-rev=origin/main = 0 issues, actionlint clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci.yml | 61 ++++++++++++++++++++++++++++++++++++++++ agent/.golangci.yml | 17 +++++++++++ 2 files changed, 78 insertions(+) create mode 100644 agent/.golangci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5477aaaea..137c2d7a70 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -796,6 +796,67 @@ jobs: working-directory: agent run: go test -race ./internal/sessionbroker ./internal/eventlog ./internal/watchdog ./cmd/breeze-watchdog + # ─── Go agent lint ──────────────────────────────────────────────────── + # The `lint` job above is JS/TS + compose guards only; the Go agent was + # never vet/lint-gated in CI (golangci-lint lived only in agent/Makefile). + # `go vet` is an unconditional gate (the tree is already vet-clean). + # golangci-lint runs in new-issues-only mode so the pre-existing backlog + # (incl. ~20 unformatted files) does not block PRs — burn it down separately. + lint-agent: + name: Lint Agent (Go) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version: ${{ env.GO_VERSION }} + cache-dependency-path: agent/go.sum + + - name: go vet + working-directory: agent + run: go vet ./... + + - name: golangci-lint (new issues only) + working-directory: agent + env: + BASE_REF: ${{ github.base_ref || 'main' }} + run: | + go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 + golangci-lint run --new-from-rev="origin/${BASE_REF}" ./... + + # ─── Go agent race tests (broad) ────────────────────────────────────── + # test-agent runs the suite CGO-off (no race detector). This job races the + # ENTIRE linux-buildable agent tree so new concurrency-heavy packages are + # covered automatically without a hand-maintained list (~80s locally). CGO is + # required by the race detector. Windows-only concurrency is covered by the + # agent's own windows race jobs. + test-agent-race: + name: Test Agent (race) + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v7 + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version: ${{ env.GO_VERSION }} + cache-dependency-path: agent/go.sum + + - name: Download Go dependencies + working-directory: agent + run: go mod download + + - name: go test -race ./... + working-directory: agent + run: CGO_ENABLED=1 go test -race -count=1 ./... + # ─── Windows runtime smoke (#1000) ──────────────────────────────────── # CI cross-compiles the Windows agent (build-agent matrix) but never RAN # it on Windows, so runtime-only Windows regressions shipped green. This diff --git a/agent/.golangci.yml b/agent/.golangci.yml new file mode 100644 index 0000000000..981315f420 --- /dev/null +++ b/agent/.golangci.yml @@ -0,0 +1,17 @@ +# golangci-lint config for the Breeze Go agent. +# +# Introduced red-safe: CI runs this with `--new-from-rev=origin/` so only +# issues on code a PR actually changes are reported. The pre-existing backlog +# (including ~20 unformatted files on main) is NOT gated — it can be burned down +# separately. `go vet` runs as an unconditional gate because the tree is already +# vet-clean. +version: "2" + +linters: + # Standard set: errcheck, govet, ineffassign, staticcheck, unused. + default: standard + +formatters: + # gofmt is reported (new code only via --new-from-rev); does not rewrite. + enable: + - gofmt From a24dd58d2703dde9158c4bd238aef3a1b7d1a9f6 Mon Sep 17 00:00:00 2001 From: Todd Hebebrand Date: Tue, 14 Jul 2026 19:02:33 -0600 Subject: [PATCH 2/2] ci(agent): fix CGO for lint/race jobs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both new jobs turned CGO on (vet compiles with it; -race requires it), which pulled in the agent's only cgo files — the linux X11/pcap capture backends (pcap.h, X11/Xlib.h) — whose C headers aren't on the runner. The repo only cgo-builds the agent on darwin (build-agent), never linux. - lint-agent: run vet + golangci CGO-off (matches test-agent). vet/lint cover the CGO-off build; the cgo backends are compiled by build-agent. - test-agent-race: -race needs CGO, so run on macos-latest — the repo's only cgo agent build path — reproducing the green local run. Concurrency logic is platform-independent. Adds CGO_LDFLAGS_ALLOW to match build-agent's darwin. Verified: CGO=0 vet clean, CGO=0 golangci --new-from-rev = 0 issues, CGO=1 go test -race ./... green locally (darwin, 81s), actionlint clean. --- .github/workflows/ci.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 137c2d7a70..d0f3fe10f4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -805,6 +805,11 @@ jobs: lint-agent: name: Lint Agent (Go) runs-on: ubuntu-latest + # CGO off (matches test-agent): the agent's only cgo files are the linux + # X11/pcap capture backends, whose C headers are not on the runner. vet + + # lint cover the CGO-off build; the cgo backends are compiled by build-agent. + env: + CGO_ENABLED: '0' steps: - name: Checkout uses: actions/checkout@v7 @@ -831,13 +836,15 @@ jobs: # ─── Go agent race tests (broad) ────────────────────────────────────── # test-agent runs the suite CGO-off (no race detector). This job races the - # ENTIRE linux-buildable agent tree so new concurrency-heavy packages are - # covered automatically without a hand-maintained list (~80s locally). CGO is - # required by the race detector. Windows-only concurrency is covered by the - # agent's own windows race jobs. + # ENTIRE agent tree so new concurrency-heavy packages are covered + # automatically without a hand-maintained list (~80s). The race detector + # requires CGO; it runs on macOS to match the repo's only cgo agent build + # (build-agent darwin) — the linux agent is never cgo-built in CI, and the + # concurrency logic under test is platform-independent. Windows-only + # concurrency is covered by the agent's own windows race jobs. test-agent-race: name: Test Agent (race) - runs-on: ubuntu-latest + runs-on: macos-latest timeout-minutes: 15 steps: - name: Checkout @@ -855,6 +862,8 @@ jobs: - name: go test -race ./... working-directory: agent + env: + CGO_LDFLAGS_ALLOW: '-weak_framework|ScreenCaptureKit' run: CGO_ENABLED=1 go test -race -count=1 ./... # ─── Windows runtime smoke (#1000) ────────────────────────────────────