Rework cloud-connect-dev recipe onto the spice cloud enrollment flow - #597
Merged
phillipleblanc merged 6 commits intoAug 21, 2026
Merged
Conversation
…e published pages Both Cloud Connect links 404: /docs/deployment/cloud/cloud-connect and /docs/deployment/cloud/cloud-connect/service are unreleased pages, published under /docs/next/ until v2.2 ships. The `spice connect` CLI reference resolves at the released path, but that page documents the superseded command (no `spice connect service install`, no `spiced --token`), so it points at /docs/next/ too — the flow this recipe and its validate.sh assert. Also align the docker-compose.yml comment with the README's PG_PASSWORD, since the README states that secret names are matched exactly.
`spice connect` no longer enrolls a runtime with Spice Cloud. It retains only the deprecated `<org>/<pod>` Spicepod-add form and rejects every lifecycle spelling. This recipe walked the reader through `spice connect`, `spice connect status`, and `spice connect remove`, all of which now exit non-zero. Rewrite it on the shipped surface — `spice cloud login`, `spice cloud link <org>/<project>`, `spice cloud status`, `spice cloud unlink`, and `spice cloud service` — verified against the CLI binary and bin/spice/src/commands/cloud rather than against release notes: - `spice cloud link` enrolls the directory and attaches it in one step, needs a terminal, and does not start the runtime; its own output tells you to run `spice run`. - A project holding no Spicepod is seeded from the local one, so the manual "paste spicepod.yaml into the portal" step is no longer needed. - `spice cloud unlink` releases the instance but never deletes the project. Clean-up names `spice cloud project delete` separately, and says to stop the runtime first, because unlink takes the runtime lock and refuses otherwise. - `spice cloud status` reports project health and appends the local view under a `Local enrolled-instance state:` header, which the expected output gains. The project is created in the portal: `spice cloud project create` still requires `--region` on trunk, so it cannot yet create the unattached Cloud Connect project this flow needs (spiceai/spiceai#13333). validate.sh is rewritten over the same surface. Its contract is to run with no account, no login, and no control-plane access, and the `spice connect status` assertions met it because that command only read local state. `spice cloud status` calls the control plane, so those checks cannot be ported. In their place: `--help` assertions over the lifecycle and service commands, a README/CLI drift guard that fails if the recipe reintroduces a removed spelling, and the non-interactive refusal path, which still fails closed and still names `spiced --token`. Dropped: the assertion that an enrollment key is refused as a positional argument. `spice cloud link` fails its terminal check before argument handling, so that property is no longer reachable from this recipe's surface. The doc-link repairs from the base commit are kept. The `spice connect` CLI reference link is removed rather than repointed, because the `spice cloud` reference page is not published yet; it can be added once it is. Every remaining link was re-checked and returns HTTP 200. ./validate.sh before this change: 18 passed, 12 failed, TEST FAILED. ./validate.sh after: 33 passed, 0 failed, TEST PASSED.
The CLI's own failure hint for an unauthenticated link reads "Run `spice login`, then retry `spice cloud link`". A reader who gets stuck reads the error before they re-read the recipe, so the recipe uses the same spelling. Also say that `spice cloud status` reads from Spice Cloud and needs that session: it reports project health from the control plane, so unlike the purely local checks in validate.sh it does not work signed out.
`spice cloud project create <name>` with no `--kind` creates the unattached Cloud Connect project that `spice cloud link` attaches to, so the recipe no longer sends the reader to the portal to make one. Setup is CLI end to end: `spice login`, `spice cloud project create`, `spice cloud link`, `spice run`. `--kind` is the discriminator. Naming one asks for a Spice-managed project and requires `--region`; omitting it asks for a Cloud Connect project, which has no region to choose. `--region` and the hosted-runtime flags are refused rather than ignored when no kind is given, so the README says so. validate.sh asserts that distinction. `execute_project_create` resolves placement before it connects, so both refusals are argument validation: they answer with no account and create nothing. The exit code is asserted alongside the message, so a future ordering change that created the project before validating it would fail the check rather than pass silently. `spice cloud link` still requires a terminal and a user login. Creating the project from the CLI does not change that. ./validate.sh: 37 passed, 0 failed, TEST PASSED (was 33 passed, 0 failed).
`spice cloud secrets set PG_PASSWORD "$SPICE_DEMO_PG_PASSWORD"` replaces the portal walkthrough, and `spice cloud secrets list` confirms it. Linking resolves the project, so neither needs `--project`. The value is a required positional argument. There is no stdin, file, or environment form: `SecretsSetArgs.value` is a bare `String` with no clap attribute, and the only stdin read in the module is the project-delete prompt. So the recipe passes the shell variable, which keeps the password out of shell history — history records the line as typed — but the expanded value is still in the process argument list while the command runs, and the README says so and points at the portal for a shared machine. `spice cloud secrets get` prints the value to stdout, so the confirmation step uses `list`, which reports names and timestamps only. validate.sh asserts the four subcommands exist and that the README passes the password by variable and never calls `secrets get`. Nothing sets, reads, or deletes a real secret: these commands reach the control plane, and a validator that mutates a cloud project when a developer happens to be logged in is worse than the coverage it would buy. The compose comment tracks the credential to the project rather than to the portal, which is where it now goes. ./validate.sh: 43 passed, 0 failed, TEST PASSED (was 37 passed, 0 failed). README URLs re-checked: 4/4 HTTP 200.
The checks that only read README.md need no CLI, but sat below the version gate with the ones that do. CI installs the stable CLI, so the gate skips everything under it and those checks never ran there — including the guard that fails if the recipe spells the database password literally instead of passing \$SPICE_DEMO_PG_PASSWORD. That is the one check that most needs to run on every pull request. Group them into a README section above the gate. The CLI sections keep only what actually needs a CLI: the --help listings, the project-kind refusals, and the non-interactive link refusal. No assertion is added or removed. Locally, where the gate passes, the suite is unchanged at 43 passed, 0 failed. On a CI image whose CLI predates the flow, the checks that run before the gate go from 16 to 23.
phillipleblanc
approved these changes
Aug 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
spice connectis no longer how a runtime is connected to Spice Cloud. It retains only the deprecated<org>/<pod>Spicepod-add form and rejects every lifecycle spelling:The
cloud-connect-devrecipe taughtspice connect,spice connect status, andspice connect remove— so every cloud-facing command in it exits non-zero today. Repairing its doc links (the original scope of this PR) would have left a recipe that walks the reader down a path the CLI no longer has, so the recipe body is reworked onto the current surface. The link repairs are kept.What changed
README.mdnow usesspice login→spice cloud project create→spice cloud link <org>/<project>→spice run, withspice cloud secrets,spice cloud status,spice cloud unlink, andspice cloud servicefor the rest. The portal is used only where it is genuinely the tool: editing the project Spicepod. Behaviours documented because the CLI actually does them:spice cloud linkenrols the directory and attaches it in one step, requires a terminal, and does not start the runtime — its own output tells you to runspice run.spicepod.yamlinto the portal" step is gone.spice cloud unlinkreleases the instance but never deletes the project. Clean-up namesspice cloud project deleteseparately, and says to stop the runtime first, because unlink takes the runtime lock and refuses while it is held.spice cloud statusreports project health and appends the local view under aLocal enrolled-instance state:header, which the expected-output block gains. It reads from the control plane, so unlike the old command it does not work signed out — the README says so.Breaking for anyone parsing
--output json: the status JSON movesconnection,service, anddeploymentunder alinkobject;schema_versionstays at the top level. That is a runtime change, not one this PR makes, but it is not discoverable from this diff and it silently breaks existing parsers.The project is created with
spice cloud project create cloud-connect-dev.--kindis the discriminator: naming one asks for a Spice-managed project and requires--region, while omitting it asks for a Cloud Connect project, which has no region to choose.--regionand the hosted-runtime flags are refused rather than ignored when no kind is given, so the README says so.validate.shasserts that distinction, and can do it headlessly:execute_project_createresolves placement before it connects, so both refusals are argument validation that answer with no account and create nothing. The exit code is asserted alongside the message, so a future ordering change that created the project before validating it would fail the check rather than pass silently.Secrets, and a hazard worth naming
The secrets step is
spice cloud secrets set PG_PASSWORD "$SPICE_DEMO_PG_PASSWORD", confirmed withspice cloud secrets list. Linking resolves the project, so neither needs--project.The value is a required positional argument, and there is no stdin, file, or environment form —
SecretsSetArgs.valueis a bareStringwith no clap attribute, and the only stdin read in the module is the project-delete confirmation prompt. So the recipe passes the shell variable: history records the line as typed, which keeps the password out of it, but the expanded value is still in the process argument list while the command runs. The README states that plainly and points at the portal for a shared machine, rather than implying the CLI form is unconditionally safer.spice cloud secrets getprints the value to stdout, so the confirmation step useslist, which reports names and timestamps only.validate.shfails if the README ever reaches forget, or if it spells the password literally instead of passing the variable.validate.sh
Its stated contract is to run with no account, no login, and no control-plane access. The old
spice connect statusassertions met that because the command only read local state.spice cloud statuscalls the control plane — offline it exits 1 withNo app specified— so those checks cannot be ported. Replacing them:--helpassertions that the four lifecycle commands and all fiveservicesubcommands existspice connectspellingspiced --tokenNothing in the suite sets, reads, or deletes a real secret, for the same reason a bare
project createis not asserted: those commands reach the control plane, and a validator that mutates someone's cloud project when a developer happens to be logged in is a worse defect than the coverage it would buy.Dropped: the assertion that an enrollment key is refused as a positional argument.
spice cloud linkfails its terminal check before argument handling, so that property is no longer reachable from this recipe's surface. The scan that fails the build if a key-shaped value appears in a recipe file is unchanged.Verified against
spice cloud --helpand thelink/unlink/status/service/project createsubcommand helps.bin/spice/src/commands/cloud/mod.rs(execute_linkoutput,execute_unlinkruntime lock,execute_statuslocal-state header and JSON shape) andbin/spice/src/commands/connect/status.rs(secrets: {n} delivered: {names}).curl -sL -o /dev/null -w '%{http_code}'— 4/4 return 200./docs/next/is the correct prefix today because the released paths still 404: Cloud Connect is new in v2.2 and noversion-2.2.xsnapshot has been cut yet. When v2.2 is published these pages are snapshotted and also resolve at/docs/deployment/cloud/cloud-connect, which is then the better link for a recipe whose readers run the stable CLI —/docs/next/tracks trunk and drifts from it. Worth revisiting at that point.spice connectCLI reference link is removed rather than repointed — thespice cloudreference page is not published yet (/docs/cli/reference/cloudand/docs/next/cli/reference/cloudboth 404). It can be added in a follow-up once that page exists.Evidence
./cloud-connect-dev/validate.sh, run locally against a v2.2 CLI:All 12 prior failures were the
spice connectassertions.Note on CI:
validate-cloud-connect-devinstalls the stable CLI, which still predates v2.2, so the workflow takes the version gate and reports the "not validated" notice — a green check there is not evidence for the CLI-dependent assertions, which were exercised locally against v2.2 and start running in CI when v2.2 ships.The checks that only read
README.mdneed no CLI, so they now sit above the gate and do run in CI: 23 checks, up from 16, including the guard that fails if the recipe ever spells the database password literally instead of passing$SPICE_DEMO_PG_PASSWORD. That is the check that most needs to run on every pull request, and it previously never did.Sweep
The rest of the cookbook was checked for
spice connect. Five other files match only in ordinary prose — "the replication user Spice connects with", "Spice connects to Unity Catalog", "the Spice connector accepts the dot form" — and no file anywhere uses the still-supported deprecatedspice connect <org>/<pod>pod-add form. No other recipe needs a change.