First beta release with the Atlantis-style apply-then-merge workflow, monorepo workspace autodiscovery, and a cleaner Terrapod-native API namespace.
Highlights
- Apply-then-merge VCS workflow with PR/MR comment interactivity — opt-in per workspace (
vcs_workflow: apply_then_merge). PR push triggers a full plan-and-save;terrapod applyfrom a PR comment runs the saved tfplan; Terrapod auto-merges (orterrapod mergedoes it) once every PR-affected workspace has applied. Authorization is delegated to the VCS provider — if you can merge the PR, you can apply it. Comment vocabulary:terrapod plan / apply / merge / unlock / help, with-W <workspace>to scope. Dual-actor audit records the VCS user, not a Terrapod identity. Modelled on Atlantis. See docs/vcs-workflows.md. - Workspace autodiscovery — connection-scoped rules with glob patterns + ignore_paths auto-create a workspace the first time a PR or default-branch push touches a matching directory. Template fields (execution mode, agent pool, terraform version, resources, labels, owner) inherited per rule. See docs/autodiscovery.md.
- API namespace cleanup (backward-compatible) — Terrapod-native management routes are now canonically served at
/api/terrapod/v1/. The TFE-V2 CLI contract (workspaces, runs, state, configuration versions, registry CLI protocols) stays at/api/v2/forterraform/tofu/tfci/go-tfe. The surface is catalogued in docs/tfe-cli-surface.md. Existing callers keep working — every Terrapod-native route is also still mounted at its pre-v0.23/api/v2/...path withDeprecation/X-Removed-In: v0.24.0response headers. The legacy mounts are scheduled for removal in v0.24.0 (#278). - Plan summary badges —
+5 ~2 -1 ⟳3 ↓1chip row above Confirm & Apply on the run detail page, with a Changes column on the runs list. Counts are extracted from the JSON plan output the runner already uploads. /plans/{id}/json-output— terraform-plugin-framework-compatible endpoint for tooling that wants the structured plan, not just the log.- Cleaner errors on unsupported endpoints —
go-tfecalls toprojectsendpoints now return a 422 with clear guidance instead of a misleading 404. Cloud-block init guidance surfaced too. - Documentation refresh — broad audit covering the API namespace split, dual-actor audit logging, dulwich → git-CLI partial-clone reality, webhook event list, per-phase auth Secrets, listener Secret-backed identity, and pool RBAC. Six refreshed + three new screenshots (labels browser, autodiscovery, configurations).
Deprecations
- Legacy
/api/v2/paths for Terrapod-native routes. All Terrapod-only endpoints (run triggers, registry management, audit, agent pools, roles, VCS connections, etc.) gained a canonical/api/terrapod/v1/...URL in this release. The previous/api/v2/...paths continue to work and now emitDeprecation: true/Link: <new-url>; rel="successor-version"/X-Removed-In: v0.24.0response headers. Update direct API consumers before upgrading to v0.24.0.
Security
- Container image scanning re-baselined:
CVE-2026-27135(nghttp2 HTTP/2 DoS) cleared on the runner image — Alpine 3.23.4 now shipsnghttp2-libs 1.68.1+. The Trivy ignore for it is gone. - Dependency bumps land Next.js 16.2.6, React 19.2.6, eslint-config-next 16.2.6, tailwind-merge 3.6.0, cryptography up to <49, mypy cap widened to <3, python-multipart to <0.0.29, plus
node:26-alpinefor the web image and a transitivebrace-expansionfix (GHSA-f886-m6hf-6m8v).
Status
Beta — apply_then_merge is opt-in per workspace; the default workflow (merge_then_apply) is unchanged.
Full Changelog: v0.22.1...v0.23.0