-
Notifications
You must be signed in to change notification settings - Fork 15
chore: manager resolves matrix #775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,89 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package workflowmanager | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "fmt" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "workspace-engine/pkg/oapi" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type MatrixResolver struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrix *oapi.WorkflowJobMatrix | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs map[string]any | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type matrixRow struct { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Key string | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Values []map[string]interface{} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func NewMatrixResolver(matrix *oapi.WorkflowJobMatrix, inputs map[string]any) *MatrixResolver { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return &MatrixResolver{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrix: matrix, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputs: inputs, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (r *MatrixResolver) getMatrixRows() ([]matrixRow, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrixRows := make([]matrixRow, 0, len(*r.matrix)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for key, value := range *r.matrix { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| asArray, err := value.AsWorkflowJobMatrix0() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrixRows = append(matrixRows, matrixRow{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Key: key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Values: asArray, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| asString, err := value.AsWorkflowJobMatrix1() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err == nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| arrayFromInput, ok := r.inputs[asString].([]map[string]interface{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if !ok { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("input %s is not an array", asString) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrixRows = append(matrixRows, matrixRow{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Key: key, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Values: arrayFromInput, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return matrixRows, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+49
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle JSON-decoded input arrays when matrix references inputs. 🔧 Suggested conversion to support JSON-decoded arrays asString, err := value.AsWorkflowJobMatrix1()
if err == nil {
- arrayFromInput, ok := r.inputs[asString].([]map[string]interface{})
- if !ok {
- return nil, fmt.Errorf("input %s is not an array", asString)
- }
+ raw, ok := r.inputs[asString]
+ if !ok {
+ return nil, fmt.Errorf("input %s not found", asString)
+ }
+ var arrayFromInput []map[string]interface{}
+ switch v := raw.(type) {
+ case []map[string]interface{}:
+ arrayFromInput = v
+ case []interface{}:
+ arrayFromInput = make([]map[string]interface{}, 0, len(v))
+ for _, item := range v {
+ m, ok := item.(map[string]interface{})
+ if !ok {
+ return nil, fmt.Errorf("input %s contains non-object item", asString)
+ }
+ arrayFromInput = append(arrayFromInput, m)
+ }
+ default:
+ return nil, fmt.Errorf("input %s is not an array", asString)
+ }
matrixRows = append(matrixRows, matrixRow{
Key: key,
Values: arrayFromInput,
})
continue
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (r *MatrixResolver) computeCartesianProduct(matrixRows []matrixRow) []map[string]interface{} { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| totalSize := 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, row := range matrixRows { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| totalSize *= len(row.Values) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result := make([]map[string]interface{}, 0, totalSize) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = append(result, map[string]interface{}{}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, row := range matrixRows { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| newResult := make([]map[string]interface{}, 0, totalSize) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, existing := range result { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for _, value := range row.Values { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| combined := make(map[string]interface{}, len(existing)+len(value)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for k, v := range existing { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| combined[k] = v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for k, v := range value { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| combined[k] = v | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| newResult = append(newResult, combined) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = newResult | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return result | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| func (r *MatrixResolver) Resolve() ([]map[string]interface{}, error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matrixRows, err := r.getMatrixRows() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return nil, fmt.Errorf("failed to get matrix rows: %w", err) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| product := r.computeCartesianProduct(matrixRows) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return product, nil | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| package workflowmanager | ||
|
|
||
| import ( | ||
| "context" | ||
| "encoding/json" | ||
| "fmt" | ||
| "maps" | ||
| "workspace-engine/pkg/oapi" | ||
| ) | ||
|
|
||
| func structToMap(v any) (map[string]interface{}, error) { | ||
| data, err := json.Marshal(v) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| var result map[string]interface{} | ||
| if err := json.Unmarshal(data, &result); err != nil { | ||
| return nil, err | ||
| } | ||
| return result, nil | ||
| } | ||
|
|
||
| func (m *Manager) getResources(ctx context.Context, selector *oapi.Selector) []map[string]interface{} { | ||
| resources := m.store.Resources.ForSelector(ctx, selector) | ||
| resourcesSlice := make([]map[string]interface{}, 0, len(resources)) | ||
| for _, resource := range resources { | ||
| entityMap, err := structToMap(resource) | ||
| if err != nil { | ||
| continue | ||
| } | ||
| resourcesSlice = append(resourcesSlice, entityMap) | ||
| } | ||
| return resourcesSlice | ||
| } | ||
|
|
||
| func (m *Manager) getEnvironments(ctx context.Context, selector *oapi.Selector) []map[string]interface{} { | ||
| environments := m.store.Environments.ForSelector(ctx, selector) | ||
| environmentsSlice := make([]map[string]interface{}, 0, len(environments)) | ||
| for _, environment := range environments { | ||
| entityMap, err := structToMap(environment) | ||
| if err != nil { | ||
| continue | ||
| } | ||
| environmentsSlice = append(environmentsSlice, entityMap) | ||
| } | ||
| return environmentsSlice | ||
| } | ||
|
|
||
| func (m *Manager) getDeployments(ctx context.Context, selector *oapi.Selector) []map[string]interface{} { | ||
| deployments := m.store.Deployments.ForSelector(ctx, selector) | ||
| deploymentsSlice := make([]map[string]interface{}, 0, len(deployments)) | ||
| for _, deployment := range deployments { | ||
| entityMap, err := structToMap(deployment) | ||
| if err != nil { | ||
| continue | ||
| } | ||
| deploymentsSlice = append(deploymentsSlice, entityMap) | ||
| } | ||
| return deploymentsSlice | ||
| } | ||
|
|
||
| func (m *Manager) getInputWithResolvedSelectors(ctx context.Context, workflowTemplate *oapi.WorkflowTemplate, inputs map[string]any) (map[string]any, error) { | ||
| inputsClone := maps.Clone(inputs) | ||
|
|
||
| for _, input := range workflowTemplate.Inputs { | ||
| asArray, err := input.AsWorkflowArrayInput() | ||
| if err != nil { | ||
| continue | ||
| } | ||
|
|
||
| asSelectorArray, err := asArray.AsWorkflowSelectorArrayInput() | ||
| if err != nil { | ||
| continue | ||
| } | ||
|
|
||
| sel := asSelectorArray.Selector.Default | ||
|
|
||
| selectorInputEntry, ok := inputsClone[asSelectorArray.Name] | ||
| if ok { | ||
| selectorInputEntryString := selectorInputEntry.(string) | ||
| sel = &oapi.Selector{} | ||
| if err := sel.FromCelSelector(oapi.CelSelector{Cel: selectorInputEntryString}); err != nil { | ||
| return nil, fmt.Errorf("failed to parse selector: %w", err) | ||
| } | ||
| } | ||
|
|
||
| if sel == nil { | ||
| return nil, fmt.Errorf("selector is nil") | ||
| } | ||
|
|
||
| var matchedEntities []map[string]interface{} | ||
|
|
||
| switch asSelectorArray.Selector.EntityType { | ||
| case oapi.WorkflowSelectorArrayInputSelectorEntityTypeResource: | ||
| matchedEntities = m.getResources(ctx, sel) | ||
| case oapi.WorkflowSelectorArrayInputSelectorEntityTypeEnvironment: | ||
| matchedEntities = m.getEnvironments(ctx, sel) | ||
| case oapi.WorkflowSelectorArrayInputSelectorEntityTypeDeployment: | ||
| matchedEntities = m.getDeployments(ctx, sel) | ||
| } | ||
|
|
||
| inputsClone[asSelectorArray.Name] = matchedEntities | ||
| } | ||
|
|
||
| return inputsClone, nil | ||
|
Comment on lines
+62
to
+105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Guard selector input type to avoid runtime panic. 🛠️ Suggested fix for safe selector parsing selectorInputEntry, ok := inputsClone[asSelectorArray.Name]
if ok {
- selectorInputEntryString := selectorInputEntry.(string)
+ selectorInputEntryString, ok := selectorInputEntry.(string)
+ if !ok {
+ return nil, fmt.Errorf("selector input %s must be a string", asSelectorArray.Name)
+ }
sel = &oapi.Selector{}
if err := sel.FromCelSelector(oapi.CelSelector{Cel: selectorInputEntryString}); err != nil {
return nil, fmt.Errorf("failed to parse selector: %w", err)
}
}🧰 Tools🪛 GitHub Actions: Apps / Workspace Engine[error] 80-80: Runtime panic: interface conversion: interface {} is float64, not string at resolve_selectors.go:80 🤖 Prompt for AI Agents |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid partial WorkflowJob persistence on matrix resolution failure.
If matrix resolution fails (Line 55–57), earlier jobs have already been Upserted (Line 61), but the workflow isn’t stored yet—this leaves orphaned jobs. Consider deferring
WorkflowJobs.Upsertuntil all templates resolve, or rolling back on error.💡 Suggested change to defer job persistence
for idx, jobTemplate := range workflowTemplate.Jobs { wfJob := &oapi.WorkflowJob{ Id: uuid.New().String(), WorkflowId: workflow.Id, Index: idx, Ref: jobTemplate.Ref, Config: maps.Clone(jobTemplate.Config), } if jobTemplate.Matrix != nil { resolvedMatrix, err := NewMatrixResolver(jobTemplate.Matrix, inputsWithResolvedSelectors).Resolve() if err != nil { return workflow, fmt.Errorf("failed to resolve matrix: %w", err) } wfJob.ResolvedMatrix = &resolvedMatrix } - m.store.WorkflowJobs.Upsert(ctx, wfJob) workflowJobs = append(workflowJobs, wfJob) } + for _, wfJob := range workflowJobs { + m.store.WorkflowJobs.Upsert(ctx, wfJob) + }🤖 Prompt for AI Agents