Repository navigation
Commit f20b552
authored
🤖 deps: bump Coder SDK to v2.37.3 (#163)
## Summary
Bump `github.com/coder/coder/v2` from v2.35.8 to v2.37.3 and re-vendor.
The bump also moves `github.com/modelcontextprotocol/go-sdk` from v1.4.1
to v1.7.0. That SDK no longer applies cross-origin protection by
default, so the MCP HTTP handler now wraps itself with `net/http`'s
`CrossOriginProtection` to keep the existing behavior.
The bump also changes one answer of the workspace start and stop
subresources (#187). This PR fixes that, so they behave as before (see
the table below).
Refs #150
Maintainer decision 2026-10-12: v2.37.3 ships as a stable-channel
exception.
## Background
The AI provider, chat model and MCP server APIs that the planned AI
resources need live in Coder v2.37 (chats moved from `/api/experimental`
to `/api/v2`). #150 and the AI CRDs (#154, #155, #156) need them.
Version choice: every v2.37.x release is a Coder *mainline* release. The
*stable* channel is still v2.36.6. #150 requires v2.37, so this takes
the newest v2.37 patch, v2.37.3. Its changes over v2.37.2 are a tailnet
panic fix, model catalog backports and `owner_id` on
`CreateChatRequest`. None of them touch workspaces, templates or
provisioners.
E2E backend pin: CI keeps `ghcr.io/coder/coder:v2.37.2@sha256:6ea19b67…`
(`.github/workflows/ci.yaml`). A v2.37.3 SDK against a v2.37.2 server is
a patch-level skew inside one minor line. The existing identity and
resourceVersion evidence is bound to 2.37.2, so the backend does not
move in this PR.
## Implementation
- `go get github.com/coder/coder/v2@v2.37.3`, `go mod tidy`, `go mod
vendor`, on top of current `main` (rebased, `vendor/` regenerated, not
hand-merged). The `go` directive (1.26.8) and all Kubernetes libraries
(`k8s.io/*`, controller-runtime) are unchanged. Notable transitive
moves: MCP go-sdk 1.4.1 → 1.7.0, prometheus `client_golang` 1.23.2 →
1.24.1, testify 1.11.1 → 1.12.0, `terraform-provider-coder` 2.18.0 →
2.19.0. The `go.mod` version moves are identical to the original
(pre-rebase) commit.
- `internal/app/mcpapp/http.go`: wrap the streamable HTTP handler with
`http.NewCrossOriginProtection().Handler(...)`, which is the SDK's
documented replacement for its deprecated option. The existing `cross
origin`, `opaque origin`, `cross site fetch` and `cross origin service`
cases in `TestHTTPTransportSecurity` fail without this wrap.
- `internal/app/mcpapp/http_test.go`: `application/json; charset=utf-8`
is now accepted, because the SDK matches the base media type. A charset
parameter keeps the request non-simple for CORS, so browsers still
preflight it. A new case pins the SDK's 4 MiB body limit (413).
- `docs/how-to/mcp-server.md`: request-rules table updated to match.
- `.github/workflows/ci.yaml`: add `vendor/github.com/coder/coder/v2/**`
to the pre-queue `e2e` path filter (#113). Before this change, an SDK
bump got only a skip notice in the PR's E2E job, even though the SDK
carries every aggregated-API call to the backend.
- `internal/aggregated/storage/workspace_transition.go`:
`isUncertainStatus` now counts a 2xx status as uncertain (see the first
table row). New cases in `TestWorkspaceTransitionUncertainPost` cover a
201 and a 200 proxy page.
- CoderTemplateTest tests (no controller change): the fake Coder gets an
`HTML` fault (a `text/html` body with any status). New cases pin a 200
and a 201 proxy page on create (`TestTemplateTestCreateResults`) and a
200 proxy page on the readiness read
(`TestTemplateTestReadinessProxyPage`).
### SDK behavior changes that affect existing resources
| Change | Evidence | Effect here |
| --- | --- | --- |
| A 2xx response whose body is not valid JSON (empty, HTML, malformed)
now returns `*codersdk.Error` with the 2xx status. It used to be a plain
decode error. `Error()` reads `invalid API response (status code N)`,
`Message` reads `Received an HTML response instead of JSON from the
Coder API.` (or the empty/invalid JSON variant), and `Unwrap` exposes
the cause. | `codersdk/client.go:521`, `:538-571`, `:664-680`, `:743` |
**Workspace start/stop (#187), fixed here.**
`workspace_transition.go:156` re-reads Coder when the error is not a
`*codersdk.Error` or has an uncertain status. A 2xx proxy page used to
take that path. With the bump it fell through to `MapCoderError` and
answered a definitive 500, although Coder had queued the build.
`isUncertainStatus` now includes 2xx, so the answer is again the
confirmed `Queued` result or the uncertain 504. **CoderTemplateTest
(#194-#213), no classification change.** Every `coderStatus()` branch
matches only specific 4xx codes (401, 404, 406, 409, 410, 412, 429, 400)
or the 4xx range, so a 2xx `*codersdk.Error` takes the same branch as
the old status-0 decode error: create stays `ConfirmingCreate` and never
sends a second request (`codertemplatetest_create.go:59-93`).
`createHadNoEffect` does not match 2xx, so the marker stays. The
readiness and confirm reads answer `CoderUnavailable` and never treat
the answer as 410 deletion (`codertemplatetest_readiness.go:36`,
`codertemplatetest_confirm.go:44`, `:66`). The status message changes
from the raw decode error to `Coder answered 2xx: Received an HTML
response…`. It holds `Message` only, so `Detail` (content type, redirect
URL) does not reach status. **Everything else, no change.**
`MapCoderError` (`internal/aggregated/coder/errors.go`),
`template_promote.go:181` (4xx only, else re-read), and the control
plane and provisioner controllers branch on 4xx only, so 2xx falls
through to the same InternalError or retry path as before. |
| A JSON body with `Content-Type: text/html` is now an error. The old
decoder ignored the header and decoded it. |
`codersdk/client.go:544-547` | Coder never labels API JSON as HTML, so
only a misconfigured proxy sees this. A CoderTemplateTest create then
becomes uncertain and confirms the workspace by provenance instead of
taking the answer. That is the fail-safe direction. |
| `Template.AgentsAllowed` (new field).
`UpdateTemplateMeta.AgentsAllowed` and
`CreateTemplateRequest.AgentsAllowed` are `*bool,omitempty`. |
`codersdk/templates.go:71`, `:288`; `codersdk/organizations.go:235` |
`convert/template.go` never sets it, so the server keeps the current
value on update and defaults it to true on create. This is the same as
before, because the 2.37.2 server already applies those defaults. Not
surfaced in the CR. CoderTemplateTest creates workspaces through the
normal API as the operator user, not as a Coder Agent, so the flag does
not gate it. |
| `CreateWorkspaceBuildRequest.OnSuccess` (omitempty),
`WorkspaceFilter.IncludeAgentMetadata`, `WorkspaceAgent.Metadata`
(omitempty) | `codersdk/workspaces.go:142`, `:565`;
`codersdk/workspaceagents.go:177` | Unset, so the wire requests are
unchanged. That includes the CoderTemplateTest delete build
(`codertemplatetest_delete.go:103`) and the start/stop builds.
CoderTemplateTest readiness reads agent status and lifecycle only, never
`Metadata`. |
| Prebuilds: `PrebuildsSystemUserID` and the agent status, lifecycle,
provisioner job status and transition constants |
`codersdk/prebuilds.go:13` | Unchanged values. CoderTemplateTest
provenance (`codertemplatetest_confirm.go:135`) still recognizes claimed
prebuilds by this user ID. |
| Entitlement comparison: a nil limit on a usage-period feature now
means unlimited | `codersdk/deployment.go:438` | Only
`agent_runtime_hours` is a usage-period feature. The control plane and
provisioner read `external_provisioner_daemons`,
`multiple_organizations` and `custom_roles`, which are unaffected. |
| `License.Trial()` reads the `trial` claim (was misspelled `trail`).
New reserved-provisioner-key helpers. | `codersdk/licenses.go:86`;
`codersdk/provisionerdaemons.go:426` | Not called by coder-k8s. |
| MCP go-sdk: cross-origin protection is off by default, `Content-Type`
matches the base media type, and request bodies are limited to 4 MiB |
`go-sdk/mcp/streamable.go:243`, `:388`, `:225` | Cross-origin protection
restored by the wrap above. The other two are documented and tested.
DNS-rebinding (loopback `Host`) protection is unchanged. |
## Validation
On the pushed commit `48891a0` (tree `cffac8d`), rebased onto `main`
`41e4acb` (#222: go1.26.9 and `golang.org/x/net` v0.60.0): actionlint,
`make verify-vendor`, `make test`, `make test-integration`, `make
build`, `make lint`, `make docs-check`, `GOFLAGS=-mod=vendor go tool
govulncheck ./...` (the CI command: 0 called vulnerabilities) and `go
test -race -count=1 ./internal/controller/...` all pass.
Dependencies: I reset `go.mod` and `go.sum` to `main`, then ran `go get
github.com/coder/coder/v2@v2.37.3 && go mod tidy && go mod vendor`. The
`go` directive stays 1.26.9 and `x/net` stays v0.60.0. The `go.mod` and
`go.sum` diffs against `main` are line-for-line identical to the diffs
of the previous head (`522fd78` against `55e7f34`), so the SDK bump
moves the same modules as before on top of the #222 baseline.
The new `TestWorkspaceTransitionUncertainPost` rows fail on the v2.37.3
SDK without the `isUncertainStatus` fix (no confirming re-read). The 200
row also fails on `main` with the v2.35.8 SDK. That SDK already returned
`*codersdk.Error` for a 200 on a POST that expects 201, so that gap
predates this PR, and the fix also covers it.
Known local-only failure: `hack/e2e-workspace-lifecycle_test.sh` (part
of `make test-scripts`) times out locally in its `pass` scenario. It
fails the same way on unmodified `main` on this host. The PR touches no
`hack/` script. CI's run is authoritative.
---
_Generated with [`xum`](https://github.com/coder/xum) • Model:
`anthropic:claude-opus-5-5` • Thinking: `high`_1 parent 41e4acb commit f20b552
258 files changed
Lines changed: 20652 additions & 4665 deletions
File tree
- .github/workflows
- docs/how-to
- internal
- aggregated/storage
- app/mcpapp
- controller
- vendor
- github.com
- apparentlymart/go-textseg/v17
- textseg
- internal
- charprops
- machine
- coder/coder/v2
- coderd
- rbac/policy
- tracing
- util
- ptr
- strings
- codersdk
- coreos/go-oidc/v3/oidc
- ebitengine/purego/internal/fakecgo
- google/jsonschema-go/jsonschema
- hashicorp/terraform-plugin-log
- internal
- fieldutils
- hclogutils
- logging
- tflog
- tfsdklog
- klauspost/compress
- flate
- huff0
- internal/snapref
- s2
- zstd
- modelcontextprotocol/go-sdk
- auth
- internal
- authutil
- jsonrpc2
- json
- util
- mcp
- oauthex
- prometheus
- client_golang
- internal/github.com/golang/gddo/httputil/header
- prometheus
- collectors
- internal
- promhttp
- procfs
- stretchr
- objx
- testify
- assert
- internal
- difflib
- spew
- mock
- require
- valyala/fasthttp/fasthttputil
- zclconf/go-cty/cty
- ctystrings
- function/stdlib
- internal/graphemes
- go.opentelemetry.io
- contrib/instrumentation/net/http/otelhttp
- internal
- request
- semconv
- otel/semconv/v1.43.0/httpconv
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
91 | 91 | | |
92 | 92 | | |
93 | 93 | | |
| 94 | + | |
| 95 | + | |
94 | 96 | | |
95 | 97 | | |
96 | 98 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
73 | 73 | | |
74 | 74 | | |
75 | 75 | | |
76 | | - | |
| 76 | + | |
77 | 77 | | |
78 | 78 | | |
79 | 79 | | |
| 80 | + | |
80 | 81 | | |
81 | | - | |
82 | | - | |
| 82 | + | |
| 83 | + | |
83 | 84 | | |
84 | 85 | | |
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
88 | | - | |
| 89 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
| 6 | + | |
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
11 | | - | |
12 | | - | |
| 11 | + | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
95 | 95 | | |
96 | 96 | | |
97 | 97 | | |
| 98 | + | |
98 | 99 | | |
99 | 100 | | |
100 | | - | |
| 101 | + | |
101 | 102 | | |
102 | 103 | | |
103 | 104 | | |
| |||
130 | 131 | | |
131 | 132 | | |
132 | 133 | | |
133 | | - | |
134 | | - | |
| 134 | + | |
| 135 | + | |
135 | 136 | | |
136 | 137 | | |
137 | 138 | | |
| |||
141 | 142 | | |
142 | 143 | | |
143 | 144 | | |
144 | | - | |
| 145 | + | |
145 | 146 | | |
146 | 147 | | |
147 | 148 | | |
| |||
196 | 197 | | |
197 | 198 | | |
198 | 199 | | |
199 | | - | |
| 200 | + | |
200 | 201 | | |
201 | 202 | | |
202 | 203 | | |
| |||
218 | 219 | | |
219 | 220 | | |
220 | 221 | | |
221 | | - | |
| 222 | + | |
222 | 223 | | |
223 | 224 | | |
224 | 225 | | |
| |||
234 | 235 | | |
235 | 236 | | |
236 | 237 | | |
237 | | - | |
| 238 | + | |
238 | 239 | | |
239 | 240 | | |
240 | 241 | | |
| |||
292 | 293 | | |
293 | 294 | | |
294 | 295 | | |
295 | | - | |
| 296 | + | |
296 | 297 | | |
297 | | - | |
298 | | - | |
| 298 | + | |
| 299 | + | |
299 | 300 | | |
300 | 301 | | |
301 | 302 | | |
| |||
334 | 335 | | |
335 | 336 | | |
336 | 337 | | |
337 | | - | |
| 338 | + | |
338 | 339 | | |
339 | 340 | | |
340 | 341 | | |
| |||
349 | 350 | | |
350 | 351 | | |
351 | 352 | | |
352 | | - | |
| 353 | + | |
353 | 354 | | |
354 | 355 | | |
355 | 356 | | |
| |||
363 | 364 | | |
364 | 365 | | |
365 | 366 | | |
366 | | - | |
| 367 | + | |
367 | 368 | | |
368 | 369 | | |
369 | 370 | | |
| |||
380 | 381 | | |
381 | 382 | | |
382 | 383 | | |
383 | | - | |
| 384 | + | |
384 | 385 | | |
385 | 386 | | |
386 | 387 | | |
| |||
412 | 413 | | |
413 | 414 | | |
414 | 415 | | |
415 | | - | |
| 416 | + | |
416 | 417 | | |
417 | 418 | | |
418 | 419 | | |
| |||
0 commit comments