Skip to content

Commit

Permalink
feat: add support for path actions outputs
Browse files Browse the repository at this point in the history
Signed-off-by: William Poussier <william.poussier@corp.ovh.com>
  • Loading branch information
wI2L committed Oct 23, 2024
1 parent d248054 commit e8a6ce3
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 14 deletions.
64 changes: 55 additions & 9 deletions engine/worker/internal/runV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,16 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte
return w.failJob(ctx, actionError.Error()), stepPostAction
}

if err := w.updateParentStepStatusWithOutputs(ctx, parentStepStatus, parentStepName, *actionContext, w.actions[name].Outputs); err != nil {
outputs := w.actions[name].Outputs
resolvedOutputs, err := w.computeOutputs(ctx, *actionContext, outputs)
if err != nil {
return w.failJob(ctx, err.Error()), stepPostAction
}

if err := w.collectActionOutputs(outputs, resolvedOutputs); err != nil {
return w.failJob(ctx, err.Error()), stepPostAction
}
if err := w.updateParentStepStatusWithOutputs(ctx, parentStepStatus, parentStepName, *actionContext, resolvedOutputs); err != nil {
return w.failJob(ctx, err.Error()), stepPostAction
}

Expand All @@ -669,21 +678,31 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte
return actionResult, stepPostAction
}

func (w *CurrentWorker) updateParentStepStatusWithOutputs(ctx context.Context, parentStepStatus sdk.JobStepsStatus, parentStepName string, actionContext sdk.WorkflowRunJobsContext, outputs map[string]sdk.ActionOutput) error {
func (w *CurrentWorker) collectActionOutputs(outputs map[string]sdk.ActionOutput, resolvedOutputs map[string]string) error {
for k, output := range outputs {
switch output.Type {
case sdk.ActionOutputTypePath:
if v, ok := resolvedOutputs[k]; ok {
w.paths = append(w.paths, v)
}
default:
// noop
}
}
return nil
}

func (w *CurrentWorker) updateParentStepStatusWithOutputs(ctx context.Context, parentStepStatus sdk.JobStepsStatus, parentStepName string, actionContext sdk.WorkflowRunJobsContext, outputs map[string]string) error {
parentStep := parentStepStatus[parentStepName]
parentStep.Outputs = sdk.JobResultOutput{}

resolvedOutpus, err := w.computeOutputs(ctx, actionContext, outputs)
if err != nil {
return err
}

for name, value := range resolvedOutpus {
for name, value := range outputs {
parentStep.Outputs[name] = value
}
parentStepStatus[parentStepName] = parentStep
return nil
}

func (w *CurrentWorker) computeOutputs(ctx context.Context, actionContext sdk.WorkflowRunJobsContext, outputs map[string]sdk.ActionOutput) (map[string]string, error) {
resolvedOutput := make(map[string]string)

Expand Down Expand Up @@ -798,7 +817,7 @@ func (w *CurrentWorker) failJob(ctx context.Context, reason string) sdk.V2Workfl
return res
}

// For actions, only pass CDS/GIT/ENV/Integration context from parrent
// For actions, only pass CDS/GIT/ENV/Integration context from parent
func (w *CurrentWorker) computeContextForAction(ctx context.Context, parentContext sdk.WorkflowRunJobsContext, inputs map[string]string) (*sdk.WorkflowRunJobsContext, error) {
actionContext := sdk.WorkflowRunJobsContext{
WorkflowRunContext: sdk.WorkflowRunContext{
Expand Down Expand Up @@ -894,10 +913,37 @@ func (w *CurrentWorker) GetEnvVariable(ctx context.Context, contexts sdk.Workflo
newEnvVar[k] = v
}
}
if len(w.paths) != 0 {
// Inject paths from the previous steps outputs.
pathList := filepath.SplitList(os.Getenv("PATH"))
if len(pathList) == 0 {
pathList = []string{""}
}
// Add current worker paths to the path list.
pathList = append(pathList, w.paths...)

// Remove duplicate paths.
pathList = removeDuplicate(pathList)

// Inject supercharged PATH environ variable.
newEnvVar["PATH"] = strings.Join(pathList, string(filepath.ListSeparator))
}
return newEnvVar, nil
}

func removeDuplicate[T comparable](s []T) []T {
all := make(map[T]bool)

var list []T
for _, item := range s {
if _, ok := all[item]; !ok {
all[item] = true
list = append(list, item)
}
}
return list
}

func computeIntegrationConfigToEnvVar(integ sdk.JobIntegrationsContext, prefix string) map[string]string {
envVars := make(map[string]string)
configValues := flatMap(integ.Config)
Expand Down
7 changes: 4 additions & 3 deletions engine/worker/internal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ type CurrentWorker struct {
client cdsclient.WorkerInterface
blur *sdk.Blur
hooks []workerHook
paths []string
}

type workerHook struct {
Expand Down Expand Up @@ -398,7 +399,7 @@ func (wk *CurrentWorker) Environ() []string {
newEnv = append(newEnv, e)
}

newEnv = append(newEnv, "CDS_KEY=********") //We have to let it here for some legacy reason
newEnv = append(newEnv, "CDS_KEY=********") // We have to let it here for some legacy reason
newEnv = append(newEnv, fmt.Sprintf("%s=%d", WorkerServerPort, wk.HTTPPort()))
newEnv = append(newEnv, fmt.Sprintf("%s=%s", CDSApiUrl, wk.cfg.APIEndpoint))
newEnv = append(newEnv, fmt.Sprintf("%s=%s", CDSCDNUrl, wk.cfg.CDNEndpoint))
Expand Down Expand Up @@ -427,7 +428,7 @@ func (wk *CurrentWorker) Environ() []string {
newEnv = append(newEnv, "BASEDIR="+wk.cfg.Basedir)
}

//set up environment variables from pipeline build job parameters
// set up environment variables from pipeline build job parameters
for _, p := range wk.currentJob.params {
// avoid put private key in environment var as it's a binary value
if strings.HasPrefix(p.Name, "cds.key.") && strings.HasSuffix(p.Name, ".priv") {
Expand All @@ -449,7 +450,7 @@ func (wk *CurrentWorker) Environ() []string {
newEnv = append(newEnv, fmt.Sprintf("%s=%s", envName, sdk.OneLineValue(p.Value)))
}

//Set env variables from hooks
// Set env variables from hooks
for k, v := range wk.currentJob.envFromHooks {
newEnv = append(newEnv, k+"="+sdk.OneLineValue(v))
}
Expand Down
12 changes: 10 additions & 2 deletions sdk/v2_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,17 @@ type ActionInput struct {
Default string `json:"default,omitempty" jsonschema_extras:"order=1" jsonschema_description:"Default input value used if the caller do not specified anything"`
}

type ActionOutputType string

const (
ActionOutputTypeDefault ActionOutputType = ""
ActionOutputTypePath = "path"
)

type ActionOutput struct {
Description string `json:"description,omitempty" jsonschema_extras:"order=2"`
Value string `json:"value" jsonschema_extras:"order=1"`
Description string `json:"description,omitempty" jsonschema_extras:"order=2"`
Value string `json:"value" jsonschema_extras:"order=1"`
Type ActionOutputType `json:"type,omitempty" jsonschema_extras:"order=3"`
}

type ActionStep struct {
Expand Down

0 comments on commit e8a6ce3

Please sign in to comment.