Skip to content

Commit e75907f

Browse files
committed
merge outputs
1 parent 30008fc commit e75907f

File tree

2 files changed

+46
-18
lines changed

2 files changed

+46
-18
lines changed

models/actions/run_job.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
137137
if err != nil {
138138
return 0, err
139139
}
140-
run.Status = aggregateJobStatus(jobs)
140+
run.Status = AggregateJobStatus(jobs)
141141
if run.Started.IsZero() && run.Status.IsRunning() {
142142
run.Started = timeutil.TimeStampNow()
143143
}
@@ -152,7 +152,7 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
152152
return affected, nil
153153
}
154154

155-
func aggregateJobStatus(jobs []*ActionRunJob) Status {
155+
func AggregateJobStatus(jobs []*ActionRunJob) Status {
156156
allDone := true
157157
allWaiting := true
158158
hasFailure := false

routers/api/actions/runner/utils.go

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,28 +162,56 @@ func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str
162162
return nil, fmt.Errorf("FindRunJobs: %w", err)
163163
}
164164

165-
ret := make(map[string]*runnerv1.TaskNeed, len(needs))
165+
jobIDJobs := make(map[string][]*actions_model.ActionRunJob)
166166
for _, job := range jobs {
167-
if !needs.Contains(job.JobID) {
168-
continue
169-
}
170-
if job.TaskID == 0 || !job.Status.IsDone() {
171-
// it shouldn't happen, or the job has been rerun
167+
jobIDJobs[job.JobID] = append(jobIDJobs[job.JobID], job)
168+
}
169+
170+
ret := make(map[string]*runnerv1.TaskNeed, len(needs))
171+
for jobID, jobsWithSameID := range jobIDJobs {
172+
if !needs.Contains(jobID) {
172173
continue
173174
}
174-
outputs := make(map[string]string)
175-
got, err := actions_model.FindTaskOutputByTaskID(ctx, job.TaskID)
176-
if err != nil {
177-
return nil, fmt.Errorf("FindTaskOutputByTaskID: %w", err)
175+
var jobOutputs map[string]string
176+
for _, job := range jobsWithSameID {
177+
if job.TaskID == 0 || !job.Status.IsDone() {
178+
// it shouldn't happen, or the job has been rerun
179+
continue
180+
}
181+
outputs := make(map[string]string)
182+
got, err := actions_model.FindTaskOutputByTaskID(ctx, job.TaskID)
183+
if err != nil {
184+
return nil, fmt.Errorf("FindTaskOutputByTaskID: %w", err)
185+
}
186+
for _, v := range got {
187+
outputs[v.OutputKey] = v.OutputValue
188+
}
189+
if len(jobOutputs) == 0 {
190+
jobOutputs = outputs
191+
} else {
192+
jobOutputs = mergeTwoOutputs(outputs, jobOutputs)
193+
}
178194
}
179-
for _, v := range got {
180-
outputs[v.OutputKey] = v.OutputValue
181-
}
182-
ret[job.JobID] = &runnerv1.TaskNeed{
183-
Outputs: outputs,
184-
Result: runnerv1.Result(job.Status),
195+
ret[jobID] = &runnerv1.TaskNeed{
196+
Outputs: jobOutputs,
197+
Result: runnerv1.Result(actions_model.AggregateJobStatus(jobsWithSameID)),
185198
}
186199
}
187200

188201
return ret, nil
189202
}
203+
204+
// mergeTwoOutputs merges two outputs from two different ActionRunJobs
205+
// Values with the same output name may be overriden. The user should ensure the output names are unique.
206+
// See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#using-job-outputs-in-a-matrix-job
207+
func mergeTwoOutputs(o1, o2 map[string]string) map[string]string {
208+
ret := make(map[string]string, len(o1))
209+
for k1, v1 := range o1 {
210+
if len(v1) > 0 {
211+
ret[k1] = v1
212+
} else {
213+
ret[k1] = o2[k1]
214+
}
215+
}
216+
return ret
217+
}

0 commit comments

Comments
 (0)