Skip to content

feat(cli): write Cloud service connection settings to .env (#1164) - #1167

Open
sdairs wants to merge 1 commit into
claude/1158-pin-subcommand-orderfrom
feat/1164-cloud-service-dotenv
Open

sdairs wants to merge 1 commit into
claude/1158-pin-subcommand-orderfrom
feat/1164-cloud-service-dotenv

Conversation

@sdairs

@sdairs sdairs commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Closes #1164.

What

  • cloud service dotenv [ID] [--name NAME] [--local] writes an existing service's connection settings to .env (or .env.local): CLICKHOUSE_HOST, CLICKHOUSE_PORT (native TLS), CLICKHOUSE_HTTP_PORT, CLICKHOUSE_USER=default, CLICKHOUSE_SECURE=true. It never writes a password, because the API only returns one at create/reset. It's a read command, so it works with OAuth.
  • cloud service create --dotenv [FILE] (.env when FILE is omitted) writes the same keys plus the one-time CLICKHOUSE_PASSWORD. Once the file is written, the password is left out of stdout in both human and JSON output, so it never reaches an agent's context or transcript. In JSON, password is removed and a dotenv: {file, keys} object is added.

Safety around the one-time password

  • The target is checked before the service is created (an existing regular file that is readable and writable, or a missing file in an existing directory). A bad path exits 2 and sends no request.
  • If the write still fails after creation, the command prints the normal create output, including the password, then exits 1 with a message that says so. The credential is never lost.
  • If the create response has no endpoints, the file gets what is known (user, secure, password) and stderr says to run cloud service dotenv <id> later. Existing keys not written by the command are kept, so a password written at create survives a later service dotenv.

Notes

  • Key meanings match local server dotenv (CLICKHOUSE_PORT is the native port). CLICKHOUSE_SECURE is new and Cloud-only, because Cloud endpoints require TLS. The mcp-clickhouse port difference stays with Design reusable connection profiles and MCP-compatible export #800.
  • The .env writer helpers moved from src/local/mod.rs to src/dotenv.rs (with their tests) and gained write_vars, which local server dotenv, local postgres dotenv and both new paths now share. Local behaviour is unchanged.
  • --local on service dotenv mirrors the local dotenv commands. create --dotenv takes a path instead, since the file is chosen at the moment the password exists.
  • Possible follow-up: the same --dotenv on cloud service reset-password, the other place a password is returned.

Tests

  • Clap parsing: the selector and --local default, read classification, bare/valued/=-form --dotenv, a following flag not taken as the file, not repeatable.
  • Unit: the variable builder (full, partial and absent endpoints), the pre-flight check, and write_vars creating or editing a file in place.
  • Wiremock subprocess: in-place .env edit that keeps an existing password, --local, the no-endpoints failure writing nothing, create --dotenv writing the password and keeping it off stdout/stderr (JSON and human), create without the flag unchanged, and a bad target rejected with no request sent.
  • Not covered: a write failing after the pre-flight check passes, which needs a race to reproduce.

Docs: Cloud service guide ("Write connection settings to .env") and the automation output table.

🤖 Generated with Claude Code


Note

Medium Risk
Renaming local server to clickhouse breaks existing scripts, and the new latest.txt publish path is on the critical path for every user update.

Overview
This PR bundles several user-facing and infrastructure changes beyond a single feature.

Release and self-update: The release workflow gains a Publish latest.txt job that writes clickhousectl/latest.txt to builds.clickhouse.com after uploads, only advancing to newer vX.Y.Z tags and verifying the CDN serves the value. Agent docs and release.yml comments now describe clickhousectl update and install.sh reading that file (with GitHub releases/latest as fallback).

Local CLI rename: User-facing examples and help switch from clickhousectl local server … to local clickhouse … (start/stop, init flows, issue templates, README). Help tests pin clickhouse in the local subcommand order.

Cloud module layout (#1157): cloud/organizations becomes a directory (cli.rs, client.rs, byoc.rs, members.rs, org, roles, mod.rs) with permissions and dispatch unchanged in spirit but split by command family. cloud/mod.rs drops the standalone service_query export (query code lives under services/). cloud/cli.rs reorders top-level cloud subcommands (e.g. Postgres after service, udf/key moved) and adds a test locking help order. Agent/skills docs describe the directory pattern for large domains and tighten convert_error_for_lookup guidance.

API library sync: OpenAPI refresh adds ClickStack log fields eventNameExpression / severityNumberExpression and ClickPipe MongoDB per-table mongoConfig (persistDeletedDocuments). Models, converters, and tests follow; clickhousectl cloud clickpipe --table-mapping-json accepts mongoConfig with validation tests.

Smaller fixes: Postgres container recovery refactors discovery into discover_project_postgres_blocking; local init test reflects that local server list no longer creates .clickhouse (#1077). .git-blame-ignore-revs adds commits from the services/postgres/organizations splits.

Reviewed by Cursor Bugbot for commit 8316f5b. Bugbot is set up for automated code reviews on this repo. Configure here.

@sdairs sdairs added enhancement New feature or request cloud Affects cloud CLI commands labels Oct 30, 2026
@sdairs
sdairs requested a review from iskakaushik as a code owner October 30, 2026 14:09

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit f481e89. Configure here.

format!("{}{}=\"{}\"", prefix, key, escaped)
} else {
format!("{}{}={}", prefix, key, val)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dotenv writer leaves $ unescaped

High Severity

format_dotenv_line does not treat $ as special, so create --dotenv writes CLICKHOUSE_PASSWORD in a form that dotenvy and other dotenv loaders expand. The write still succeeds and the password is omitted from command output, so the stored credential can be silently wrong.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit f481e89. Configure here.

Add `cloud service dotenv` to write an existing service's host, ports,
user and TLS setting to .env (or .env.local), without a password, and
`cloud service create --dotenv [FILE]` to write the same settings plus
the one-time password. With --dotenv, the password goes only to the file
and is left out of human and JSON output; the target is checked before
the service is created, and a write that still fails afterwards prints
the password as before and exits 1.

Move the .env writer helpers from local into the dotenv module, shared
by the local and Cloud dotenv paths.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sdairs
sdairs force-pushed the feat/1164-cloud-service-dotenv branch from f481e89 to 8316f5b Compare October 30, 2026 17:27
@sdairs
sdairs changed the base branch from main to claude/1158-pin-subcommand-order October 30, 2026 17:27
@sdairs
sdairs added this pull request to stack #1153 October 30, 2026 17:28

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cloud Affects cloud CLI commands enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Write Cloud service connection settings to .env

1 participant