@@ -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+ got , err := actions_model .FindTaskOutputByTaskID (ctx , job .TaskID )
182+ if err != nil {
183+ return nil , fmt .Errorf ("FindTaskOutputByTaskID: %w" , err )
184+ }
185+ outputs := make (map [string ]string , len (got ))
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 overridden. 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