Skip to content

feat(hosting-cli): add reflex cloud gcp deploy for Cloud Run#6450

Open
Kastier1 wants to merge 3 commits intomainfrom
cloudrun-deploy-cli
Open

feat(hosting-cli): add reflex cloud gcp deploy for Cloud Run#6450
Kastier1 wants to merge 3 commits intomainfrom
cloudrun-deploy-cli

Conversation

@Kastier1
Copy link
Copy Markdown
Contributor

@Kastier1 Kastier1 commented May 4, 2026

ENG-9469

Summary

  • New reflex cloud gcp deploy command 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.
  • Pre-flights bash/gcloud/docker on PATH and an active gcloud account, with actionable error messages. Surfaces a clear "Enterprise tier required" message on a 403 from flexgen.
  • Deploy parameters (--gcp-project required; --region, --service-name, --ar-repo, --version) are passed to the script via GCP_PROJECT, GCP_REGION, SERVICE_NAME, AR_REPO, VERSION environment variables. --dry-run prints the manifest without writing or executing; --overwrite-dockerfile skips the existing-Dockerfile prompt.

Auth model

  • Reflex hosting auth uses the existing X-API-Token flow (hosting.get_authenticated_client).
  • GCP credentials never leave the user's machine — the CLI relies on the user's existing gcloud login (detected via gcloud auth list --filter=status:ACTIVE).

Test plan

  • uv run pytest tests/units/reflex_cli — 152 tests pass (12 new in tests/units/reflex_cli/v2/test_gcp.py).
  • uv run ruff check, uv run ruff format, uv run pyright clean on changed files.
  • uv run pre-commit run --files <changed> passes (ruff-format, ruff-check, codespell, update-pyi-files, pyright).
  • End-to-end run against a real flexgen + GCP project (requires Enterprise-tier account).

🤖 Generated with Claude Code

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>
@Kastier1 Kastier1 requested a review from a team as a code owner May 4, 2026 20:21
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 4, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks
⏩ 2 skipped benchmarks1


Comparing cloudrun-deploy-cli (16a39ee) with main (1eed933)

Open in CodSpeed

Footnotes

  1. 2 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 4, 2026

Greptile Summary

Adds reflex cloud deploy --gcp for deploying Reflex apps to GCP Cloud Run: it fetches a server-side Dockerfile and bash deploy script, writes the Dockerfile locally, and runs the script under a restricted environment allowlist. Previous review concerns (full-env passthrough, no non-interactive mode, inline string keys) have all been addressed.

  • gcp.py — new 470-line module with deploy_command, helper functions, a DEPLOY_ENV_ALLOWLIST frozenset that keeps AWS/GitHub/SSH credentials out of the subprocess env, and constants for all response-field names and env var keys.
  • deployments.py — one-line registration of the new command as deploy under hosting_cli; no pre-existing deploy command is displaced.
  • Docs + sidebar — new deploy-to-gcp.md covering prereqs, all options, security model, CI usage, and troubleshooting; sidebar acronym map extended with Gcp → GCP.

Confidence Score: 5/5

Safe 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

Filename Overview
packages/reflex-hosting-cli/src/reflex_cli/v2/gcp.py New GCP Cloud Run deploy command with env allowlist, dry-run, interactive/non-interactive modes, and proper error handling; pre-flight tool checks occur after the auth network call (minor UX ordering issue).
packages/reflex-hosting-cli/src/reflex_cli/v2/deployments.py Registers the new gcp_deploy_command as 'deploy' under hosting_cli; no pre-existing 'deploy' command is overwritten.
tests/units/reflex_cli/v2/test_gcp.py 12 new tests covering happy path, abort, dry-run, overwrite flow, non-interactive CI mode, tool pre-flight failures, and env-allowlist enforcement.
docs/hosting/deploy-to-gcp.md New documentation page covering prerequisites, quick start, all CLI options, security model, CI usage, and troubleshooting.

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]
Loading

Reviews (2): Last reviewed commit: "refactor(hosting-cli): rename gcp deploy..." | Re-trigger Greptile

Comment thread packages/reflex-hosting-cli/src/reflex_cli/v2/gcp.py Outdated
Comment thread packages/reflex-hosting-cli/src/reflex_cli/v2/gcp.py Outdated
Comment on lines +25 to +27
GCP_MANIFEST_ENDPOINT = "/api/v1/cli/gcp-cloud-run-manifest"

DOCKERFILE_NAME = "Dockerfile"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 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.

Suggested change
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

Kastier1 and others added 2 commits May 7, 2026 10:30
…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>
@Kastier1 Kastier1 requested a review from Alek99 as a code owner May 8, 2026 01:01
@Kastier1
Copy link
Copy Markdown
Contributor Author

Kastier1 commented May 8, 2026

@greptileai

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants