@@ -15,6 +15,8 @@ import (
15
15
16
16
"github.com/sirupsen/logrus"
17
17
18
+ "k8s.io/apimachinery/pkg/util/sets"
19
+
18
20
"github.com/openshift/ci-tools/pkg/api"
19
21
"github.com/openshift/ci-tools/pkg/config"
20
22
"github.com/openshift/ci-tools/pkg/promotion"
@@ -77,6 +79,8 @@ func (f *censoringFormatter) Format(entry *logrus.Entry) ([]byte, error) {
77
79
return f .delegate .Format (entry )
78
80
}
79
81
82
+ type gitCmd func (l * logrus.Entry , args ... string ) error
83
+
80
84
func main () {
81
85
o := gatherOptions ()
82
86
if err := o .Validate (); err != nil {
@@ -107,7 +111,16 @@ func main() {
107
111
}
108
112
}
109
113
110
- failed := false
114
+ brachingFailure := false
115
+ failedConfigs := sets .New [string ]()
116
+ appendFailedConfig := func (c * api.ReleaseBuildConfiguration ) {
117
+ configInfo := fmt .Sprintf ("%s/%s@%s" , c .Metadata .Org , c .Metadata .Repo , c .Metadata .Branch )
118
+ if c .Metadata .Variant != "" {
119
+ configInfo += "__" + c .Metadata .Variant
120
+ }
121
+ failedConfigs .Insert (configInfo )
122
+ }
123
+
111
124
if err := o .OperateOnCIOperatorConfigDir (o .ConfigDir , api .WithoutOKD , func (configuration * api.ReleaseBuildConfiguration , repoInfo * config.Info ) error {
112
125
logger := config .LoggerForInfo (* repoInfo )
113
126
@@ -117,27 +130,29 @@ func main() {
117
130
return nil
118
131
}
119
132
120
- executeGitCmd := executeGitCMDFactory (repoDir )
133
+ gitCmd := gitCmdFunc (repoDir )
121
134
122
135
remote , err := url .Parse (fmt .Sprintf ("https://github.com/%s/%s" , repoInfo .Org , repoInfo .Repo ))
123
136
if err != nil {
124
- logger .WithError (err ).Fatal ("Could not construct remote URL." )
137
+ logger .WithError (err ).Error ("Could not construct remote URL." )
138
+ appendFailedConfig (configuration )
139
+ return err
125
140
}
126
141
if o .Confirm {
127
142
remote .User = url .UserPassword (o .username , token )
128
143
}
129
144
for _ , command := range [][]string {{"init" }, {"fetch" , "--depth" , "1" , remote .String (), repoInfo .Branch }} {
130
- if err := executeGitCmd (logger , command ... ); err != nil {
131
- failed = true
132
- return nil
145
+ if err := gitCmd (logger , command ... ); err != nil {
146
+ appendFailedConfig ( configuration )
147
+ return err
133
148
}
134
149
}
135
150
136
151
for _ , futureRelease := range o .FutureReleases .Strings () {
137
152
futureBranch , err := promotion .DetermineReleaseBranch (o .CurrentRelease , futureRelease , repoInfo .Branch )
138
153
if err != nil {
139
154
logger .WithError (err ).Error ("could not determine release branch" )
140
- failed = true
155
+ appendFailedConfig ( configuration )
141
156
return nil
142
157
}
143
158
if futureBranch == repoInfo .Branch {
@@ -148,8 +163,8 @@ func main() {
148
163
// it is in sync with the current branch that is promoting
149
164
logger := logger .WithField ("future-branch" , futureBranch )
150
165
command := []string {"ls-remote" , remote .String (), fmt .Sprintf ("refs/heads/%s" , futureBranch )}
151
- if err := executeGitCmd (logger , command ... ); err != nil {
152
- failed = true
166
+ if err := gitCmd (logger , command ... ); err != nil {
167
+ appendFailedConfig ( configuration )
153
168
continue
154
169
}
155
170
@@ -158,53 +173,69 @@ func main() {
158
173
continue
159
174
}
160
175
161
- pushBranch := func () (retry bool ) {
162
- command = []string {"push" , remote .String (), fmt .Sprintf ("FETCH_HEAD:refs/heads/%s" , futureBranch )}
163
- logger := logger .WithFields (logrus.Fields {"commands" : fmt .Sprintf ("git %s" , strings .Join (command , " " ))})
164
- if err := executeGitCmd (logger , command ... ); err != nil {
165
- tooShallowErr := strings .Contains (err .Error (), "Updates were rejected because the remote contains work that you do" )
166
- if tooShallowErr {
167
- logger .Warn ("Failed to push, trying a deeper clone..." )
168
- return true
169
- }
170
- failed = true
171
- }
172
- return false
173
- }
174
-
175
- fetchDeeper := func (depth int ) error {
176
- command = []string {"fetch" , "--depth" , strconv .Itoa (depth ), remote .String (), repoInfo .Branch }
177
- if err := executeGitCmd (logger , command ... ); err != nil {
178
- failed = true
179
- return err
176
+ for depth := 1 ; depth < 9 ; depth += 1 {
177
+ retry , err := pushBranch (logger , remote , futureBranch , gitCmd )
178
+ if err != nil {
179
+ logger .WithError (err ).Error ("Failed to push branch" )
180
+ appendFailedConfig (configuration )
181
+ break
180
182
}
181
- return nil
182
- }
183
183
184
- for depth := 1 ; depth < 9 ; depth += 1 {
185
- retry := pushBranch ()
186
184
if ! retry {
187
185
break
188
186
}
189
187
190
188
if depth == 8 && retry {
191
189
logger .Error ("Could not push branch even with retries." )
192
- failed = true
190
+ appendFailedConfig ( configuration )
193
191
break
194
192
}
195
193
196
- if err := fetchDeeper (int (math .Exp2 (float64 (depth )))); err != nil {
197
- break
194
+ if err := fetchDeeper (logger , remote , gitCmd , repoInfo , int (math .Exp2 (float64 (depth )))); err != nil {
195
+ appendFailedConfig (configuration )
196
+ return nil
198
197
}
199
198
}
200
199
}
201
200
return nil
202
- }); err != nil || failed {
203
- logrus .WithError (err ).Fatal ("Could not branch configurations." )
201
+ }); err != nil {
202
+ logrus .WithError (err ).Error ("Could not branch configurations." )
203
+ brachingFailure = true
204
+ }
205
+
206
+ if len (failedConfigs ) > 0 {
207
+ logrus .WithField ("configs" , failedConfigs .UnsortedList ()).Error ("Failed configurations." )
208
+ brachingFailure = true
209
+ }
210
+
211
+ if brachingFailure {
212
+ os .Exit (1 )
213
+ }
214
+ }
215
+
216
+ func pushBranch (logger * logrus.Entry , remote * url.URL , futureBranch string , gitCmd gitCmd ) (bool , error ) {
217
+ command := []string {"push" , remote .String (), fmt .Sprintf ("FETCH_HEAD:refs/heads/%s" , futureBranch )}
218
+ logger = logger .WithFields (logrus.Fields {"commands" : fmt .Sprintf ("git %s" , strings .Join (command , " " ))})
219
+ if err := gitCmd (logger , command ... ); err != nil {
220
+ tooShallowErr := strings .Contains (err .Error (), "Updates were rejected because the remote contains work that you do" )
221
+ if tooShallowErr {
222
+ logger .Warn ("Failed to push, trying a deeper clone..." )
223
+ return true , nil
224
+ }
225
+ return false , err
204
226
}
227
+ return false , nil
228
+ }
229
+
230
+ func fetchDeeper (logger * logrus.Entry , remote * url.URL , gitCmd gitCmd , repoInfo * config.Info , depth int ) error {
231
+ command := []string {"fetch" , "--depth" , strconv .Itoa (depth ), remote .String (), repoInfo .Branch }
232
+ if err := gitCmd (logger , command ... ); err != nil {
233
+ return err
234
+ }
235
+ return nil
205
236
}
206
237
207
- func executeGitCMDFactory (dir string ) func ( l * logrus. Entry , args ... string ) error {
238
+ func gitCmdFunc (dir string ) gitCmd {
208
239
return func (l * logrus.Entry , args ... string ) error {
209
240
l = l .WithField ("commands" , fmt .Sprintf ("git %s" , strings .Join (args , " " )))
210
241
var b []byte
0 commit comments