pkg/api/internal/variables/variables.go (60 lines of code) (raw):

// package variables implements a type and functions to handle CI job variables as described in // https://docs.gitlab.com/ee/ci/variables. This includes handling file-type variables and (eventually) masked // variables. It is analogous to, but a subset/simplification of, // https://gitlab.com/gitlab-org/gitlab-runner/-/blob/main/common/variables.go. This includes things like expanding // variables and writing file-type variables to file. package variables import ( "fmt" "os" "path" "gitlab.com/gitlab-org/step-runner/proto" ) type Variable struct { v *proto.Variable tmpPath string } func (v *Variable) File() bool { return v.v.File } func (v *Variable) Masked() bool { return v.v.Masked } func (v *Variable) Key() string { return v.v.Key } // File type variables return the full path to the file instead of the value. func (v *Variable) Value() string { if v.v.File { return path.Join(v.tmpPath, v.v.Key) } else { return v.v.Value } } func (v *Variable) Write() error { if !v.v.File { return fmt.Errorf("variable %q is not a file variable", v.v.Key) } return os.WriteFile(v.Value(), []byte(v.v.Value), 0600) } type Variables []Variable func New(vars []*proto.Variable, tmpPath string) Variables { result := make(Variables, 0, len(vars)) for _, v := range vars { result = append(result, Variable{v: v, tmpPath: tmpPath}) } return result } func (vs *Variables) Write() error { for _, v := range *vs { if !v.File() { continue } if err := v.Write(); err != nil { return fmt.Errorf("writing file variable %q: %w", v.Key(), err) } } return nil } func Prepare(pjob *proto.Job, tmpPath string) (map[string]string, error) { if pjob == nil { return map[string]string{}, nil } outEnv := make(map[string]string, len(pjob.Variables)) jobVars := New(pjob.Variables, tmpPath) for _, v := range jobVars { outEnv[v.Key()] = v.Value() } if err := jobVars.Write(); err != nil { return nil, fmt.Errorf("preparing variables: %w", err) } return outEnv, nil }