Skip to content

Commit 4e10ea9

Browse files
fix: Add create release for backwards compatibility
1 parent 480ac8f commit 4e10ea9

2 files changed

Lines changed: 129 additions & 0 deletions

File tree

cmd/ctrlc/root/api/create/create.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package create
33
import (
44
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/api/create/environment"
55
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/api/create/relationship"
6+
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/api/create/release"
67
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/api/create/releasechannel"
78
"github.com/spf13/cobra"
89
)
@@ -20,6 +21,7 @@ func NewCreateCmd() *cobra.Command {
2021
cmd.AddCommand(releasechannel.NewCreateReleaseChannelCmd())
2122
cmd.AddCommand(environment.NewCreateEnvironmentCmd())
2223
cmd.AddCommand(relationship.NewRelationshipCmd())
24+
cmd.AddCommand(release.NewCreateReleaseCmd())
2325

2426
return cmd
2527
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package release
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"net/http"
7+
"strings"
8+
"time"
9+
10+
"github.com/MakeNowJust/heredoc/v2"
11+
"github.com/ctrlplanedev/cli/internal/api"
12+
"github.com/ctrlplanedev/cli/internal/cliutil"
13+
"github.com/spf13/cobra"
14+
"github.com/spf13/viper"
15+
)
16+
17+
func safeConvertToReleaseStatus(status string) (*api.UpsertReleaseJSONBodyStatus, error) {
18+
statusLower := strings.ToLower(status)
19+
if statusLower == "ready" || statusLower == "" {
20+
s := api.UpsertReleaseJSONBodyStatusReady
21+
return &s, nil
22+
}
23+
if statusLower == "building" {
24+
s := api.UpsertReleaseJSONBodyStatusBuilding
25+
return &s, nil
26+
}
27+
if statusLower == "failed" {
28+
s := api.UpsertReleaseJSONBodyStatusFailed
29+
return &s, nil
30+
}
31+
return nil, fmt.Errorf("invalid release status: %s", status)
32+
}
33+
34+
func NewCreateReleaseCmd() *cobra.Command {
35+
var versionFlag string
36+
var deploymentID []string
37+
var metadata map[string]string
38+
var configArray map[string]string
39+
var links map[string]string
40+
var createdAt string
41+
var name string
42+
var status string
43+
var message string
44+
45+
cmd := &cobra.Command{
46+
Use: "release [flags]",
47+
Short: "Create a release",
48+
Long: `Create a release with the specified version and configuration.`,
49+
Example: heredoc.Doc(`
50+
# Create a release
51+
$ ctrlc create release --version v1.0.0 --deployment 1234567890
52+
53+
# Create a release using Go template syntax
54+
$ ctrlc create release --version v1.0.0 --deployment 1234567890 --template='{{.status.phase}}'
55+
56+
# Create a release for multiple deployments
57+
$ ctrlc create release --version v1.0.0 --deployment 1234567890 --deployment 0987654321
58+
`),
59+
RunE: func(cmd *cobra.Command, args []string) error {
60+
apiURL := viper.GetString("url")
61+
apiKey := viper.GetString("api-key")
62+
client, err := api.NewAPIKeyClientWithResponses(apiURL, apiKey)
63+
if err != nil {
64+
return fmt.Errorf("failed to create API client: %w", err)
65+
}
66+
67+
var parsedTime *time.Time
68+
if createdAt != "" {
69+
t, err := time.Parse(time.RFC3339, createdAt)
70+
if err != nil {
71+
return fmt.Errorf("failed to parse created_at time: %w", err)
72+
}
73+
parsedTime = &t
74+
}
75+
76+
if len(links) > 0 {
77+
linksJSON, err := json.Marshal(links)
78+
if err != nil {
79+
return fmt.Errorf("failed to marshal links: %w", err)
80+
}
81+
metadata["ctrlplane/links"] = string(linksJSON)
82+
}
83+
84+
stat, err := safeConvertToReleaseStatus(status)
85+
if err != nil {
86+
return fmt.Errorf("failed to convert release status: %w", err)
87+
}
88+
89+
config := cliutil.ConvertConfigArrayToNestedMap(configArray)
90+
var response *http.Response
91+
for _, id := range deploymentID {
92+
resp, err := client.UpsertRelease(cmd.Context(), api.UpsertReleaseJSONRequestBody{
93+
Version: versionFlag,
94+
DeploymentId: id,
95+
Metadata: cliutil.MetadataPtr(metadata),
96+
CreatedAt: parsedTime,
97+
Config: cliutil.ConfigPtr(config),
98+
Name: cliutil.StringPtr(name),
99+
Status: stat,
100+
Message: cliutil.StringPtr(message),
101+
})
102+
if err != nil {
103+
return fmt.Errorf("failed to create release: %w", err)
104+
}
105+
response = resp
106+
}
107+
108+
return cliutil.HandleOutput(cmd, response)
109+
},
110+
}
111+
112+
// Add flags
113+
cmd.Flags().StringVarP(&versionFlag, "version", "v", "", "Version of the release (required)")
114+
cmd.Flags().StringArrayVarP(&deploymentID, "deployment", "d", []string{}, "IDs of the deployments (required, supports multiple)")
115+
cmd.Flags().StringToStringVarP(&metadata, "metadata", "m", make(map[string]string), "Metadata key-value pairs (e.g. --metadata key=value)")
116+
cmd.Flags().StringToStringVarP(&configArray, "config", "c", make(map[string]string), "Config key-value pairs with nested values (can be specified multiple times)")
117+
cmd.Flags().StringToStringVarP(&links, "link", "l", make(map[string]string), "Links key-value pairs (can be specified multiple times)")
118+
cmd.Flags().StringVarP(&createdAt, "created-at", "t", "", "Created at timestamp (e.g. --created-at 2024-01-01T00:00:00Z) for the release channel")
119+
cmd.Flags().StringVarP(&name, "name", "n", "", "Name of the release channel")
120+
cmd.Flags().StringVarP(&status, "status", "s", string(api.UpsertReleaseJSONBodyStatusReady), "Status of the release channel (one of: ready, building, failed)")
121+
cmd.Flags().StringVar(&message, "message", "", "Message of the release channel")
122+
123+
cmd.MarkFlagRequired("version")
124+
cmd.MarkFlagRequired("deployment")
125+
126+
return cmd
127+
}

0 commit comments

Comments
 (0)