Skip to content

Commit

Permalink
add 'sync' command to sync remote split assignments with local schema (
Browse files Browse the repository at this point in the history
…#64)

Sometimes we want to sync our local TestTrack assignments with the weights in the production environment. Creating a TestTrack CLI command to easily take all the assignments from remote json split registry and assign them to local yaml assignment file.
  • Loading branch information
SirNeuman authored Feb 10, 2025
1 parent 3fc51c2 commit f2d887e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
SHELL = /bin/sh

VERSION=1.5.0
VERSION=1.6.0
BUILD=`git rev-parse HEAD`

LDFLAGS=-ldflags "-w -s \
Expand Down
60 changes: 60 additions & 0 deletions cmds/sync.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package cmds

import (
"github.com/Betterment/testtrack-cli/schema"
"github.com/Betterment/testtrack-cli/serializers"
"github.com/Betterment/testtrack-cli/servers"
"github.com/Betterment/testtrack-cli/splits"
"github.com/spf13/cobra"
)

var syncDoc = `
Sync the local schema TestTrack assignments with the remote production TestTrack assignments.
`

func init() {
rootCmd.AddCommand(syncCommand)
}

var syncCommand = &cobra.Command{
Use: "sync",
Short: "Sync TestTrack assignments with production",
Long: syncDoc,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return Sync()
},
}

// Sync synchronizes the local schema TestTrack assignments with the remote production TestTrack assignments.
func Sync() error {
server, err := servers.New()
if err != nil {
return err
}

var splitRegistry serializers.RemoteRegistry
err = server.Get("api/v2/split_registry.json", &splitRegistry)
if err != nil {
return err
}

localSchema, err := schema.Read()
if err != nil {
return err
}

for ind, localSplit := range localSchema.Splits {
remoteSplit, exists := splitRegistry.Splits[localSplit.Name]
if exists {
remoteWeights := splits.Weights(remoteSplit.Weights)
localSchema.Splits[ind].Weights = remoteWeights.ToYAML()
}
}

if err := schema.Write(localSchema); err != nil {
return err
}

return nil
}
12 changes: 11 additions & 1 deletion serializers/serializers.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,22 @@ type SplitYAML struct {
Owner string `yaml:"owner,omitempty"`
}

// SplitJSON is is the JSON-marshalabe representation of a Split
// SplitJSON is the JSON-marshalabe representation of a Split
type SplitJSON struct {
Name string `json:"name"`
WeightingRegistry map[string]int `json:"weighting_registry"`
}

// RemoteRegistrySplit is the JSON-marshalable representation of a server-provided split configuration
type RemoteRegistrySplit struct {
Weights map[string]int `json:"weights"`
}

// RemoteRegistry is the JSON-marshalable representation of a server-provided split registry
type RemoteRegistry struct {
Splits map[string]RemoteRegistrySplit `json:"splits"`
}

// SplitRetirement is the JSON and YAML-marshalable representation of a SplitRetirement
type SplitRetirement struct {
Split string `json:"split"`
Expand Down

0 comments on commit f2d887e

Please sign in to comment.