Skip to content

feat(service): add delete command#169

Open
canyugs wants to merge 3 commits intomainfrom
can/zea-8536-cli-add-service-delete-command
Open

feat(service): add delete command#169
canyugs wants to merge 3 commits intomainfrom
can/zea-8536-cli-add-service-delete-command

Conversation

@canyugs
Copy link
Contributor

@canyugs canyugs commented Feb 13, 2026

Summary

  • Add zeabur service delete command to delete a service from an environment
  • Add DeleteService GraphQL mutation to the API client
  • Require --yes flag in non-interactive mode to prevent accidental deletions

Test plan

  • Run zeabur service delete in interactive mode — should prompt for service selection and confirmation
  • Run zeabur service delete --id <id> --env-id <env> without --yes — should refuse and prompt to use --yes
  • Run zeabur service delete --id <id> --env-id <env> --yes — should delete successfully

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added service deletion capability via new CLI command
    • Supports both interactive and non-interactive deletion modes with optional confirmation prompts
    • Allows service identification by ID or name within specified environments

canyugs and others added 3 commits January 23, 2026 13:19
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevent accidental service deletion in non-interactive mode (e.g. CI/CD)
by requiring explicit --yes confirmation, consistent with project delete.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 13, 2026 16:56
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai
Copy link

coderabbitai bot commented Feb 13, 2026

Walkthrough

The pull request introduces a new service deletion feature by adding a delete command handler, registering it with the service command group, and implementing the underlying API interface and client method to support deleting services by ID within a specified environment.

Changes

Cohort / File(s) Summary
Delete Command Implementation
internal/cmd/service/delete/delete.go
Implements NewCmdDelete factory function and Options struct to handle service deletion with parameter validation, interactive/non-interactive modes, confirmation prompts, and error handling via the API client.
Command Registration
internal/cmd/service/service.go
Registers the new delete subcommand by importing and adding the delete command to the service command group.
API Interface & Implementation
pkg/api/interface.go, pkg/api/service.go
Defines DeleteService interface method and implements it as a GraphQL mutation that deletes a service by ID within a specified environment.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (43 files):

