@@ -20,10 +20,12 @@ import (
2020 "context"
2121 "fmt"
2222 "io"
23+ "os"
2324 "strconv"
2425 "time"
2526
2627 "github.com/cenkalti/backoff/v4"
28+ "go.opentelemetry.io/otel/trace"
2729
2830 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/constants"
2931 "github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/event"
@@ -93,34 +95,27 @@ func (r *SkaffoldRunner) doDev(ctx context.Context, out io.Writer) error {
9395 instrumentation .AddDevIteration ("sync" )
9496 meterUpdated = true
9597
96- syncHandler := func (s * sync.Item ) error {
97- fileCount := len (s .Copy ) + len (s .Delete )
98- output .Default .Fprintf (out , "Syncing %d files for %s\n " , fileCount , s .Image )
99- fileSyncInProgress (fileCount , s .Image )
100-
101- if err := r .deployer .GetSyncer ().Sync (childCtx , out , s ); err != nil {
102- log .Entry (ctx ).Warn ("Skipping deploy due to sync error:" , err )
103- fileSyncFailed (fileCount , s .Image , err )
104- event .DevLoopFailedInPhase (r .devIteration , constants .Sync , err )
105- eventV2 .TaskFailed (constants .DevLoop , err )
106- endTrace (instrumentation .TraceEndError (err ))
107-
108- return err
109- }
110-
111- fileSyncSucceeded (fileCount , s .Image )
112-
113- return nil
114- }
98+ syncHandler := r .getSyncHandler (ctx , childCtx , out , endTrace )
11599 for _ , s := range r .changeSet .NeedsResync () {
116100 err := backoff .Retry (
117101 func () error {
118- return syncHandler (s )
102+ err := syncHandler (s )
103+ if err == nil {
104+ return nil
105+ }
106+
107+ // If file doesn't exist (e.g., deleted), stop retrying
108+ if os .IsNotExist (err ) {
109+ return backoff .Permanent (err )
110+ }
111+
112+ return err
119113 }, backoff .WithContext (opts , childCtx ),
120114 )
121115
122116 if err != nil {
123- return nil
117+ log .Entry (ctx ).Warnf ("Sync failed after retries for %s: %v" , s .Image , err )
118+ continue
124119 }
125120 }
126121 endTrace ()
@@ -232,6 +227,32 @@ func (r *SkaffoldRunner) doDev(ctx context.Context, out io.Writer) error {
232227 return nil
233228}
234229
230+ func (r * SkaffoldRunner ) getSyncHandler (
231+ ctx , childCtx context.Context ,
232+ out io.Writer ,
233+ endTrace func (options ... trace.SpanEndOption ),
234+ ) func (s * sync.Item ) error {
235+ return func (s * sync.Item ) error {
236+ fileCount := len (s .Copy ) + len (s .Delete )
237+ output .Default .Fprintf (out , "Syncing %d files for %s\n " , fileCount , s .Image )
238+ fileSyncInProgress (fileCount , s .Image )
239+
240+ if err := r .deployer .GetSyncer ().Sync (childCtx , out , s ); err != nil {
241+ log .Entry (ctx ).Warn ("Skipping deploy due to sync error:" , err )
242+ fileSyncFailed (fileCount , s .Image , err )
243+ event .DevLoopFailedInPhase (r .devIteration , constants .Sync , err )
244+ eventV2 .TaskFailed (constants .DevLoop , err )
245+ endTrace (instrumentation .TraceEndError (err ))
246+
247+ return err
248+ }
249+
250+ fileSyncSucceeded (fileCount , s .Image )
251+
252+ return nil
253+ }
254+ }
255+
235256// Dev watches for changes and runs the skaffold build, test and deploy
236257// config until interrupted by the user.
237258func (r * SkaffoldRunner ) Dev (ctx context.Context , out io.Writer , artifacts []* latest.Artifact ) error {
0 commit comments