feat: add POST /api/v2/templatebuilder/compose endpoint (#26351)

> [!NOTE]
> This PR was authored by Coder Agents on behalf of @jeremyruppel.

Part 4 of DEVEX-277 (POST /api/v2/templatebuilder/compose).

Adds the HTTP handler, route wiring, and integration tests for the
compose endpoint.

The handler accepts a JSON request with a base template ID and optional
modules with variable overrides, renders them via `Compose`/`BundleTar`,
and returns the tar archive directly with `Content-Type:
application/x-tar`. The registry URL comes from the deployment config
(`CODER_TEMPLATE_BUILDER_REGISTRY_URL`).

RBAC uses `policy.ActionCreate` on
`rbac.ResourceTemplate.AnyOrganization()`.

Integration tests cover: base-only compose, base with modules, unknown
base/module errors, missing base template ID, and feature-disabled 404.
This commit is contained in:
Jeremy Ruppel
2026-06-15 11:07:16 -04:00
committed by GitHub
parent c50cef5ae1
commit b61b62f4b3
8 changed files with 438 additions and 1 deletions
+2 -1
View File
@@ -406,7 +406,8 @@ func assertProduce(t *testing.T, comment SwaggerComment) {
(comment.router == "/api/v2/debug/coordinator" && comment.method == "get") ||
(comment.router == "/api/v2/debug/tailnet" && comment.method == "get") ||
(comment.router == "/api/v2/workspaces/{workspace}/acl" && comment.method == "patch") ||
(comment.router == "/api/v2/init-script/{os}/{arch}" && comment.method == "get") {
(comment.router == "/api/v2/init-script/{os}/{arch}" && comment.method == "get") ||
(comment.router == "/api/v2/templatebuilder/compose" && comment.method == "post") {
return // Exception: HTTP 200 is returned without response entity
}