⚔️ .github/workflows/build-test.yml (content)
⚔️ .github/workflows/codeql.yaml (content)
⚔️ .github/workflows/lint.yml (content)
⚔️ .github/workflows/release.yml (content)
⚔️ .gitignore (content)
⚔️ docs/development_guide.md (content)
⚔️ go.mod (content)
⚔️ go.sum (content)
⚔️ internal/cmd/auth/auth.go (content)
⚔️ internal/cmd/auth/logout/logout.go (content)
⚔️ internal/cmd/context/clear/clear.go (content)
⚔️ internal/cmd/context/get/get.go (content)
⚔️ internal/cmd/deployment/list/list.go (content)
⚔️ internal/cmd/project/get/get.go (content)
⚔️ internal/cmd/project/list/list.go (content)
⚔️ internal/cmd/service/list/list.go (content)
⚔️ internal/cmd/service/service.go (content)
⚔️ internal/cmd/template/delete/delete.go (content)
⚔️ internal/cmd/template/deploy/deploy.go (content)
⚔️ internal/cmd/template/get/get.go (content)
⚔️ internal/cmd/template/list/list.go (content)
⚔️ internal/cmd/upload/upload.go (content)
⚔️ internal/cmdutil/constants.go (content)
⚔️ internal/util/pack.go (content)
⚔️ internal/util/project.go (content)
⚔️ internal/util/runE.go (content)
⚔️ internal/util/service.go (content)
⚔️ pkg/api/domain.go (content)
⚔️ pkg/api/environment.go (content)
⚔️ pkg/api/git.go (content)
⚔️ pkg/api/interface.go (content)
⚔️ pkg/api/log.go (content)
⚔️ pkg/api/project.go (content)
⚔️ pkg/api/service.go (content)
⚔️ pkg/api/variable.go (content)
⚔️ pkg/config/init.go (content)
⚔️ pkg/fill/fill.go (content)
⚔️ pkg/model/deployment.go (content)
⚔️ pkg/model/domain.go (content)
⚔️ pkg/model/project.go (content)
⚔️ pkg/model/user.go (content)
⚔️ pkg/printer/printer.go (content)
⚔️ pkg/prompt/prompter.go (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(service): add delete command' directly and concisely describes the main change: adding a delete command to the service functionality.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch can/zea-8536-cli-add-service-delete-command
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch can/zea-8536-cli-add-service-delete-command
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a new zeabur service delete CLI command and wires it into the existing service command group, backed by a new DeleteService GraphQL mutation on the API client. It also introduces a --yes guard in non-interactive mode to reduce the chance of accidental deletions.

Changes:

  • Add DeleteService to the API client and public API interface.
  • Register a new zeabur service delete subcommand under zeabur service.
  • Implement interactive selection + confirmation flow, and require --yes in non-interactive mode.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
pkg/api/service.go Adds DeleteService GraphQL mutation call.
pkg/api/interface.go Exposes DeleteService on the API interface.
internal/cmd/service/service.go Registers the new service delete command.
internal/cmd/service/delete/delete.go Implements the delete command behavior (interactive + non-interactive).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

}
} else if !f.Interactive && !opts.skipConfirm {
f.Log.Info("Please use --yes to confirm deletion without interactive prompt")
return nil
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

In non-interactive mode, missing --yes currently logs an info message and returns nil, which exits with status 0. For scripting/CI safety, consider returning a non-nil error here so callers can reliably detect that the delete was refused (while still printing the guidance to use --yes).

Suggested change
return nil
return fmt.Errorf("deletion not confirmed: rerun with --yes to confirm deletion in non-interactive mode")

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping return nil to stay consistent with the existing project delete command, which uses the same pattern. Changing the exit behavior for just this command would introduce inconsistency.

if err != nil {
return err
}
if !confirm {
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

When the user declines the confirmation prompt, the command returns without any message. Consider logging a clear cancellation message (consistent with other delete commands) so users understand no action was taken.

Suggested change
if !confirm {
if !confirm {
f.Log.Info("Service deletion cancelled")

Copilot uses AI. Check for mistakes.

// double check
if f.Interactive && !opts.skipConfirm {
confirm, err := f.Prompter.Confirm(fmt.Sprintf("Are you sure to delete service <%s>?", idOrName), false)
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

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

The confirmation prompt text is a bit awkward ("Are you sure to delete..."). Consider rephrasing to something like "Are you sure you want to delete service <...>?" for clarity.

Suggested change
confirm, err := f.Prompter.Confirm(fmt.Sprintf("Are you sure to delete service <%s>?", idOrName), false)
confirm, err := f.Prompter.Confirm(fmt.Sprintf("Are you sure you want to delete service <%s>?", idOrName), false)

Copilot uses AI. Check for mistakes.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@internal/cmd/service/delete/delete.go`:
- Around line 98-101: The branch that currently logs "Please use --yes to
confirm deletion without interactive prompt" should return a non-nil error to
produce a non-zero exit code instead of returning nil; update the conditional
using f.Interactive and opts.skipConfirm so it returns an error (e.g., a
formatted error or cli.Exit) after logging via f.Log.Info (or replace the log
with f.Log.Error) with a clear message like "use --yes to confirm deletion
without interactive prompt" so scripts detect failure. Ensure you modify the
function that contains the f.Interactive / opts.skipConfirm check to propagate
the error return type.

Comment on lines +98 to +101
} else if !f.Interactive && !opts.skipConfirm {
f.Log.Info("Please use --yes to confirm deletion without interactive prompt")
return nil
}
Copy link

@coderabbitai coderabbitai bot Feb 13, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Return a non-zero exit when --yes is required but missing.

Right now the command logs a message and exits successfully even though nothing happened. That’s risky for scripts that assume success means deletion.

💡 Proposed fix
-	} else if !f.Interactive && !opts.skipConfirm {
-		f.Log.Info("Please use --yes to confirm deletion without interactive prompt")
-		return nil
-	}
+	} else if !f.Interactive && !opts.skipConfirm {
+		return fmt.Errorf("confirmation required: re-run with --yes to delete non-interactively")
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else if !f.Interactive && !opts.skipConfirm {
f.Log.Info("Please use --yes to confirm deletion without interactive prompt")
return nil
}
} else if !f.Interactive && !opts.skipConfirm {
return fmt.Errorf("confirmation required: re-run with --yes to delete non-interactively")
}
🤖 Prompt for AI Agents
In `@internal/cmd/service/delete/delete.go` around lines 98 - 101, The branch that
currently logs "Please use --yes to confirm deletion without interactive prompt"
should return a non-nil error to produce a non-zero exit code instead of
returning nil; update the conditional using f.Interactive and opts.skipConfirm
so it returns an error (e.g., a formatted error or cli.Exit) after logging via
f.Log.Info (or replace the log with f.Log.Error) with a clear message like "use
--yes to confirm deletion without interactive prompt" so scripts detect failure.
Ensure you modify the function that contains the f.Interactive /
opts.skipConfirm check to propagate the error return type.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping return nil to stay consistent with project delete, which uses the same pattern (internal/cmd/project/delete/delete.go:61).

Copy link

Choose a reason for hiding this comment

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the project delete command to verify the pattern
cat internal/cmd/project/delete/delete.go | head -70 | tail -20

Length of output: 471


@canyugs Confirmed! I can see the same pattern in project delete where it returns nil with an info message when --yes is missing. Consistency across commands makes sense. Thanks for the context! 👍

@canyugs canyugs self-assigned this Feb 13, 2026
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.

1 participant