From 5c6cb310d58189d9ca83e31117d10bb394cfdd62 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 23 Jul 2026 16:56:23 +0000 Subject: [PATCH 1/2] Prepare release 0.4.0-beta --- .../unreleased/BUG FIXES-20260630-131853.yaml | 3 -- .../unreleased/BUG FIXES-20260709-163223.yaml | 3 -- .../unreleased/BUG FIXES-20260710-135409.yaml | 3 -- .../unreleased/BUG FIXES-20260713-133903.yaml | 3 -- .../unreleased/BUG FIXES-20260713-133938.yaml | 3 -- .../unreleased/BUG FIXES-20260716-153934.yaml | 3 -- .../unreleased/BUG FIXES-20260717-154516.yaml | 3 -- .../ENHANCEMENTS-20260708-165846.yaml | 3 -- .../ENHANCEMENTS-20260714-163609.yaml | 3 -- .../ENHANCEMENTS-20260715-215302.yaml | 3 -- .../NEW FEATURES-20260630-162715.yaml | 3 -- .../unreleased/NOTES-20260714-120419.yaml | 3 -- .changes/v0.4.0-beta.md | 38 +++++++++++++++++++ CHANGELOG.md | 38 +++++++++++++++++++ version/VERSION | 2 +- 15 files changed, 77 insertions(+), 37 deletions(-) delete mode 100644 .changes/unreleased/BUG FIXES-20260630-131853.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260709-163223.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260710-135409.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260713-133903.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260713-133938.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260716-153934.yaml delete mode 100644 .changes/unreleased/BUG FIXES-20260717-154516.yaml delete mode 100644 .changes/unreleased/ENHANCEMENTS-20260708-165846.yaml delete mode 100644 .changes/unreleased/ENHANCEMENTS-20260714-163609.yaml delete mode 100644 .changes/unreleased/ENHANCEMENTS-20260715-215302.yaml delete mode 100644 .changes/unreleased/NEW FEATURES-20260630-162715.yaml delete mode 100644 .changes/unreleased/NOTES-20260714-120419.yaml create mode 100644 .changes/v0.4.0-beta.md diff --git a/.changes/unreleased/BUG FIXES-20260630-131853.yaml b/.changes/unreleased/BUG FIXES-20260630-131853.yaml deleted file mode 100644 index 77a8beb..0000000 --- a/.changes/unreleased/BUG FIXES-20260630-131853.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Don't attempt to retry telemetry transmission on server errors, like rate limiting 429 errors. -time: 2026-06-30T13:18:53.530515-06:00 diff --git a/.changes/unreleased/BUG FIXES-20260709-163223.yaml b/.changes/unreleased/BUG FIXES-20260709-163223.yaml deleted file mode 100644 index 1aa9709..0000000 --- a/.changes/unreleased/BUG FIXES-20260709-163223.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Detect Terraform's `TF_TOKEN_` environment variables (such as `TF_TOKEN_app_terraform_io`) during authentication, matching Terraform CLI's resolution. This includes punycode hostnames and the interchangeable dash encodings (literal `-` or double underscore). Previously these tokens were not detected. -time: 2026-07-09T16:32:23.267381-04:00 diff --git a/.changes/unreleased/BUG FIXES-20260710-135409.yaml b/.changes/unreleased/BUG FIXES-20260710-135409.yaml deleted file mode 100644 index d107053..0000000 --- a/.changes/unreleased/BUG FIXES-20260710-135409.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Clarify the not-found (404) API error message to point at verifying the request path and resource IDs instead of suggesting an authentication problem. -time: 2026-07-10T13:54:09.690093-04:00 diff --git a/.changes/unreleased/BUG FIXES-20260713-133903.yaml b/.changes/unreleased/BUG FIXES-20260713-133903.yaml deleted file mode 100644 index e7c1765..0000000 --- a/.changes/unreleased/BUG FIXES-20260713-133903.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Fix `api --all` returning no output when the result fits in a single page. The response body was consumed while checking for additional pages and not restored, so single-page responses rendered empty. -time: 2026-07-13T13:39:03-04:00 diff --git a/.changes/unreleased/BUG FIXES-20260713-133938.yaml b/.changes/unreleased/BUG FIXES-20260713-133938.yaml deleted file mode 100644 index 1a01b87..0000000 --- a/.changes/unreleased/BUG FIXES-20260713-133938.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Fix `api` `--json` and `--jq` output incorrectly including one-to-one relationship IDs under `attributes`. Those IDs are surfaced for table and pretty output only, and are no longer written back into the raw JSON payload. -time: 2026-07-13T13:39:38-04:00 diff --git a/.changes/unreleased/BUG FIXES-20260716-153934.yaml b/.changes/unreleased/BUG FIXES-20260716-153934.yaml deleted file mode 100644 index ea48f51..0000000 --- a/.changes/unreleased/BUG FIXES-20260716-153934.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Redacts customer data within HTTP paths in telemetry payloads, such as organization and workspace names. -time: 2026-07-16T15:39:34.248018-06:00 diff --git a/.changes/unreleased/BUG FIXES-20260717-154516.yaml b/.changes/unreleased/BUG FIXES-20260717-154516.yaml deleted file mode 100644 index cac19bf..0000000 --- a/.changes/unreleased/BUG FIXES-20260717-154516.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: BUG FIXES -body: Using the --quiet argument no longer suppresses api command rendering for GET requests. -time: 2026-07-17T15:45:16.235312-06:00 diff --git a/.changes/unreleased/ENHANCEMENTS-20260708-165846.yaml b/.changes/unreleased/ENHANCEMENTS-20260708-165846.yaml deleted file mode 100644 index a5eafc2..0000000 --- a/.changes/unreleased/ENHANCEMENTS-20260708-165846.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: ENHANCEMENTS -body: Adds a `--plan-only` flag to `run start` that creates a speculative plan-only run which is never applied, regardless of the workspace's auto-apply setting. -time: 2026-07-08T16:58:46-04:00 diff --git a/.changes/unreleased/ENHANCEMENTS-20260714-163609.yaml b/.changes/unreleased/ENHANCEMENTS-20260714-163609.yaml deleted file mode 100644 index 237592f..0000000 --- a/.changes/unreleased/ENHANCEMENTS-20260714-163609.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: ENHANCEMENTS -body: Positional arguments and API path parameters are now checked for basic input hygiene, rejecting control characters and invalid UTF-8. This keeps malformed values out of requests and out of terminal/audit output. This is not a security boundary; authorization is still enforced by your API token. -time: 2026-07-14T16:36:09.687002-04:00 diff --git a/.changes/unreleased/ENHANCEMENTS-20260715-215302.yaml b/.changes/unreleased/ENHANCEMENTS-20260715-215302.yaml deleted file mode 100644 index cf07d05..0000000 --- a/.changes/unreleased/ENHANCEMENTS-20260715-215302.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: ENHANCEMENTS -body: The config directory can now be overridden with the TFCTL_CONFIG_DIR environment variable. Profiles and exec sessions both resolve against this directory, making it easy to isolate tfctl state (for example, in CI or eval harnesses). -time: 2026-07-15T21:53:02.000000-04:00 diff --git a/.changes/unreleased/NEW FEATURES-20260630-162715.yaml b/.changes/unreleased/NEW FEATURES-20260630-162715.yaml deleted file mode 100644 index befa94a..0000000 --- a/.changes/unreleased/NEW FEATURES-20260630-162715.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: NEW FEATURES -body: Adds the `harness exec` command, which lets a human grant session-scoped, noninteractive `tfctl` delete permissions to a wrapped command (such as a coding agent) via `--allow-delete`. The grant is tied to the wrapped process, auto-reverts when it exits, and never covers the irreversible `organizations` and `projects` classes unless they are named explicitly. -time: 2026-06-30T16:27:15.272217-04:00 diff --git a/.changes/unreleased/NOTES-20260714-120419.yaml b/.changes/unreleased/NOTES-20260714-120419.yaml deleted file mode 100644 index 698db00..0000000 --- a/.changes/unreleased/NOTES-20260714-120419.yaml +++ /dev/null @@ -1,3 +0,0 @@ -kind: NOTES -body: For developers of tfctl, added CONTRIBUTING.md, developer setup automation, and `make help` -time: 2026-07-14T12:04:19.469961-06:00 diff --git a/.changes/v0.4.0-beta.md b/.changes/v0.4.0-beta.md new file mode 100644 index 0000000..24061af --- /dev/null +++ b/.changes/v0.4.0-beta.md @@ -0,0 +1,38 @@ +## v0.4.0-beta (July 23, 2026) + + +NEW FEATURES: + +* Adds the `harness exec` command, which lets a human grant session-scoped, noninteractive `tfctl` delete permissions to a wrapped command (such as a coding agent) via `--allow-delete`. The grant is tied to the wrapped process, auto-reverts when it exits, and never covers the irreversible `organizations` and `projects` classes unless they are named explicitly. + + +ENHANCEMENTS: + +* Adds a `--plan-only` flag to `run start` that creates a speculative plan-only run which is never applied, regardless of the workspace's auto-apply setting. + +* Positional arguments and API path parameters are now checked for basic input hygiene, rejecting control characters and invalid UTF-8. This keeps malformed values out of requests and out of terminal/audit output. This is not a security boundary; authorization is still enforced by your API token. + +* The config directory can now be overridden with the TFCTL_CONFIG_DIR environment variable. Profiles and exec sessions both resolve against this directory, making it easy to isolate tfctl state (for example, in CI or eval harnesses). + + +BUG FIXES: + +* Don't attempt to retry telemetry transmission on server errors, like rate limiting 429 errors. + +* Detect Terraform's `TF_TOKEN_` environment variables (such as `TF_TOKEN_app_terraform_io`) during authentication, matching Terraform CLI's resolution. This includes punycode hostnames and the interchangeable dash encodings (literal `-` or double underscore). Previously these tokens were not detected. + +* Clarify the not-found (404) API error message to point at verifying the request path and resource IDs instead of suggesting an authentication problem. + +* Fix `api --all` returning no output when the result fits in a single page. The response body was consumed while checking for additional pages and not restored, so single-page responses rendered empty. + +* Fix `api` `--json` and `--jq` output incorrectly including one-to-one relationship IDs under `attributes`. Those IDs are surfaced for table and pretty output only, and are no longer written back into the raw JSON payload. + +* Redacts customer data within HTTP paths in telemetry payloads, such as organization and workspace names. + +* Using the --quiet argument no longer suppresses api command rendering for GET requests. + + +NOTES: + +* For developers of tfctl, added CONTRIBUTING.md, developer setup automation, and `make help` + diff --git a/CHANGELOG.md b/CHANGELOG.md index ffdabf2..ac2b61b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ +## v0.4.0-beta (July 23, 2026) + + +NEW FEATURES: + +* Adds the `harness exec` command, which lets a human grant session-scoped, noninteractive `tfctl` delete permissions to a wrapped command (such as a coding agent) via `--allow-delete`. The grant is tied to the wrapped process, auto-reverts when it exits, and never covers the irreversible `organizations` and `projects` classes unless they are named explicitly. + + +ENHANCEMENTS: + +* Adds a `--plan-only` flag to `run start` that creates a speculative plan-only run which is never applied, regardless of the workspace's auto-apply setting. + +* Positional arguments and API path parameters are now checked for basic input hygiene, rejecting control characters and invalid UTF-8. This keeps malformed values out of requests and out of terminal/audit output. This is not a security boundary; authorization is still enforced by your API token. + +* The config directory can now be overridden with the TFCTL_CONFIG_DIR environment variable. Profiles and exec sessions both resolve against this directory, making it easy to isolate tfctl state (for example, in CI or eval harnesses). + + +BUG FIXES: + +* Don't attempt to retry telemetry transmission on server errors, like rate limiting 429 errors. + +* Detect Terraform's `TF_TOKEN_` environment variables (such as `TF_TOKEN_app_terraform_io`) during authentication, matching Terraform CLI's resolution. This includes punycode hostnames and the interchangeable dash encodings (literal `-` or double underscore). Previously these tokens were not detected. + +* Clarify the not-found (404) API error message to point at verifying the request path and resource IDs instead of suggesting an authentication problem. + +* Fix `api --all` returning no output when the result fits in a single page. The response body was consumed while checking for additional pages and not restored, so single-page responses rendered empty. + +* Fix `api` `--json` and `--jq` output incorrectly including one-to-one relationship IDs under `attributes`. Those IDs are surfaced for table and pretty output only, and are no longer written back into the raw JSON payload. + +* Redacts customer data within HTTP paths in telemetry payloads, such as organization and workspace names. + +* Using the --quiet argument no longer suppresses api command rendering for GET requests. + + +NOTES: + +* For developers of tfctl, added CONTRIBUTING.md, developer setup automation, and `make help` + ## v0.3.0 (June 22, 2026) diff --git a/version/VERSION b/version/VERSION index 9325c3c..578dca3 100644 --- a/version/VERSION +++ b/version/VERSION @@ -1 +1 @@ -0.3.0 \ No newline at end of file +0.4.0-beta From b168e6df13d4807f502c40d8a2b312d29981e7d9 Mon Sep 17 00:00:00 2001 From: Brandon Croft Date: Thu, 23 Jul 2026 11:31:09 -0600 Subject: [PATCH 2/2] fix: trim newlines from VERSION file --- version/version.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/version/version.go b/version/version.go index 5605120..0e2b953 100644 --- a/version/version.go +++ b/version/version.go @@ -42,7 +42,7 @@ var ( // IsDev returns true if the current version is a development version. func IsDev() bool { - return strings.HasSuffix(version, "-dev") + return strings.HasSuffix(Version, "-dev") } // Commit returns the git commit used for this specific version. @@ -68,7 +68,7 @@ func mustParseTime(ts string) time.Time { // version, we will ensure it is prefixed with a `v`. If not, we will leave the // version as is and return it. func publicVersion(v string) string { - sv, err := goversion.NewSemver(v) + sv, err := goversion.NewSemver(strings.TrimRight(v, "\r\n")) if err != nil { return v }