Skip to content

Commit

Permalink
Introduce optional replace semantics for railway variables set as a…
Browse files Browse the repository at this point in the history
…n alternative to upsert (#265)

* Introduce optional replace semantics for variables set as an alternative to upsert

* Add a safety prompt for replace and a flag to skip it

* Update wordings, simplify function signature and add comment to warn about destructive query
ChristianIvicevic authored Aug 24, 2022

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent 46ce910 commit 112651c
Showing 5 changed files with 49 additions and 9 deletions.
32 changes: 30 additions & 2 deletions cmd/variables.go
Original file line number Diff line number Diff line change
@@ -63,6 +63,29 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest)
skipRedeploy = false
}

replace, err := req.Cmd.Flags().GetBool("replace")
if err != nil {
// The flag is optional; default to false.
replace = false
}

yes, err := req.Cmd.Flags().GetBool("yes")
if err != nil {
// The flag is optional; default to false.
yes = false
}

if replace && !yes {
fmt.Println(ui.Bold(ui.RedText(fmt.Sprintf("Warning! You are about to fully replace all your variables for the service '%s'.", serviceName)).String()))
confirm, err := ui.PromptYesNo("Continue?")
if err != nil {
return err
}
if !confirm {
return nil
}
}

variables := &entity.Envs{}
updatedEnvNames := make([]string, 0)

@@ -78,7 +101,7 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest)
updatedEnvNames = append(updatedEnvNames, key)
}

err = h.ctrl.UpsertEnvs(ctx, variables, &serviceName)
err = h.ctrl.UpdateEnvs(ctx, variables, &serviceName, replace)

if err != nil {
return err
@@ -89,7 +112,12 @@ func (h *Handler) VariablesSet(ctx context.Context, req *entity.CommandRequest)
return err
}

fmt.Print(ui.Heading(fmt.Sprintf("Updated %s for \"%s\"", strings.Join(updatedEnvNames, ", "), environment.Name)))
operation := "Updated"
if replace {
operation = "Replaced existing variables with"
}

fmt.Print(ui.Heading(fmt.Sprintf("%s %s for \"%s\"", operation, strings.Join(updatedEnvNames, ", "), environment.Name)))
fmt.Print(ui.KeyValues(*variables))

if !skipRedeploy {
7 changes: 4 additions & 3 deletions controller/envs.go
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ func (c *Controller) AutoImportDotEnv(ctx context.Context) error {
return err
}
if len(envMap) > 0 {
return c.UpsertEnvs(ctx, (*entity.Envs)(&envMap), nil)
return c.UpdateEnvs(ctx, (*entity.Envs)(&envMap), nil, false)
}
}
return nil
@@ -134,7 +134,7 @@ func (c *Controller) SaveEnvsToFile(ctx context.Context) error {
return nil
}

func (c *Controller) UpsertEnvs(ctx context.Context, envs *entity.Envs, serviceName *string) error {
func (c *Controller) UpdateEnvs(ctx context.Context, envs *entity.Envs, serviceName *string, replace bool) error {
projectCfg, err := c.GetProjectConfigs(ctx)
if err != nil {
return err
@@ -185,12 +185,13 @@ func (c *Controller) UpsertEnvs(ctx context.Context, envs *entity.Envs, serviceN
}
}

return c.gtwy.UpsertVariablesFromObject(ctx, &entity.UpdateEnvsRequest{
return c.gtwy.UpdateVariablesFromObject(ctx, &entity.UpdateEnvsRequest{
ProjectID: projectCfg.Project,
EnvironmentID: projectCfg.Environment,
PluginID: pluginID,
ServiceID: serviceID,
Envs: envs,
Replace: replace,
})
}

1 change: 1 addition & 0 deletions entity/envs.go
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ type UpdateEnvsRequest struct {
PluginID string
ServiceID string
Envs *Envs
Replace bool
}

type DeleteVariableRequest struct {
16 changes: 12 additions & 4 deletions gateway/envs.go
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ package gateway

import (
"context"
"fmt"

"github.com/railwayapp/cli/entity"
)
@@ -32,12 +33,19 @@ func (g *Gateway) GetEnvs(ctx context.Context, req *entity.GetEnvsRequest) (*ent
return resp.Envs, nil
}

func (g *Gateway) UpsertVariablesFromObject(ctx context.Context, req *entity.UpdateEnvsRequest) error {
gqlReq, err := g.NewRequestWithAuth(`
func (g *Gateway) UpdateVariablesFromObject(ctx context.Context, req *entity.UpdateEnvsRequest) error {
queryName := "upsertVariablesFromObject"

if req.Replace {
// When replacing, use the set query which will blow away all old variables and only set the ones in this query
queryName = "variablesSetFromObject"
}

gqlReq, err := g.NewRequestWithAuth(fmt.Sprintf(`
mutation($projectId: String!, $environmentId: String!, $pluginId: String, $serviceId: String, $variables: Json!) {
upsertVariablesFromObject(projectId: $projectId, environmentId: $environmentId, pluginId: $pluginId, serviceId: $serviceId, variables: $variables)
%s(projectId: $projectId, environmentId: $environmentId, pluginId: $pluginId, serviceId: $serviceId, variables: $variables)
}
`)
`, queryName))
if err != nil {
return err
}
2 changes: 2 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -154,6 +154,8 @@ func init() {
variablesCmd.AddCommand(variablesSetCmd)
variablesSetCmd.Flags().StringP("service", "s", "", "Fetch variables accessible to a specific service")
variablesSetCmd.Flags().Bool("skip-redeploy", false, "Skip redeploying the specified service after changing the variables")
variablesSetCmd.Flags().Bool("replace", false, "Fully replace all previous variables instead of updating them")
variablesSetCmd.Flags().Bool("yes", false, "Skip all confirmation dialogs")

variablesDeleteCmd := &cobra.Command{
Use: "delete key",

0 comments on commit 112651c

Please sign in to comment.