gitops

package
v6.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 28, 2026 License: MIT Imports: 22 Imported by: 0

Documentation

Overview

Package gitops compares files kept in Git with what the platform holds, for `diff` and `apply --dry-run`, and moves whole projects between the two.

Index

Constants

This section is empty.

Variables

View Source
var ErrDifferent = errors.New("files differ from the platform")

ErrDifferent ends `diff` with exit status 2 when files and platform disagree, so a pipeline can tell drift (2) from a failure (1).

View Source
var Experiment = Kind{
	Name:     "experiment",
	ReadOnly: []string{"version", "created", "createdBy", "edited", "editedBy"},
	Identity: "key",

	Remote: func(ctx context.Context, c *platform.Client, local *jsyaml.Map) (string, *jsyaml.Map, error) {
		key := str(local, "key")
		if key == "" {
			externalID := str(local, "externalId")
			if externalID == "" {
				return "", nil, nil
			}
			var list struct {
				Experiments []struct {
					Key string `json:"key"`
				} `json:"experiments"`
			}
			ids := []string{externalID}
			resp, err := c.GetExperiments(ctx, &api.GetExperimentsParams{ExternalId: &ids})
			if _, err := platform.Decode(resp, err, &list); err != nil {
				return "", nil, err
			}
			if len(list.Experiments) == 0 {
				return "", nil, nil
			}
			key = list.Experiments[0].Key
		}
		remote, err := fetch(c.GetExperiment(ctx, key))
		return key, remote, err
	},
}
View Source
var Schedule = Kind{
	Name:     "experiment schedule",
	ReadOnly: []string{"editedBy", "lastUpdated", "nextExecution"},
	Defaults: map[string]any{"allowParallel": true},
	Identity: "id",
	Remote: func(ctx context.Context, c *platform.Client, local *jsyaml.Map) (string, *jsyaml.Map, error) {
		id := str(local, "id")
		if id == "" {
			return "", nil, nil
		}
		remote, err := fetch(c.GetSchedules(ctx, id))
		return id, remote, err
	},
}
View Source
var Service = Kind{
	Name:     "service",
	ReadOnly: []string{"version", "created", "createdBy", "edited", "editedBy"},
	Defaults: map[string]any{"logoId": "service", "logoColor": "blue"},
	Identity: "id",
	Remote: func(ctx context.Context, c *platform.Client, local *jsyaml.Map) (string, *jsyaml.Map, error) {
		id := str(local, "id")
		u, ok := uuid(id)
		if !ok {
			return "", nil, nil
		}
		remote, err := fetch(c.GetService(ctx, u))
		return id, remote, err
	},
}
View Source
var ServiceProfile = Kind{
	Name:     "service profile",
	ReadOnly: []string{"version", "created", "createdBy", "edited", "editedBy", "defaultProfile"},
	Defaults: map[string]any{"origin": "CUSTOM"},
	Identity: "id",

	Remote: func(ctx context.Context, c *platform.Client, local *jsyaml.Map) (string, *jsyaml.Map, error) {
		id := str(local, "id")
		if u, ok := uuid(id); ok {
			remote, err := fetch(c.GetProfile(ctx, u))
			return id, remote, err
		}
		name := str(local, "name")
		if name == "" {
			return "", nil, nil
		}
		type profile struct {
			ID   string `json:"id"`
			Name string `json:"name"`
		}
		profiles, err := platform.AllPages[profile](func(page, size int32) (*http.Response, error) {
			return c.GetProfiles(ctx, &api.GetProfilesParams{Name: &name, Page: api.PageRequestAO{Page: &page, Size: &size}})
		})
		if err != nil {
			return "", nil, err
		}
		for _, p := range profiles {
			if p.Name == name {
				u, _ := uuid(p.ID)
				remote, err := fetch(c.GetProfile(ctx, u))
				return p.ID, remote, err
			}
		}
		return "", nil, nil
	},
}

Functions

func ApplyProject

func ApplyProject(ctx context.Context, c *platform.Client, o ApplyOptions) error

ApplyProject applies every kind in a project, profiles first and schedules last.

func Changes

func Changes(diff string) int

Changes counts the changed lines of a diff, for dry runs.

func Comparable

func Comparable(local, remote any) any

Comparable projects the platform's version of a document onto the file's: every field the file sets, and only those fields the file leaves out that hold something. The platform fills in defaults (false, empty lists and maps) that a file written by hand omits; reporting those would bury every real difference.

func Diff

func Diff(file string, local, remote *jsyaml.Map, always ...string) (string, error)

Diff is a unified diff from the platform's version to the file's, empty when they agree. Both sides are rendered as YAML the way `get` writes it. Fields in always are reported whenever the platform holds them and the file does not.

func DiffFiles

func DiffFiles(ctx context.Context, c *platform.Client, k Kind, paths []string, recursive bool) error

DiffFiles prints how each file differs from the platform: a unified diff for changes, a line for files that would create something new.

func DiffProject

func DiffProject(ctx context.Context, c *platform.Client, dir string) error

DiffProject diffs every kind in a project, and reports drift once all were compared.

func DryRun

func DryRun(ctx context.Context, c *platform.Client, k Kind, paths []string, recursive bool) error

DryRun reports what applying the files would do, without applying anything.

func Export

func Export(ctx context.Context, c *platform.Client, o ExportOptions) error

Export writes a team's experiments, schedules and services, and the custom service profiles those services use, as a project. Files are only written, never removed, so something deleted on the platform keeps its file until it is removed by hand.

Types

type ApplyOptions

type ApplyOptions struct {
	Directory         string
	DeleteExperiments bool
	DryRun            bool
}

type ExportOptions

type ExportOptions struct {
	Directory string
	Team      string
}

type Kind

type Kind struct {
	// Name is what messages call it, "experiment" or "service profile".
	Name string
	// ReadOnly fields are reported by the platform but not part of the file.
	ReadOnly []string
	// Defaults are the values the platform gives fields a file leaves out. Holding
	// exactly that, such a field is not a difference; holding anything else, applying
	// the file would reset it, which is.
	Defaults map[string]any
	// Identity is the field that names it on the platform. A file matched otherwise, by
	// an externalId or a name, has none yet, which is not a difference.
	Identity string
	// Remote finds the platform's version of a file: its id and content, or nil when
	// applying the file would create something new.
	Remote func(ctx context.Context, c *platform.Client, local *jsyaml.Map) (string, *jsyaml.Map, error)
}

Kind is a type of file kept in Git and how to find its counterpart on the platform.

type Result

type Result struct {
	File  string
	ID    string
	State State
	Diff  string
}

func Compare

func Compare(ctx context.Context, c *platform.Client, k Kind, file string, local *output.Document) (Result, error)

Compare works out what applying the file would change on the platform.

func (Result) Describe

func (r Result) Describe(k Kind) string

Describe is the one-line outcome of a comparison, as a dry run reports it.

type State

type State int

State is what applying a file would do.

const (
	Unchanged State = iota
	Changed
	New
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL