diff --git a/internal/push/push.go b/internal/push/push.go index e69139c..9704421 100644 --- a/internal/push/push.go +++ b/internal/push/push.go @@ -307,26 +307,10 @@ func (pushService *pushService) uploadReleaseAsset(release *github.RepositoryRel return asset, response, nil } -func (pushService *pushService) createOrUpdateReleaseAsset(release *github.RepositoryRelease, existingAssets []*github.ReleaseAsset, assetPathStat os.FileInfo) error { - for _, existingAsset := range existingAssets { - if existingAsset.GetName() == assetPathStat.Name() { - actualSize := int64(existingAsset.GetSize()) - expectedSize := assetPathStat.Size() - if actualSize == expectedSize { - return nil - } else { - 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) - response, err := pushService.githubEnterpriseClient.Repositories.DeleteReleaseAsset(pushService.ctx, pushService.destinationRepositoryOwner, pushService.destinationRepositoryName, existingAsset.GetID()) - if err != nil { - return githubapiutil.EnrichResponseError(response, err, "Error deleting existing release asset.") - } - } - } - } - log.Debugf("Uploading release asset %s...", assetPathStat.Name()) +func (pushService *pushService) uploadAsset(release *github.RepositoryRelease, assetPathStat os.FileInfo) (*github.Response, error) { assetFile, err := os.Open(pushService.cacheDirectory.AssetPath(release.GetTagName(), assetPathStat.Name())) if err != nil { - return errors.Wrap(err, "Error opening release asset.") + return nil, errors.Wrap(err, "Error opening release asset.") } defer assetFile.Close() progressReader := &ioprogress.Reader{ @@ -334,11 +318,51 @@ func (pushService *pushService) createOrUpdateReleaseAsset(release *github.Repos Size: assetPathStat.Size(), DrawFunc: ioprogress.DrawTerminalf(os.Stderr, ioprogress.DrawTextFormatBytes), } - _, response, err := pushService.uploadReleaseAsset(release, assetPathStat, progressReader) if err != nil { - return githubapiutil.EnrichResponseError(response, err, "Error uploading release asset.") + return nil, errors.Wrap(err, "Error opening release asset.") + } + _, response, err := pushService.uploadReleaseAsset(release, assetPathStat, progressReader) + return response, err +} + +func (pushService *pushService) createOrUpdateReleaseAsset(release *github.RepositoryRelease, existingAssets []*github.ReleaseAsset, assetPathStat os.FileInfo) error { + attempt := 0 + for { + attempt++ + for _, existingAsset := range existingAssets { + if existingAsset.GetName() == assetPathStat.Name() { + actualSize := int64(existingAsset.GetSize()) + expectedSize := assetPathStat.Size() + if actualSize == expectedSize { + return nil + } else { + 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) + response, err := pushService.githubEnterpriseClient.Repositories.DeleteReleaseAsset(pushService.ctx, pushService.destinationRepositoryOwner, pushService.destinationRepositoryName, existingAsset.GetID()) + if err != nil { + return githubapiutil.EnrichResponseError(response, err, "Error deleting existing release asset.") + } + } + } + } + log.Debugf("Uploading release asset %s...", assetPathStat.Name()) + response, err := pushService.uploadAsset(release, assetPathStat) + if err == nil { + return nil + } else { + if githubErrorResponse := new(github.ErrorResponse); errors.As(err, &githubErrorResponse) { + for _, innerError := range githubErrorResponse.Errors { + if innerError.Code == "already_exists" { + log.Warn("Asset already existed.") + return nil + } + } + } + if response == nil || response.StatusCode < 500 || attempt >= 5 { + return err + } + log.Warnf("Attempt %d failed to upload release asset (%s), retrying...", attempt, err.Error()) + } } - return nil } func (pushService *pushService) pushReleases() error {
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: