mirror of
https://github.com/goreleaser/goreleaser.git
synced 2025-02-03 13:11:48 +02:00
feat(git): retry git clone on retriable error (#4725)
This PR adds retry logic to the process of cloning a git repository. Currently, it retries only if the output of the git clone command contains the string `Connection reset`. Probably, there are more cases where retry is reasonable, but I'm not sure what they are. The number of retries is hardcoded to 10 with increasing delay between retries — in the same way as it is done in #4265, which served me as an example. The initial use case is described in #4724.
This commit is contained in:
parent
a00bf7e5d6
commit
ec7106fdea
@ -8,6 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/caarlos0/log"
|
||||
"github.com/charmbracelet/x/exp/ordered"
|
||||
@ -85,10 +86,8 @@ func (g *gitClient) CreateFiles(
|
||||
return fmt.Errorf("git: failed to create parent: %w", err)
|
||||
}
|
||||
|
||||
if err := runGitCmds(ctx, parent, env, [][]string{
|
||||
{"clone", url, name},
|
||||
}); err != nil {
|
||||
return fmt.Errorf("git: failed to clone local repository: %w", err)
|
||||
if err := cloneRepoWithRetries(ctx, parent, url, name, env); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := runGitCmds(ctx, cwd, env, [][]string{
|
||||
@ -200,6 +199,31 @@ func isPasswordError(err error) bool {
|
||||
return errors.As(err, &kerr)
|
||||
}
|
||||
|
||||
func cloneRepoWithRetries(ctx *context.Context, parent, url, name string, env []string) error {
|
||||
var try int
|
||||
for try < 10 {
|
||||
try++
|
||||
err := runGitCmds(ctx, parent, env, [][]string{{"clone", url, name}})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if isRetriableCloneError(err) {
|
||||
log.WithField("try", try).
|
||||
WithField("image", name).
|
||||
WithError(err).
|
||||
Warnf("failed to push image, will retry")
|
||||
time.Sleep(time.Duration(try*10) * time.Second)
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("failed to clone local repository: %w", err)
|
||||
}
|
||||
return fmt.Errorf("failed to push %s after %d tries", name, try)
|
||||
}
|
||||
|
||||
func isRetriableCloneError(err error) bool {
|
||||
return strings.Contains(err.Error(), "Connection reset")
|
||||
}
|
||||
|
||||
func runGitCmds(ctx *context.Context, cwd string, env []string, cmds [][]string) error {
|
||||
for _, cmd := range cmds {
|
||||
args := append([]string{"-C", cwd}, cmd...)
|
||||
|
Loading…
x
Reference in New Issue
Block a user