Skip to content

feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) [ship]#1390

Open
martzoukos wants to merge 5 commits into
mainfrom
martzoukos/ai-426-preserve-resources-flag
Open

feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) [ship]#1390
martzoukos wants to merge 5 commits into
mainfrom
martzoukos/ai-426-preserve-resources-flag

Conversation

@martzoukos

@martzoukos martzoukos commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

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 default deploy can't silently destroy run history.

Changes

  • New --preserve-resources boolean flag; forwarded as preserveResources to the deploy endpoint (rest/projects.ts).
  • Pre-deploy "This will:" summary advertises the flag.
  • Preflight destructive-delete guard: for an interactive, non-forced, non-preserve run, a dry-run surfaces resources that would be permanently deleted and requires explicit confirmation (skipped by --force).
  • Preview renders removed resources in a dedicated "Detached (kept in account, now UI-managed)" section, separate from the red "Delete:".
  • Explicit DETACHED diff action: the preview reads a DETACHED action 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.
  • Unit test for the query-param forwarding.

Backwards compatibility of the DETACHED action

  • Older backends that still return DELETE for preserved resources keep working: when --preserve-resources is set, DELETE items are folded into the detached bucket.
  • Older CLIs receiving DETACHED from a newer backend won't break — action is an unvalidated string matched by an if/else chain, so an unknown value is simply skipped (no crash). It would be silently omitted from the preview, so the backend should only emit DETACHED when the request opted in via preserveResources.

Behavioral notes

  • Every interactive, non-forced deploy now makes one extra dry-run round-trip; a destructive one prompts twice (generic intent, then the deletion gate).
  • Requires the backend preserveResources param (checkly/monorepo: https://github.com/checkly/monorepo/pull/2854). The DETACHED action is an additive, opt-in response value.

Testing

tsc build ✅, eslint ✅, vitest ✅.

🤖 Generated with Claude Code

martzoukos and others added 2 commits July 7, 2026 17:08
… (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>
@thebiglabasky thebiglabasky force-pushed the martzoukos/ai-426-preserve-resources-flag branch from c976852 to a7e42d0 Compare July 7, 2026 17:55

@thebiglabasky thebiglabasky left a comment

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.

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> = {

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.

Isn't this missing StatusPages?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, good catch. Status pages and Status page services.

Comment thread packages/cli/src/commands/deploy.ts Outdated
? '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'

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.

>management in the UI

management in the Checkly Webapp

Comment thread packages/cli/src/commands/deploy.ts Outdated
: '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',

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.

The em dash actually hurts readability because of the -- next to it. I'd use a "." or ";"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Oh damn, yeah that hurts.

Comment thread packages/cli/src/commands/deploy.ts
this.log(this.formatPreview(data, project, verbose, preserveResources))
}
if (!preview) {
await setTimeout(500)

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.

I know this is pre-existing but that looks quite fishy

Comment thread packages/cli/src/commands/deploy.ts Outdated
// 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) {

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.

I'd kill "backwards compatibility" which is nonsensical here: this is the CLI, so this version can count on the new backend endpoint.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

martzoukos and others added 2 commits July 8, 2026 12:03
…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.
@martzoukos martzoukos requested a review from thebiglabasky July 8, 2026 09:08
thebiglabasky
thebiglabasky previously approved these changes Jul 8, 2026
…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>
@martzoukos martzoukos changed the title feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) feat(cli): add deploy --preserve-resources + destructive-delete guard (AI-426) [ship] Jul 8, 2026

@github-actions github-actions 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.

Auto-approved: ship/show PR from a same-repo branch.

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