| packagejobparser |
| |
| import( |
| "bytes" |
| "fmt" |
| "sort" |
| "strings" |
| |
| "go.yaml.in/yaml/v4" |
| |
| "github.com/nektos/act/pkg/exprparser" |
| "github.com/nektos/act/pkg/model" |
| ) |
| |
| funcParse(content[]byte,options...ParseOption)([]*SingleWorkflow,error){ |
| origin,err:=model.ReadWorkflow(bytes.NewReader(content)) |
| iferr!=nil{ |
| returnnil,fmt.Errorf("model.ReadWorkflow: %w",err) |
| } |
| |
| workflow:=&SingleWorkflow{} |
| iferr:=yaml.Unmarshal(content,workflow);err!=nil{ |
| returnnil,fmt.Errorf("yaml.Unmarshal: %w",err) |
| } |
| |
| pc:=&parseContext{} |
| for_,o:=rangeoptions{ |
| o(pc) |
| } |
| results:=map[string]*JobResult{} |
| forid,job:=rangeorigin.Jobs{ |
| results[id]=&JobResult{ |
| Needs:job.Needs(), |
| Result:pc.jobResults[id], |
| Outputs:nil,// not supported yet |
| } |
| } |
| |
| varret[]*SingleWorkflow |
| ids,jobs,err:=workflow.jobs() |
| iferr!=nil{ |
| returnnil,fmt.Errorf("invalid jobs: %w",err) |
| } |
| |
| evaluator:=NewExpressionEvaluator(exprparser.NewInterpeter(&exprparser.EvaluationEnvironment{Github:pc.gitContext,Vars:pc.vars,Inputs:pc.inputs},exprparser.Config{})) |
| workflow.RunName=evaluator.Interpolate(workflow.RunName) |
| |
| fori,id:=rangeids{ |
| job:=jobs[i] |
| matricxes,err:=getMatrixes(origin.GetJob(id)) |
| iferr!=nil{ |
| returnnil,fmt.Errorf("getMatrixes: %w",err) |
| } |
| for_,matrix:=rangematricxes{ |
| job:=job.Clone() |
| ifjob.Name==""{ |
| job.Name=id |
| } |
| job.Strategy.RawMatrix=encodeMatrix(matrix) |
| evaluator:=NewExpressionEvaluator(NewInterpeter(id,origin.GetJob(id),matrix,pc.gitContext,results,pc.vars,pc.inputs)) |
| job.Name=nameWithMatrix(job.Name,matrix,evaluator) |
| runsOn:=origin.GetJob(id).RunsOn() |
| fori,v:=rangerunsOn{ |
| runsOn[i]=evaluator.Interpolate(v) |
| } |
| job.RawRunsOn=encodeRunsOn(runsOn) |
| swf:=&SingleWorkflow{ |
| Name:workflow.Name, |
| RawOn:workflow.RawOn, |
| Env:workflow.Env, |
| Defaults:workflow.Defaults, |
| RawPermissions:workflow.RawPermissions, |
| RunName:workflow.RunName, |
| } |
| iferr:=swf.SetJob(id,job);err!=nil{ |
| returnnil,fmt.Errorf("SetJob: %w",err) |
| } |
| ret=append(ret,swf) |
| } |
| } |
| returnret,nil |
| } |
| |
| funcWithJobResults(resultsmap[string]string)ParseOption{ |
| returnfunc(c*parseContext){ |
| c.jobResults=results |
| } |
| } |
| |
| funcWithGitContext(context*model.GithubContext)ParseOption{ |
| returnfunc(c*parseContext){ |
| c.gitContext=context |
| } |
| } |
| |
| funcWithVars(varsmap[string]string)ParseOption{ |
| returnfunc(c*parseContext){ |
| c.vars=vars |
| } |
| } |
| |
| funcWithInputs(inputsmap[string]any)ParseOption{ |
| returnfunc(c*parseContext){ |
| c.inputs=inputs |
| } |
| } |
| |
| typeparseContextstruct{ |
| jobResultsmap[string]string |
| gitContext*model.GithubContext |
| varsmap[string]string |
| inputsmap[string]any |
| } |
| |
| typeParseOptionfunc(c*parseContext) |
| |
| funcgetMatrixes(job*model.Job)([]map[string]interface{},error){ |
| ret,err:=job.GetMatrixes() |
| iferr!=nil{ |
| returnnil,fmt.Errorf("GetMatrixes: %w",err) |
| } |
| sort.Slice(ret,func(i,jint)bool{ |
| returnmatrixName(ret[i])<matrixName(ret[j]) |
| }) |
| returnret,nil |
| } |
| |
| funcencodeMatrix(matrixmap[string]interface{})yaml.Node{ |
| iflen(matrix)==0{ |
| returnyaml.Node{} |
| } |
| value:=map[string][]interface{}{} |
| fork,v:=rangematrix{ |
| value[k]=[]interface{}{v} |
| } |
| node:=yaml.Node{} |
| _=node.Encode(value) |
| returnnode |
| } |
| |
| funcencodeRunsOn(runsOn[]string)yaml.Node{ |
| node:=yaml.Node{} |
| iflen(runsOn)==1{ |
| _=node.Encode(runsOn[0]) |
| }else{ |
| _=node.Encode(runsOn) |
| } |
| returnnode |
| } |
| |
| funcnameWithMatrix(namestring,mmap[string]interface{},evaluator*ExpressionEvaluator)string{ |
| iflen(m)==0{ |
| returnname |
| } |
| |
| if!strings.Contains(name,"${{")||!strings.Contains(name,"}}"){ |
| returnname+" "+matrixName(m) |
| } |
| |
| returnevaluator.Interpolate(name) |
| } |
| |
| funcmatrixName(mmap[string]interface{})string{ |
| ks:=make([]string,0,len(m)) |
| fork:=rangem{ |
| ks=append(ks,k) |
| } |
| sort.Strings(ks) |
| vs:=make([]string,0,len(m)) |
| for_,v:=rangeks{ |
| vs=append(vs,fmt.Sprint(m[v])) |
| } |
| |
| returnfmt.Sprintf("(%s)",strings.Join(vs,", ")) |
| } |