Skip to content

Commit

Permalink
feat(directives): add compose-output directive
Browse files Browse the repository at this point in the history
Signed-off-by: Hidde Beydals <[email protected]>
  • Loading branch information
hiddeco committed Dec 13, 2024
1 parent 620f666 commit 7f0be4c
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 0 deletions.
73 changes: 73 additions & 0 deletions internal/directives/output_composer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package directives

import (
"context"
"fmt"

"github.com/xeipuuv/gojsonschema"

kargoapi "github.com/akuity/kargo/api/v1alpha1"
)

func init() {
builtins.RegisterPromotionStepRunner(newOutputComposer(), nil)
}

// outputComposer is an implementation of the PromotionStepRunner interface
// that allows composing outputs from previous steps into new outputs.
//
// It works based on the PromotionStepContext.Config field allowing to an
// arbitrary number of key-value pairs to be exported as outputs.
// Because the values are allowed to be expressions and can contain
// references to outputs from previous steps, this allows for remapping
// the outputs of previous steps to new keys, or even combining them
// into new structures.
type outputComposer struct {
schemaLoader gojsonschema.JSONLoader
}

// newOutputComposer returns an implementation of the PromotionStepRunner
// interface that composes output from previous steps into new output.
func newOutputComposer() PromotionStepRunner {
r := &outputComposer{}
r.schemaLoader = getConfigSchemaLoader(r.Name())
return r
}

// Name implements the PromotionStepRunner interface.
func (c *outputComposer) Name() string {
return "compose-output"
}

// RunPromotionStep implements the PromotionStepRunner interface.
func (c *outputComposer) RunPromotionStep(
_ context.Context,
stepCtx *PromotionStepContext,
) (PromotionStepResult, error) {
// Validate the configuration against the JSON Schema.
if err := validate(c.schemaLoader, gojsonschema.NewGoLoader(stepCtx.Config), c.Name()); err != nil {
return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored}, err
}

// Convert the configuration into a typed object.
cfg, err := ConfigToStruct[ComposeOutput](stepCtx.Config)
if err != nil {
return PromotionStepResult{Status: kargoapi.PromotionPhaseErrored},
fmt.Errorf("could not convert config into %s config: %w", c.Name(), err)
}

return c.runPromotionStep(cfg)
}

func (c *outputComposer) runPromotionStep(
cfg ComposeOutput,
) (PromotionStepResult, error) {
var output = make(map[string]any, len(cfg))
for k, v := range cfg {
output[k] = v
}
return PromotionStepResult{
Status: kargoapi.PromotionPhaseSucceeded,
Output: output,
}, nil
}
6 changes: 6 additions & 0 deletions internal/directives/schemas/compose-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ComposeOutput",
"type": "object",
"minProperties": 1
}
2 changes: 2 additions & 0 deletions internal/directives/zz_config_types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions ui/src/gen/directives/compose-output.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ComposeOutput",
"type": "object",
"minProperties": 1
}

0 comments on commit 7f0be4c

Please sign in to comment.