feat(hosting-cli): add reflex cloud gcp deploy for Cloud Run#6450
feat(hosting-cli): add reflex cloud gcp deploy for Cloud Run#6450
Conversation
Fetches a Dockerfile and bash deploy script from flexgen (`GET /api/v1/cli/gcp-cloud-run-manifest`), writes the Dockerfile into the user's source directory, prints the script, and runs it via bash after the user confirms. Pre-flights `bash`/`gcloud`/`docker` on PATH and an active gcloud account, and surfaces a clear message on 403 (Enterprise tier required). Deploy parameters (project, region, service name, AR repo, version) are passed via env vars to the script. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Merging this PR will not alter performance
Comparing Footnotes
|
Greptile SummaryAdds
Confidence Score: 5/5Safe to merge; the feature is new, well-tested, and all previously flagged concerns have been addressed. The implementation is self-contained (new command, no existing behaviour changed), the env-allowlist approach correctly prevents credential exfiltration, and the 12 new tests cover the key flows including non-interactive CI use, abort, dry-run, and overwrite handling. packages/reflex-hosting-cli/src/reflex_cli/v2/gcp.py — pre-flight ordering and abort exit code are minor UX suggestions only. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User invokes deploy --gcp] --> B{use_gcp set?}
B -- No --> Z1[Exit 2: specify a target]
B -- Yes --> C{gcp_project set?}
C -- No --> Z2[Exit 2: gcp-project required]
C -- Yes --> D[Check bash / gcloud / docker on PATH]
D -- Missing tool --> Z3[Exit 1: install tool]
D -- OK --> E[Check active gcloud account]
E -- Not logged in --> Z4[Exit 1: gcloud auth login]
E -- OK --> F[get_authenticated_client]
F --> G[Fetch manifest from flexgen]
G -- 403 --> Z5[Exit 1: Enterprise tier required]
G -- Error --> Z6[Exit 1: request failed]
G -- OK --> H[Print manifest for review]
H --> I{dry_run?}
I -- Yes --> Z7[Exit 0: nothing written]
I -- No --> J[Write Dockerfile]
J -- Failed/declined --> Z8[Exit 1]
J -- OK --> K{interactive?}
K -- Yes --> L[Prompt: Run script now?]
L -- No --> Z9[Exit 0: aborted by user]
L -- Yes --> M[Run bash script with allowlisted env]
K -- No --> M
M --> N{exit code 0?}
N -- Yes --> Z10[Success]
N -- No --> Z11[Exit with script code]
Reviews (2): Last reviewed commit: "refactor(hosting-cli): rename gcp deploy..." | Re-trigger Greptile |
| GCP_MANIFEST_ENDPOINT = "/api/v1/cli/gcp-cloud-run-manifest" | ||
|
|
||
| DOCKERFILE_NAME = "Dockerfile" |
There was a problem hiding this comment.
Hardcoded env-var and response-field key strings
Per the project rule, string literals used as identifiers or dictionary keys should be extracted into named constants. The five GCP environment variable keys and the two response field names ("dockerfile", "deploy_command") appear inline in multiple places, making typos hard to catch and refactoring error-prone. Extracting them to module-level constants (as is already done for GCP_MANIFEST_ENDPOINT and DOCKERFILE_NAME) keeps the file consistent.
| GCP_MANIFEST_ENDPOINT = "/api/v1/cli/gcp-cloud-run-manifest" | |
| DOCKERFILE_NAME = "Dockerfile" | |
| GCP_MANIFEST_ENDPOINT = "/api/v1/cli/gcp-cloud-run-manifest" | |
| DOCKERFILE_NAME = "Dockerfile" | |
| # Environment variable keys passed to the deploy script | |
| _ENV_GCP_PROJECT = "GCP_PROJECT" | |
| _ENV_GCP_REGION = "GCP_REGION" | |
| _ENV_SERVICE_NAME = "SERVICE_NAME" | |
| _ENV_AR_REPO = "AR_REPO" | |
| _ENV_VERSION = "VERSION" | |
| # Flexgen manifest response field names | |
| _FIELD_DOCKERFILE = "dockerfile" | |
| _FIELD_DEPLOY_COMMAND = "deploy_command" |
Rule Used: String literals that are used as identifiers or ke... (source)
Learned From
reflex-dev/flexgen#2170
…act constants Address PR feedback: - Restrict the deploy script's environment to an allowlist of host vars (PATH, HOME, gcloud/docker config, proxy/TLS) plus the explicit deploy overrides. Prevents a tampered or compromised flexgen manifest from exfiltrating unrelated host secrets like AWS_*/GITHUB_TOKEN. - Add --interactive/--no-interactive (default true) so the command works in CI. In non-interactive mode the run prompt is skipped, and an existing Dockerfile errors out unless --overwrite-dockerfile is set. - Extract env-var keys and manifest field names into module-level constants per project convention. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…p`, add docs Flatten the `gcp` group into a single `deploy` command with a `--gcp` target flag so the surface can grow to other targets without nesting. `--gcp-project` becomes optional at the Click level and is validated in-function so the missing-target error fires first. Add a hosting doc (with Enterprise-only callout) covering prerequisites, options, what gets created in the GCP project, the env-allowlist security model, CI usage, and troubleshooting. Wire it into the sidebar's Self Hosting section and add `Gcp` -> `GCP` to the sidebar acronym map. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ENG-9469
Summary
reflex cloud gcp deploycommand that fetches a Dockerfile + bash deploy script from flexgen (GET /api/v1/cli/gcp-cloud-run-manifest), writes the Dockerfile into the user's source directory, prints the script, and runs it via bash after a single y/n confirmation.bash/gcloud/dockeron PATH and an active gcloud account, with actionable error messages. Surfaces a clear "Enterprise tier required" message on a 403 from flexgen.--gcp-projectrequired;--region,--service-name,--ar-repo,--version) are passed to the script viaGCP_PROJECT,GCP_REGION,SERVICE_NAME,AR_REPO,VERSIONenvironment variables.--dry-runprints the manifest without writing or executing;--overwrite-dockerfileskips the existing-Dockerfile prompt.Auth model
X-API-Tokenflow (hosting.get_authenticated_client).gcloudlogin (detected viagcloud auth list --filter=status:ACTIVE).Test plan
uv run pytest tests/units/reflex_cli— 152 tests pass (12 new intests/units/reflex_cli/v2/test_gcp.py).uv run ruff check,uv run ruff format,uv run pyrightclean on changed files.uv run pre-commit run --files <changed>passes (ruff-format, ruff-check, codespell, update-pyi-files, pyright).🤖 Generated with Claude Code