|
|
@ -7,12 +7,14 @@ import ( |
|
|
|
"context" |
|
|
|
"context" |
|
|
|
"errors" |
|
|
|
"errors" |
|
|
|
"fmt" |
|
|
|
"fmt" |
|
|
|
|
|
|
|
"strings" |
|
|
|
|
|
|
|
|
|
|
|
actions_model "code.gitea.io/gitea/models/actions" |
|
|
|
actions_model "code.gitea.io/gitea/models/actions" |
|
|
|
"code.gitea.io/gitea/models/db" |
|
|
|
"code.gitea.io/gitea/models/db" |
|
|
|
"code.gitea.io/gitea/modules/graceful" |
|
|
|
"code.gitea.io/gitea/modules/graceful" |
|
|
|
"code.gitea.io/gitea/modules/queue" |
|
|
|
"code.gitea.io/gitea/modules/queue" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/nektos/act/pkg/jobparser" |
|
|
|
"xorm.io/builder" |
|
|
|
"xorm.io/builder" |
|
|
|
) |
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
@ -76,12 +78,15 @@ func checkJobsOfRun(ctx context.Context, runID int64) error { |
|
|
|
type jobStatusResolver struct { |
|
|
|
type jobStatusResolver struct { |
|
|
|
statuses map[int64]actions_model.Status |
|
|
|
statuses map[int64]actions_model.Status |
|
|
|
needs map[int64][]int64 |
|
|
|
needs map[int64][]int64 |
|
|
|
|
|
|
|
jobMap map[int64]*actions_model.ActionRunJob |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func newJobStatusResolver(jobs actions_model.ActionJobList) *jobStatusResolver { |
|
|
|
func newJobStatusResolver(jobs actions_model.ActionJobList) *jobStatusResolver { |
|
|
|
idToJobs := make(map[string][]*actions_model.ActionRunJob, len(jobs)) |
|
|
|
idToJobs := make(map[string][]*actions_model.ActionRunJob, len(jobs)) |
|
|
|
|
|
|
|
jobMap := make(map[int64]*actions_model.ActionRunJob) |
|
|
|
for _, job := range jobs { |
|
|
|
for _, job := range jobs { |
|
|
|
idToJobs[job.JobID] = append(idToJobs[job.JobID], job) |
|
|
|
idToJobs[job.JobID] = append(idToJobs[job.JobID], job) |
|
|
|
|
|
|
|
jobMap[job.ID] = job |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
statuses := make(map[int64]actions_model.Status, len(jobs)) |
|
|
|
statuses := make(map[int64]actions_model.Status, len(jobs)) |
|
|
@ -97,6 +102,7 @@ func newJobStatusResolver(jobs actions_model.ActionJobList) *jobStatusResolver { |
|
|
|
return &jobStatusResolver{ |
|
|
|
return &jobStatusResolver{ |
|
|
|
statuses: statuses, |
|
|
|
statuses: statuses, |
|
|
|
needs: needs, |
|
|
|
needs: needs, |
|
|
|
|
|
|
|
jobMap: jobMap, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -135,7 +141,20 @@ func (r *jobStatusResolver) resolve() map[int64]actions_model.Status { |
|
|
|
if allSucceed { |
|
|
|
if allSucceed { |
|
|
|
ret[id] = actions_model.StatusWaiting |
|
|
|
ret[id] = actions_model.StatusWaiting |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
ret[id] = actions_model.StatusSkipped |
|
|
|
// If a job's "if" condition is "always()", the job should always run even if some of its dependencies did not succeed.
|
|
|
|
|
|
|
|
// See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idneeds
|
|
|
|
|
|
|
|
always := false |
|
|
|
|
|
|
|
if wfJobs, _ := jobparser.Parse(r.jobMap[id].WorkflowPayload); len(wfJobs) == 1 { |
|
|
|
|
|
|
|
_, wfJob := wfJobs[0].Job() |
|
|
|
|
|
|
|
expr := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(wfJob.If.Value, "${{"), "}}")) |
|
|
|
|
|
|
|
always = expr == "always()" |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if always { |
|
|
|
|
|
|
|
ret[id] = actions_model.StatusWaiting |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
ret[id] = actions_model.StatusSkipped |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|