feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) [ship]#1390
feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) [ship]#1390martzoukos wants to merge 5 commits into
Conversation
… (AI-426) `checkly deploy --preserve-resources` detaches resources removed from code (kept in the account, returned to UI management) instead of deleting them, forwarding preserveResources to the deploy endpoint and rendering the removed resources as "Detached" in the preview. Default deploy now guards against silent data loss: for an interactive, non-forced run a preflight dry-run surfaces any resources that would be permanently deleted and requires an explicit confirmation (skipped by --force). The pre-deploy summary also advertises --preserve-resources. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The deploy preview now reads an explicit DETACHED action from the diff instead of inferring detachment solely from the client-side --preserve-resources flag. Detached resources render in their own "Detached (kept in account, now UI-managed)" section, separate from "Delete:". Backwards compatible both ways: older backends that still return DELETE for preserved resources are folded into the detached bucket when --preserve-resources is set, and older CLIs simply ignore the unknown DETACHED action (no crash, since the action field is an unvalidated string matched by an if/else chain). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
c976852 to
a7e42d0
Compare
thebiglabasky
left a comment
There was a problem hiding this comment.
My bad for the commit that's reverted, I used Linear and asked a question to the agent which just went ahead and changed stuff.
This is a human review, I think there are legit questions I'd consider before approving. I'll have a bot review done separately to consider my remarks too
| DETACHED = 'DETACHED', | ||
| } | ||
|
|
||
| const PRETTY_RESOURCE_TYPES: Record<string, string> = { |
There was a problem hiding this comment.
Isn't this missing StatusPages?
There was a problem hiding this comment.
Yes, good catch. Status pages and Status page services.
| ? 'Schedule checks after deploy' | ||
| : 'Checks will NOT be scheduled after deploy', | ||
| preserveResources | ||
| ? 'Detach any resources removed from code, keeping them and their run history for management in the UI' |
There was a problem hiding this comment.
>management in the UImanagement in the Checkly Webapp
| : 'Checks will NOT be scheduled after deploy', | ||
| preserveResources | ||
| ? 'Detach any resources removed from code, keeping them and their run history for management in the UI' | ||
| : 'Delete any resources removed from code, losing their run history — pass --preserve-resources to detach and keep them instead', |
There was a problem hiding this comment.
The em dash actually hurts readability because of the -- next to it. I'd use a "." or ";"
There was a problem hiding this comment.
Oh damn, yeah that hurts.
| this.log(this.formatPreview(data, project, verbose, preserveResources)) | ||
| } | ||
| if (!preview) { | ||
| await setTimeout(500) |
There was a problem hiding this comment.
I know this is pre-existing but that looks quite fishy
| // Backwards compatibility: older backends don't emit DETACHED and instead | ||
| // return DELETE for resources removed from code even when preserveResources | ||
| // is set. When we asked to preserve, treat those deletions as detachments. | ||
| if (preserveResources) { |
There was a problem hiding this comment.
I'd kill "backwards compatibility" which is nonsensical here: this is the CLI, so this version can count on the new backend endpoint.
There was a problem hiding this comment.
Ah, the agent got overjealous here and applied backwards compat both in the backend and this code.
As we'll deploy the backend first, we indeed don't need this block – I'll remove it.
…I-426) - Add StatusPage and StatusPageService to PRETTY_RESOURCE_TYPES so they render with friendly names in delete/detach previews and guards. - Reword user-facing "UI" references to "Checkly Webapp". - Replace the em dash before --preserve-resources with a period for readability. - Remove the transitional DELETE-to-detach display fallback in formatPreview (and its now-unused preserveResources param); the backend ships before the CLI and always emits DETACHED. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolved conflicts in: - packages/cli/src/commands/deploy.ts: kept main's async deploy progress UI (actionStart/Status/Success, cancelInProgress, onProgress/onStatus) and added the preserveResources option to the deploy call. - packages/cli/src/rest/projects.ts: took main's event-stream deploy rewrite and threaded preserveResources through deploy()/submitDeployment() into the /v1/projects/deploy query, mirroring the delete path. Updated the deploy-URL test assertion and added coverage for preserveResources=true.
…426) The /v1/projects/deploy endpoint rejects unknown query params, and the deploy-side backend support for preserveResources is not deployed yet, so sending preserveResources=false on every deploy made all deploys fail with `"preserveResources" is not allowed` (all e2e deploy tests red). preserveResources=false is identical to the backend's default (delete resources removed from code), so omit the param unless the user opted in with --preserve-resources. Default deploys are now byte-for-byte identical to before the feature; the param only rides along when explicitly requested (which requires the deploy-side backend support to ship first). Also fix the merged projects-deploy unit test to drive the async event-stream deploy, and update assertions to the conditional param. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What & why
AI-426 (CLI half). Adds
checkly deploy --preserve-resources: resources removed from code are detached (kept in the account, returned to UI management) instead of deleted. Also adds a guardrail so a defaultdeploycan't silently destroy run history.Changes
--preserve-resourcesboolean flag; forwarded aspreserveResourcesto the deploy endpoint (rest/projects.ts).--force).DETACHEDdiff action: the preview reads aDETACHEDaction from the deploy diff and buckets those resources as detached, rather than inferring detachment purely from the client-side flag. The CLI is now the source of truth for the label based on what the backend actually did.Backwards compatibility of the
DETACHEDactionDELETEfor preserved resources keep working: when--preserve-resourcesis set,DELETEitems are folded into the detached bucket.DETACHEDfrom a newer backend won't break —actionis an unvalidatedstringmatched by anif/elsechain, so an unknown value is simply skipped (no crash). It would be silently omitted from the preview, so the backend should only emitDETACHEDwhen the request opted in viapreserveResources.Behavioral notes
preserveResourcesparam (checkly/monorepo: https://github.com/checkly/monorepo/pull/2854). TheDETACHEDaction is an additive, opt-in response value.Testing
tscbuild ✅, eslint ✅, vitest ✅.🤖 Generated with Claude Code