Skip to content

Commit

Permalink
feat(worker): remove action input type (#7189)
Browse files Browse the repository at this point in the history
  • Loading branch information
sguiheux authored Oct 30, 2024
1 parent 98af0f0 commit ff15bbc
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 36 deletions.
43 changes: 31 additions & 12 deletions engine/worker/internal/runV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ func (w *CurrentWorker) computeContextForJob(ctx context.Context) error {
}
ap := sdk.NewActionParser(parserContext, sdk.DefaultFuncs)
for k, e := range w.currentJobV2.runJobContext.Inputs {
interpolatedValue, err := ap.InterpolateToString(ctx, e)
stringInput, ok := e.(string)
if !ok {
w.currentJobV2.runJobContext.Inputs[k] = e
continue
}
interpolatedValue, err := ap.InterpolateToString(ctx, stringInput)
if err != nil {
return sdk.NewErrorFrom(sdk.ErrInvalidData, "unable to interpolate env variabke %s: %v", k, err)
}
Expand Down Expand Up @@ -497,7 +502,7 @@ func (w *CurrentWorker) runActionStep(ctx context.Context, step sdk.ActionStep,
return result, postActionsJob
}

func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionStep, currentStepContext sdk.WorkflowRunJobsContext, parentStepName string, inputWith map[string]string) (sdk.V2WorkflowRunJobResult, *ActionPostJob) {
func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionStep, currentStepContext sdk.WorkflowRunJobsContext, parentStepName string, inputWith map[string]interface{}) (sdk.V2WorkflowRunJobResult, *ActionPostJob) {
name := strings.TrimPrefix(step.Uses, "actions/")
actionRefSplit := strings.Split(name, "@")
actionPath := strings.Split(actionRefSplit[0], "/")
Expand All @@ -507,7 +512,7 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte
}

// Set action inputs
inputs := make(map[string]string)
inputs := make(map[string]interface{})
if len(actionPath) == 1 {
p := w.GetActionPlugin(actionPath[0])
if p == nil {
Expand Down Expand Up @@ -558,7 +563,7 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte
stepPostAction = &ActionPostJob{
ContinueOnError: postActionDefinition.ContinueOnError,
PluginName: postActionDefinition.PluginName,
Inputs: make(map[string]string),
Inputs: make(map[string]interface{}),
}
jsonContext, _ := json.Marshal(actionContext)
// Interpolate post script
Expand All @@ -568,7 +573,12 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte
}
ap := sdk.NewActionParser(mapContexts, sdk.DefaultFuncs)
for k, v := range postActionDefinition.Inputs {
interpolatedValue, err := ap.InterpolateToString(ctx, v)
inputString, ok := v.(string)
if !ok {
stepPostAction.Inputs[k] = v
continue
}
interpolatedValue, err := ap.InterpolateToString(ctx, inputString)
if err != nil {
return w.failJob(ctx, err.Error()), nil
}
Expand Down Expand Up @@ -640,7 +650,7 @@ func (w *CurrentWorker) runJobStepAction(ctx context.Context, step sdk.ActionSte

stepPostAction = &ActionPostJob{
PluginName: "script",
Inputs: map[string]string{"content": interpolatedPost},
Inputs: map[string]interface{}{"content": interpolatedPost},
StepName: parentStepName,
}
}
Expand Down Expand Up @@ -766,13 +776,13 @@ func (w *CurrentWorker) runJobStepScript(ctx context.Context, step sdk.ActionSte
if err != nil {
return w.failJob(ctx, fmt.Sprintf("%v", err))
}
res, _ := w.runPlugin(ctx, "script", map[string]string{
res, _ := w.runPlugin(ctx, "script", map[string]interface{}{
"content": contentString,
}, env)
return res
}

func (w *CurrentWorker) runPlugin(ctx context.Context, pluginName string, opts map[string]string, env map[string]string) (sdk.V2WorkflowRunJobResult, *ActionPostJob) {
func (w *CurrentWorker) runPlugin(ctx context.Context, pluginName string, opts map[string]interface{}, env map[string]string) (sdk.V2WorkflowRunJobResult, *ActionPostJob) {
pluginClient, err := w.pluginFactory.NewClient(ctx, w, plugin.TypeStream, pluginName, plugin.InputManagementStrict, env)
if pluginClient != nil {
defer pluginClient.Close(ctx)
Expand All @@ -781,7 +791,11 @@ func (w *CurrentWorker) runPlugin(ctx context.Context, pluginName string, opts m
return w.failJob(ctx, fmt.Sprintf("%v", err)), nil
}

pluginResult := pluginClient.Run(ctx, opts)
optsString := make(map[string]string)
for k, v := range opts {
optsString[k] = fmt.Sprintf("%v", v)
}
pluginResult := pluginClient.Run(ctx, optsString)

if pluginResult.Status == sdk.StatusFail {
return w.failJob(ctx, pluginResult.Details), nil
Expand Down Expand Up @@ -818,15 +832,15 @@ func (w *CurrentWorker) failJob(ctx context.Context, reason string) sdk.V2Workfl
}

// 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) {
func (w *CurrentWorker) computeContextForAction(ctx context.Context, parentContext sdk.WorkflowRunJobsContext, inputs map[string]interface{}) (*sdk.WorkflowRunJobsContext, error) {
actionContext := sdk.WorkflowRunJobsContext{
WorkflowRunContext: sdk.WorkflowRunContext{
CDS: parentContext.CDS,
Git: parentContext.Git,
Env: map[string]string{},
},
Integrations: parentContext.Integrations,
Inputs: make(map[string]string),
Inputs: make(map[string]interface{}),
}
for k, v := range parentContext.Env {
actionContext.Env[k] = v
Expand All @@ -844,7 +858,12 @@ func (w *CurrentWorker) computeContextForAction(ctx context.Context, parentConte

// Interpolate step inputs and set them in context
for k, e := range inputs {
interpolatedValue, err := ap.InterpolateToString(ctx, e)
stringInput, ok := e.(string)
if !ok {
actionContext.Inputs[k] = e
continue
}
interpolatedValue, err := ap.Interpolate(ctx, stringInput)
if err != nil {
return nil, sdk.NewErrorFrom(sdk.ErrInvalidData, "unable to interpolate inputs %s: %s: %v", k, e, err)
}
Expand Down
2 changes: 1 addition & 1 deletion engine/worker/internal/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,6 @@ func (wk *CurrentWorker) SetSecrets(secrets []sdk.Variable) error {
type ActionPostJob struct {
ContinueOnError bool
PluginName string
Inputs map[string]string
Inputs map[string]interface{}
StepName string
}
63 changes: 53 additions & 10 deletions sdk/action_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -575,21 +575,42 @@ func (a *ActionParser) compare(operands []interface{}, operator string) (bool, e
if len(operands) != 2 {
return false, NewErrorFrom(ErrInvalidData, "cannot compare more or less than 2 operands")
}
operand1, ok := operands[0].(float64)
var operand1, operand2 float64

jsonNum1, ok := operands[0].(json.Number)
if !ok {
operand1Int, ok := operands[0].(int)
operand1, ok = operands[0].(float64)
if !ok {
return false, NewErrorFrom(ErrInvalidData, "%v must be a float or an int, got [%T]", operands[0], operands[0])
operand1Int, ok := operands[0].(int)
if !ok {
return false, NewErrorFrom(ErrInvalidData, "%v must be a float or an int, got [%T]", operands[0], operands[0])
}
operand1 = float64(operand1Int)
}
} else {
var err error
operand1, err = jsonNum1.Float64()
if err != nil {
return false, NewErrorFrom(ErrInvalidData, "unable to cast %s into a float", operands[0])
}
operand1 = float64(operand1Int)
}
operand2, ok := operands[1].(float64)

jsonNum2, ok := operands[1].(json.Number)
if !ok {
operand2Int, ok := operands[1].(int)
operand2, ok = operands[1].(float64)
if !ok {
return false, NewErrorFrom(ErrInvalidData, "%v must be a float or an int, got [%T]", operands[1], operands[1])
operand2Int, ok := operands[1].(int)
if !ok {
return false, NewErrorFrom(ErrInvalidData, "%v must be a float or an int, got [%T]", operands[1], operands[1])
}
operand2 = float64(operand2Int)
}
} else {
var err error
operand2, err = jsonNum2.Float64()
if err != nil {
return false, NewErrorFrom(ErrInvalidData, "unable to cast %s into a float", operands[1])
}
operand2 = float64(operand2Int)
}

switch operator {
Expand All @@ -611,16 +632,38 @@ func (a *ActionParser) equal(operands []interface{}, operator string) (bool, err
return false, NewErrorFrom(ErrInvalidData, "cannot equalize more or less than 2 operands")
}

operand0 := a.getPrimitiveType(operands[0])
operand1 := a.getPrimitiveType(operands[1])

switch operator {
case "==":
return operands[0] == operands[1], nil
return operand0 == operand1, nil
case "!=":
return operands[0] != operands[1], nil
return operand0 != operand1, nil
default:
return false, NewErrorFrom(ErrInvalidData, "unknown equalizer operator %s", operator)
}
}

func (a ActionParser) getPrimitiveType(operand interface{}) interface{} {
switch s := operand.(type) {
case string, bool, float64:
return s
case int64:
return float64(s)
case int:
return float64(s)
case json.Number:
f, err := s.Float64()
if err != nil {
return s.String()
}
return f
default:
return fmt.Sprintf("%v", operand)
}
}

func (a *ActionParser) and(operands []interface{}) (bool, error) {
if len(operands) == 0 {
return false, nil
Expand Down
2 changes: 1 addition & 1 deletion sdk/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ type PluginPost struct {
With PluginPostWith `json:"with,omitempty"`
}

type PluginPostWith map[string]string
type PluginPostWith map[string]interface{}

// Scan plugin inputs.
func (p *PluginInputs) Scan(src interface{}) error {
Expand Down
21 changes: 10 additions & 11 deletions sdk/v2_action.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,14 @@ type ActionRuns struct {
}

type ActionInput struct {
Description string `json:"description,omitempty" jsonschema_extras:"order=2"`
Default string `json:"default,omitempty" jsonschema_extras:"order=1" jsonschema_description:"Default input value used if the caller do not specified anything"`
Description string `json:"description,omitempty" jsonschema_extras:"order=3"`
Default interface{} `json:"default,omitempty" jsonschema_extras:"order=2" jsonschema_description:"Default input value used if the caller do not specified anything"`
}

type ActionOutputType string

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

type ActionOutput struct {
Expand All @@ -43,13 +42,13 @@ type ActionOutput struct {
}

type ActionStep struct {
ID string `json:"id,omitempty" jsonschema_extras:"order=2" jsonschema_description:"Identifier of the step"`
Uses string `json:"uses,omitempty" jsonschema:"oneof_required=uses" jsonschema_extras:"order=4,onchange=loadentity,prefix=actions/" jsonschema_description:"Sub action to call"`
Run string `json:"run,omitempty" jsonschema:"oneof_required=run" jsonschema_extras:"order=4,code=true" jsonschema_description:"Script to execute"`
With map[string]string `json:"with,omitempty" jsonschema:"oneof_not_required=run" jsonschema_extras:"order=5,mode=use" jsonschema_description:"Action parameters"`
If string `json:"if,omitempty" jsonschema_extras:"order=1,textarea=true" jsonschema_description:"Condition to execute/skip the step"`
ContinueOnError bool `json:"continue-on-error,omitempty" jsonschema_extras:"order=2" jsonschema_description:"Allow a job to continue when this step fails"`
Env map[string]string `json:"env,omitempty" jsonschema_extras:"order=3,mode=edit" jsonschema_description:"Environment variable available in the step"`
ID string `json:"id,omitempty" jsonschema_extras:"order=2" jsonschema_description:"Identifier of the step"`
Uses string `json:"uses,omitempty" jsonschema:"oneof_required=uses" jsonschema_extras:"order=4,onchange=loadentity,prefix=actions/" jsonschema_description:"Sub action to call"`
Run string `json:"run,omitempty" jsonschema:"oneof_required=run" jsonschema_extras:"order=4,code=true" jsonschema_description:"Script to execute"`
With map[string]interface{} `json:"with,omitempty" jsonschema:"oneof_not_required=run" jsonschema_extras:"order=5,mode=use" jsonschema_description:"Action parameters"`
If string `json:"if,omitempty" jsonschema_extras:"order=1,textarea=true" jsonschema_description:"Condition to execute/skip the step"`
ContinueOnError bool `json:"continue-on-error,omitempty" jsonschema_extras:"order=2" jsonschema_description:"Allow a job to continue when this step fails"`
Env map[string]string `json:"env,omitempty" jsonschema_extras:"order=3,mode=edit" jsonschema_description:"Environment variable available in the step"`
}

type ActionStepUsesWith map[string]string
Expand Down
2 changes: 1 addition & 1 deletion sdk/v2_workflow_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ func (m *WorkflowRunContext) Scan(src interface{}) error {

type WorkflowRunJobsContext struct {
WorkflowRunContext
Inputs map[string]string `json:"inputs,omitempty"`
Inputs map[string]interface{} `json:"inputs,omitempty"`
Jobs JobsResultContext `json:"jobs"`
Needs NeedsContext `json:"needs"`
Steps StepsContext `json:"steps"`
Expand Down

0 comments on commit ff15bbc

Please sign in to comment.