Skip to content

Commit ec091ad

Browse files
Zettat123Lunny Xiao
authored andcommitted
Support concurrency (#124)
To support `concurrency` syntax for Gitea Actions Gitea PR: go-gitea/gitea#32751 Reviewed-on: https://gitea.com/gitea/act/pulls/124 Reviewed-by: Lunny Xiao <[email protected]> Co-authored-by: Zettat123 <[email protected]> Co-committed-by: Zettat123 <[email protected]>
1 parent 1656206 commit ec091ad

File tree

4 files changed

+91
-2
lines changed

4 files changed

+91
-2
lines changed

pkg/jobparser/interpeter.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ func NewInterpeter(
1616
gitCtx *model.GithubContext,
1717
results map[string]*JobResult,
1818
vars map[string]string,
19+
inputs map[string]interface{},
1920
) exprparser.Interpreter {
2021
strategy := make(map[string]interface{})
2122
if job.Strategy != nil {
@@ -62,7 +63,7 @@ func NewInterpeter(
6263
Strategy: strategy,
6364
Matrix: matrix,
6465
Needs: using,
65-
Inputs: nil, // not supported yet
66+
Inputs: inputs,
6667
Vars: vars,
6768
}
6869

pkg/jobparser/jobparser.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func Parse(content []byte, options ...ParseOption) ([]*SingleWorkflow, error) {
5252
job.Name = id
5353
}
5454
job.Strategy.RawMatrix = encodeMatrix(matrix)
55-
evaluator := NewExpressionEvaluator(NewInterpeter(id, origin.GetJob(id), matrix, pc.gitContext, results, pc.vars))
55+
evaluator := NewExpressionEvaluator(NewInterpeter(id, origin.GetJob(id), matrix, pc.gitContext, results, pc.vars, nil))
5656
job.Name = nameWithMatrix(job.Name, matrix, evaluator)
5757
runsOn := origin.GetJob(id).RunsOn()
5858
for i, v := range runsOn {

pkg/jobparser/model.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package jobparser
22

33
import (
4+
"bytes"
45
"fmt"
56

67
"github.com/nektos/act/pkg/model"
@@ -82,6 +83,7 @@ type Job struct {
8283
Uses string `yaml:"uses,omitempty"`
8384
With map[string]interface{} `yaml:"with,omitempty"`
8485
RawSecrets yaml.Node `yaml:"secrets,omitempty"`
86+
RawConcurrency *model.RawConcurrency `yaml:"concurrency,omitempty"`
8587
}
8688

8789
func (j *Job) Clone() *Job {
@@ -104,6 +106,7 @@ func (j *Job) Clone() *Job {
104106
Uses: j.Uses,
105107
With: j.With,
106108
RawSecrets: j.RawSecrets,
109+
RawConcurrency: j.RawConcurrency,
107110
}
108111
}
109112

@@ -241,6 +244,73 @@ func parseWorkflowDispatchInputs(inputs map[string]interface{}) ([]WorkflowDispa
241244
return results, nil
242245
}
243246

247+
func ReadWorkflowRawConcurrency(content []byte) (*model.RawConcurrency, error) {
248+
w := new(model.Workflow)
249+
err := yaml.NewDecoder(bytes.NewReader(content)).Decode(w)
250+
return w.RawConcurrency, err
251+
}
252+
253+
func EvaluateConcurrency(rc *model.RawConcurrency, jobID string, job *Job, gitCtx map[string]any, results map[string]*JobResult, vars map[string]string, inputs map[string]any) (string, bool, error) {
254+
actJob := &model.Job{}
255+
if job != nil {
256+
actJob.Strategy = &model.Strategy{
257+
FailFastString: job.Strategy.FailFastString,
258+
MaxParallelString: job.Strategy.MaxParallelString,
259+
RawMatrix: job.Strategy.RawMatrix,
260+
}
261+
actJob.Strategy.FailFast = actJob.Strategy.GetFailFast()
262+
actJob.Strategy.MaxParallel = actJob.Strategy.GetMaxParallel()
263+
}
264+
265+
matrix := make(map[string]any)
266+
matrixes, err := actJob.GetMatrixes()
267+
if err != nil {
268+
return "", false, err
269+
}
270+
if len(matrixes) > 0 {
271+
matrix = matrixes[0]
272+
}
273+
274+
evaluator := NewExpressionEvaluator(NewInterpeter(jobID, actJob, matrix, toGitContext(gitCtx), results, vars, inputs))
275+
group := evaluator.Interpolate(rc.Group)
276+
cancelInProgress := evaluator.Interpolate(rc.CancelInProgress)
277+
return group, cancelInProgress == "true", nil
278+
}
279+
280+
func toGitContext(input map[string]any) *model.GithubContext {
281+
gitContext := &model.GithubContext{
282+
EventPath: asString(input["event_path"]),
283+
Workflow: asString(input["workflow"]),
284+
RunID: asString(input["run_id"]),
285+
RunNumber: asString(input["run_number"]),
286+
Actor: asString(input["actor"]),
287+
Repository: asString(input["repository"]),
288+
EventName: asString(input["event_name"]),
289+
Sha: asString(input["sha"]),
290+
Ref: asString(input["ref"]),
291+
RefName: asString(input["ref_name"]),
292+
RefType: asString(input["ref_type"]),
293+
HeadRef: asString(input["head_ref"]),
294+
BaseRef: asString(input["base_ref"]),
295+
Token: asString(input["token"]),
296+
Workspace: asString(input["workspace"]),
297+
Action: asString(input["action"]),
298+
ActionPath: asString(input["action_path"]),
299+
ActionRef: asString(input["action_ref"]),
300+
ActionRepository: asString(input["action_repository"]),
301+
Job: asString(input["job"]),
302+
RepositoryOwner: asString(input["repository_owner"]),
303+
RetentionDays: asString(input["retention_days"]),
304+
}
305+
306+
event, ok := input["event"].(map[string]any)
307+
if ok {
308+
gitContext.Event = event
309+
}
310+
311+
return gitContext
312+
}
313+
244314
func ParseRawOn(rawOn *yaml.Node) ([]*Event, error) {
245315
switch rawOn.Kind {
246316
case yaml.ScalarNode:
@@ -422,3 +492,12 @@ func parseMappingNode[T any](node *yaml.Node) ([]string, []T, error) {
422492

423493
return scalars, datas, nil
424494
}
495+
496+
func asString(v interface{}) string {
497+
if v == nil {
498+
return ""
499+
} else if s, ok := v.(string); ok {
500+
return s
501+
}
502+
return ""
503+
}

pkg/model/workflow.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ type Workflow struct {
2323
Env map[string]string `yaml:"env"`
2424
Jobs map[string]*Job `yaml:"jobs"`
2525
Defaults Defaults `yaml:"defaults"`
26+
27+
RawConcurrency *RawConcurrency `yaml:"concurrency"` // For Gitea
2628
}
2729

2830
// On events for the workflow
@@ -769,3 +771,10 @@ func decodeNode(node yaml.Node, out interface{}) bool {
769771
}
770772
return true
771773
}
774+
775+
// For Gitea
776+
// RawConcurrency represents a workflow concurrency or a job concurrency with uninterpolated options
777+
type RawConcurrency struct {
778+
Group string `yaml:"group,omitempty"`
779+
CancelInProgress string `yaml:"cancel-in-progress,omitempty"`
780+
}

0 commit comments

Comments
 (0)