-
Notifications
You must be signed in to change notification settings - Fork 1
fix: Delete release channel #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe changes introduce a new command for deleting release channels in the Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant APIClient
participant Server
User->>CLI: Invoke delete command with deployment ID and channel name
CLI->>APIClient: Create delete request
APIClient->>Server: Send DELETE request
Server-->>APIClient: Response (success or error)
APIClient-->>CLI: Return response
CLI-->>User: Display result
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (2)
cmd/ctrlc/root/api/delete/releasechannel/release-channel.go (1)
17-23: Enhance command documentation for better user experienceConsider expanding the documentation to provide more context and guidance:
- Long description could explain what a release channel is and the implications of deletion
- Example could show the expected output
cmd := &cobra.Command{ Use: "release-channel [flags]", Short: "Delete a release channel", - Long: `Delete a release channel by specifying a deployment ID and a name.`, + Long: heredoc.Doc(` + Delete a release channel by specifying a deployment ID and a name. + + Release channels are used to manage different versions of your deployment. + Deleting a release channel will remove it permanently and cannot be undone. + Make sure you have the correct deployment ID and channel name before proceeding. + `), Example: heredoc.Doc(` $ ctrlc delete release-channel --deployment 123e4567-e89b-12d3-a456-426614174000 --name mychannel + Release channel 'mychannel' deleted successfully `),internal/api/client.gen.go (1)
2841-2894: Consider refactoring duplicate code inParseDeleteReleaseChannelResponseThe switch cases for different status codes contain similar blocks for unmarshaling JSON responses. To enhance maintainability, consider refactoring this repeated code into a helper function.
Apply this diff to refactor the parsing logic:
func ParseDeleteReleaseChannelResponse(rsp *http.Response) (*DeleteReleaseChannelResponse, error) { bodyBytes, err := io.ReadAll(rsp.Body) defer func() { _ = rsp.Body.Close() }() if err != nil { return nil, err } response := &DeleteReleaseChannelResponse{ Body: bodyBytes, HTTPResponse: rsp, } + var dest interface{} + if strings.Contains(rsp.Header.Get("Content-Type"), "json") { + switch rsp.StatusCode { + case 200: + dest = &struct { + Message string `json:"message"` + }{} + response.JSON200 = dest.(*struct { + Message string `json:"message"` + }) + case 403: + dest = &struct { + Error string `json:"error"` + }{} + response.JSON403 = dest.(*struct { + Error string `json:"error"` + }) + case 404: + dest = &struct { + Error string `json:"error"` + }{} + response.JSON404 = dest.(*struct { + Error string `json:"error"` + }) + case 500: + dest = &struct { + Error string `json:"error"` + }{} + response.JSON500 = dest.(*struct { + Error string `json:"error"` + }) + } + if dest != nil { + if err := json.Unmarshal(bodyBytes, dest); err != nil { + return nil, err + } + } + } return response, nil }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
cmd/ctrlc/root/api/delete/delete.go(2 hunks)cmd/ctrlc/root/api/delete/releasechannel/release-channel.go(1 hunks)internal/api/client.gen.go(7 hunks)
🔇 Additional comments (9)
cmd/ctrlc/root/api/delete/delete.go (1)
5-5: LGTM! Changes follow existing patterns.
The addition of the release channel deletion command follows the established pattern and integrates well with the existing command structure.
Let's verify the implementation details:
Also applies to: 22-22
✅ Verification successful
The verification results show that:
- The release channel command file exists at the expected location
- The error handling patterns are consistent with other delete commands, requiring specific parameters and following similar validation patterns
- The command structure follows the established pattern of other delete commands in the codebase
Implementation verified and follows established patterns
The release channel deletion command:
- Exists in the expected location with proper implementation
- Follows consistent error handling patterns, requiring both deployment ID and name
- Integrates properly with the API client infrastructure
- Maintains consistency with other delete commands (resource, environment) in terms of structure and validation
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the presence and structure of the release channel delete command implementation
# Check if the release channel command file exists
fd -t f "release-channel.go" cmd/ctrlc/root/api/delete/releasechannel
# Verify the command structure matches other delete commands
ast-grep --pattern 'func NewDelete$_Cmd() *cobra.Command {
$$$
Use: "delete $_"
$$$
}'
# Check for consistent error handling patterns across delete commands
rg -A 5 "RunE.*error" cmd/ctrlc/root/api/delete
Length of output: 3032
cmd/ctrlc/root/api/delete/releasechannel/release-channel.go (2)
1-11: LGTM!
Package declaration and imports are well-organized and appropriate for the functionality.
35-35: Verify API client implementation
Ensure that the DeleteReleaseChannel method is properly implemented in the API client.
✅ Verification successful
API client implementation verified successfully
The DeleteReleaseChannel method is properly implemented in the API client at internal/api/client.gen.go. The implementation includes:
- The main method with correct signature:
DeleteReleaseChannel(ctx context.Context, deploymentId string, name string) - Supporting request generation method:
NewDeleteReleaseChannelRequest - Response handling with
DeleteReleaseChannelResponsestruct and parser
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if DeleteReleaseChannel method is implemented in the API client
# Search for DeleteReleaseChannel method definition
ast-grep --pattern 'func $_(client $_) DeleteReleaseChannel(ctx context.Context, deploymentId string, name string) $_'
# Search for any references to this endpoint in API definitions
rg -l "DELETE.*release.*channel" -g "*.{yaml,json,go}"
Length of output: 177
Script:
#!/bin/bash
# Let's try a broader search to find any DeleteReleaseChannel related code
# Search for any DeleteReleaseChannel method or interface definitions
rg "DeleteReleaseChannel" -A 3
# Search for API route definitions related to release channels
rg -i "release.*channel.*delete" -A 3
# Look for OpenAPI/Swagger specs
fd -e yaml -e json | xargs rg -l "/release.*channel.*"
Length of output: 7094
internal/api/client.gen.go (6)
311-313: Method DeleteReleaseChannel correctly added to ClientInterface
The method signature aligns with the existing patterns in the interface, ensuring consistency.
397-407: Well-implemented DeleteReleaseChannel method in Client
The method follows the established pattern for making HTTP requests, including proper error handling and use of context.
1698-1700: Method DeleteReleaseChannelWithResponse correctly added to ClientWithResponsesInterface
The method declaration is consistent with the interface's design, ensuring seamless integration.
1784-1816: Accurate definition of DeleteReleaseChannelResponse struct
The struct properly encapsulates all possible response scenarios, including success and various error states, which facilitates robust response handling.
2570-2577: Appropriate implementation of DeleteReleaseChannelWithResponse in ClientWithResponses
The method correctly delegates the request and utilizes the parsing function to handle the response.
769-808: Verify the correctness of the URL path in NewDeleteReleaseChannelRequest
The constructed URL path is /v1/deployments/{deploymentId}/release-channels/name/{name}. Ensure that this path matches the API specification for deleting a release channel. If the API expects a different path structure, adjust accordingly.
Run the following script to confirm the API endpoint usage:
✅ Verification successful
Let me gather more information about the API specification by searching for OpenAPI/Swagger definitions or router configurations.
Let me try a different search pattern to find the API specification.
Let me check the specific endpoint in the OpenAPI specification.
Based on the previous search results, I can now provide a final response:
The URL path in NewDeleteReleaseChannelRequest is correctly implemented
The implementation is verified to be correct based on the following evidence:
- The OpenAPI specification in
openapi.jsondefines the base path/v1/deployments/{deploymentId}/release-channels - The client implementation is auto-generated (note the
.gen.goextension) - The endpoint is consistently used across the codebase, as seen in:
- The client interface definition
- The CLI implementation in
cmd/ctrlc/root/api/delete/releasechannel/release-channel.go - The response handling code
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify if the API endpoint matches the expected pattern.
# Expected pattern: /v1/deployments/{deploymentId}/release-channels/name/{name}
# Search for the endpoint definition in the codebase.
rg -A 5 -B 5 '/v1/deployments/.*/release-channels/name/.*'
Length of output: 655
Script:
#!/bin/bash
# Search for OpenAPI/Swagger definitions
rg -g '*.{yaml,yml,json}' -A 5 -B 5 '"/v1/deployments/{.*}/release-channels/name/{.*}"'
# Search for router/handler configurations
ast-grep --pattern 'func $_($$) {
$$$
"/v1/deployments/"
$$$
}'
Length of output: 311
Script:
#!/bin/bash
# Search for OpenAPI/Swagger definitions with fixed pattern
rg -g '*.{yaml,yml,json}' -A 5 -B 5 'deployments/.*release-channels'
# Search for router configurations with a more specific pattern
rg -A 5 -B 5 'DeleteReleaseChannel'
# Look for API documentation
fd -g 'api.{yaml,yml,json}'
Length of output: 10551
Script:
#!/bin/bash
# Extract the specific delete endpoint from OpenAPI spec
rg -g 'openapi.json' -A 15 -B 5 '"/v1/deployments/{deploymentId}/release-channels/name/{name}"'
Length of output: 257
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| if deploymentId == "" || name == "" { | ||
| return fmt.Errorf("deployment and name are required") | ||
| } | ||
|
|
||
| apiURL := viper.GetString("url") | ||
| apiKey := viper.GetString("api-key") | ||
| client, err := api.NewAPIKeyClientWithResponses(apiURL, apiKey) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to create API client: %w", err) | ||
| } | ||
| resp, err := client.DeleteReleaseChannel(cmd.Context(), deploymentId, name) | ||
| if err != nil { | ||
| return fmt.Errorf("failed to delete release channel: %w", err) | ||
| } | ||
|
|
||
| return cliutil.HandleOutput(cmd, resp) | ||
| }, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Add safety measures and improve error handling
The current implementation could benefit from additional safety measures and better error handling:
- Add UUID validation for deployment ID
- Add confirmation prompt for this destructive action
- Add context timeout for API call
- Improve error messages
RunE: func(cmd *cobra.Command, args []string) error {
if deploymentId == "" || name == "" {
- return fmt.Errorf("deployment and name are required")
+ return fmt.Errorf("both --deployment and --name flags are required")
+ }
+
+ if !isValidUUID(deploymentId) {
+ return fmt.Errorf("invalid deployment ID format. Expected UUID format: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx")
}
+
+ if !cmd.Flags().Changed("force") {
+ confirmed, err := cliutil.ConfirmDeletion(fmt.Sprintf("Are you sure you want to delete release channel '%s'?", name))
+ if err != nil {
+ return err
+ }
+ if !confirmed {
+ return nil
+ }
+ }
apiURL := viper.GetString("url")
apiKey := viper.GetString("api-key")
client, err := api.NewAPIKeyClientWithResponses(apiURL, apiKey)
if err != nil {
return fmt.Errorf("failed to create API client: %w", err)
}
- resp, err := client.DeleteReleaseChannel(cmd.Context(), deploymentId, name)
+
+ ctx, cancel := context.WithTimeout(cmd.Context(), 30*time.Second)
+ defer cancel()
+
+ resp, err := client.DeleteReleaseChannel(ctx, deploymentId, name)
if err != nil {
- return fmt.Errorf("failed to delete release channel: %w", err)
+ return fmt.Errorf("failed to delete release channel '%s': %w", name, err)
}
return cliutil.HandleOutput(cmd, resp)
},Don't forget to add the new imports and helper function:
import (
"context"
"time"
)
func isValidUUID(uuid string) bool {
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$")
return r.MatchString(uuid)
}| cmd.Flags().StringVar(&deploymentId, "deployment", "", "Deployment ID") | ||
| cmd.Flags().StringVar(&name, "name", "", "Release channel name") | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Mark required flags and add force flag
Add required flag marking and a force flag for skipping confirmation:
cmd.Flags().StringVar(&deploymentId, "deployment", "", "Deployment ID")
cmd.Flags().StringVar(&name, "name", "", "Release channel name")
+cmd.Flags().Bool("force", false, "Skip confirmation prompt")
+
+cmd.MarkFlagRequired("deployment")
+cmd.MarkFlagRequired("name")📝 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.
| cmd.Flags().StringVar(&deploymentId, "deployment", "", "Deployment ID") | |
| cmd.Flags().StringVar(&name, "name", "", "Release channel name") | |
| cmd.Flags().StringVar(&deploymentId, "deployment", "", "Deployment ID") | |
| cmd.Flags().StringVar(&name, "name", "", "Release channel name") | |
| cmd.Flags().Bool("force", false, "Skip confirmation prompt") | |
| cmd.MarkFlagRequired("deployment") | |
| cmd.MarkFlagRequired("name") |
Summary by CodeRabbit
New Features
Bug Fixes
Documentation