@@ -117,28 +117,55 @@ func FindTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str
117117 return nil , fmt .Errorf ("FindRunJobs: %w" , err )
118118 }
119119
120- ret := make (map [string ]* TaskNeed , len ( needs ) )
120+ jobIDJobs := make (map [string ][] * actions_model. ActionRunJob )
121121 for _ , job := range jobs {
122- if ! needs .Contains (job .JobID ) {
123- continue
124- }
125- if job .TaskID == 0 || ! job .Status .IsDone () {
126- // it shouldn't happen, or the job has been rerun
122+ jobIDJobs [job .JobID ] = append (jobIDJobs [job .JobID ], job )
123+ }
124+
125+ ret := make (map [string ]* TaskNeed , len (needs ))
126+ for jobID , jobsWithSameID := range jobIDJobs {
127+ if ! needs .Contains (jobID ) {
127128 continue
128129 }
129- outputs := make (map [string ]string )
130- got , err := actions_model .FindTaskOutputByTaskID (ctx , job .TaskID )
131- if err != nil {
132- return nil , fmt .Errorf ("FindTaskOutputByTaskID: %w" , err )
130+ var jobOutputs map [string ]string
131+ for _ , job := range jobsWithSameID {
132+ if job .TaskID == 0 || ! job .Status .IsDone () {
133+ // it shouldn't happen, or the job has been rerun
134+ continue
135+ }
136+ got , err := actions_model .FindTaskOutputByTaskID (ctx , job .TaskID )
137+ if err != nil {
138+ return nil , fmt .Errorf ("FindTaskOutputByTaskID: %w" , err )
139+ }
140+ outputs := make (map [string ]string , len (got ))
141+ for _ , v := range got {
142+ outputs [v .OutputKey ] = v .OutputValue
143+ }
144+ if len (jobOutputs ) == 0 {
145+ jobOutputs = outputs
146+ } else {
147+ jobOutputs = mergeTwoOutputs (outputs , jobOutputs )
148+ }
133149 }
134- for _ , v := range got {
135- outputs [v .OutputKey ] = v .OutputValue
136- }
137- ret [job .JobID ] = & TaskNeed {
138- Outputs : outputs ,
139- Result : job .Status ,
150+ ret [jobID ] = & TaskNeed {
151+ Outputs : jobOutputs ,
152+ Result : actions_model .AggregateJobStatus (jobsWithSameID ),
140153 }
141154 }
142-
143155 return ret , nil
144156}
157+
158+ // mergeTwoOutputs merges two outputs from two different ActionRunJobs
159+ // Values with the same output name may be overridden. The user should ensure the output names are unique.
160+ // See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#using-job-outputs-in-a-matrix-job
161+ func mergeTwoOutputs (o1 , o2 map [string ]string ) map [string ]string {
162+ ret := make (map [string ]string , len (o1 ))
163+ for k1 , v1 := range o1 {
164+ if len (v1 ) > 0 {
165+ ret [k1 ] = v1
166+ } else {
167+ ret [k1 ] = o2 [k1 ]
168+ }
169+ }
170+ return ret
171+ }
0 commit comments