@@ -117,28 +117,55 @@ func FindTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[str
117
117
return nil , fmt .Errorf ("FindRunJobs: %w" , err )
118
118
}
119
119
120
- ret := make (map [string ]* TaskNeed , len ( needs ) )
120
+ jobIDJobs := make (map [string ][] * actions_model. ActionRunJob )
121
121
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 ) {
127
128
continue
128
129
}
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
+ }
133
149
}
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 ),
140
153
}
141
154
}
142
-
143
155
return ret , nil
144
156
}
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