@@ -307,38 +307,62 @@ func (pushService *pushService) uploadReleaseAsset(release *github.RepositoryRel
307307 return asset , response , nil
308308}
309309
310- func (pushService * pushService ) createOrUpdateReleaseAsset (release * github.RepositoryRelease , existingAssets []* github.ReleaseAsset , assetPathStat os.FileInfo ) error {
311- for _ , existingAsset := range existingAssets {
312- if existingAsset .GetName () == assetPathStat .Name () {
313- actualSize := int64 (existingAsset .GetSize ())
314- expectedSize := assetPathStat .Size ()
315- if actualSize == expectedSize {
316- return nil
317- } else {
318- log .Warnf ("Removing existing release asset %s because it was only partially-uploaded (had size %d, but should have been %d)..." , existingAsset .GetName (), actualSize , expectedSize )
319- response , err := pushService .githubEnterpriseClient .Repositories .DeleteReleaseAsset (pushService .ctx , pushService .destinationRepositoryOwner , pushService .destinationRepositoryName , existingAsset .GetID ())
320- if err != nil {
321- return githubapiutil .EnrichResponseError (response , err , "Error deleting existing release asset." )
322- }
323- }
324- }
325- }
326- log .Debugf ("Uploading release asset %s..." , assetPathStat .Name ())
310+ func (pushService * pushService ) uploadAsset (release * github.RepositoryRelease , assetPathStat os.FileInfo ) (* github.Response , error ) {
327311 assetFile , err := os .Open (pushService .cacheDirectory .AssetPath (release .GetTagName (), assetPathStat .Name ()))
328312 if err != nil {
329- return errors .Wrap (err , "Error opening release asset." )
313+ return nil , errors .Wrap (err , "Error opening release asset." )
330314 }
331315 defer assetFile .Close ()
332316 progressReader := & ioprogress.Reader {
333317 Reader : assetFile ,
334318 Size : assetPathStat .Size (),
335319 DrawFunc : ioprogress .DrawTerminalf (os .Stderr , ioprogress .DrawTextFormatBytes ),
336320 }
337- _ , response , err := pushService .uploadReleaseAsset (release , assetPathStat , progressReader )
338321 if err != nil {
339- return githubapiutil .EnrichResponseError (response , err , "Error uploading release asset." )
322+ return nil , errors .Wrap (err , "Error opening release asset." )
323+ }
324+ _ , response , err := pushService .uploadReleaseAsset (release , assetPathStat , progressReader )
325+ return response , err
326+ }
327+
328+ func (pushService * pushService ) createOrUpdateReleaseAsset (release * github.RepositoryRelease , existingAssets []* github.ReleaseAsset , assetPathStat os.FileInfo ) error {
329+ attempt := 0
330+ for {
331+ attempt ++
332+ for _ , existingAsset := range existingAssets {
333+ if existingAsset .GetName () == assetPathStat .Name () {
334+ actualSize := int64 (existingAsset .GetSize ())
335+ expectedSize := assetPathStat .Size ()
336+ if actualSize == expectedSize {
337+ return nil
338+ } else {
339+ log .Warnf ("Removing existing release asset %s because it was only partially-uploaded (had size %d, but should have been %d)..." , existingAsset .GetName (), actualSize , expectedSize )
340+ response , err := pushService .githubEnterpriseClient .Repositories .DeleteReleaseAsset (pushService .ctx , pushService .destinationRepositoryOwner , pushService .destinationRepositoryName , existingAsset .GetID ())
341+ if err != nil {
342+ return githubapiutil .EnrichResponseError (response , err , "Error deleting existing release asset." )
343+ }
344+ }
345+ }
346+ }
347+ log .Debugf ("Uploading release asset %s..." , assetPathStat .Name ())
348+ response , err := pushService .uploadAsset (release , assetPathStat )
349+ if err == nil {
350+ return nil
351+ } else {
352+ if githubErrorResponse := new (github.ErrorResponse ); errors .As (err , & githubErrorResponse ) {
353+ for _ , innerError := range githubErrorResponse .Errors {
354+ if innerError .Code == "already_exists" {
355+ log .Warn ("Asset already existed." )
356+ return nil
357+ }
358+ }
359+ }
360+ if response == nil || response .StatusCode < 500 || attempt >= 5 {
361+ return err
362+ }
363+ log .Warnf ("Attempt %d failed to upload release asset (%s), retrying..." , attempt , err .Error ())
364+ }
340365 }
341- return nil
342366}
343367
344368func (pushService * pushService ) pushReleases () error {
0 commit comments