@@ -84,7 +84,8 @@ type DeployOptions struct {
8484 BuildDir string
8585 LargeMediaEnabled bool
8686
87- IsDraft bool
87+ IsDraft bool
88+ SkipRetry bool
8889
8990 Title string
9091 Branch string
@@ -350,12 +351,14 @@ func (n *Netlify) DoDeploy(ctx context.Context, options *DeployOptions, deploy *
350351 return deploy , nil
351352 }
352353
353- if err := n .uploadFiles (ctx , deploy , options .files , options .Observer , fileUpload , options .UploadTimeout ); err != nil {
354+ skipRetry := options .SkipRetry
355+
356+ if err := n .uploadFiles (ctx , deploy , options .files , options .Observer , fileUpload , options .UploadTimeout , skipRetry ); err != nil {
354357 return nil , err
355358 }
356359
357360 if options .functions != nil {
358- if err := n .uploadFiles (ctx , deploy , options .functions , options .Observer , functionUpload , options .UploadTimeout ); err != nil {
361+ if err := n .uploadFiles (ctx , deploy , options .functions , options .Observer , functionUpload , options .UploadTimeout , skipRetry ); err != nil {
359362 return nil , err
360363 }
361364 }
@@ -402,12 +405,17 @@ func (n *Netlify) WaitUntilDeployReady(ctx context.Context, d *models.Deploy) (*
402405 return n .waitForState (ctx , d , "prepared" , "ready" )
403406}
404407
405- // WaitUntilDeployLive blocks until the deploy is in the "ready" state. At this point, the deploy is ready to recieve traffic.
408+ // WaitUntilDeployLive blocks until the deploy is in the "ready" state. At this point, the deploy is ready to receive traffic to all of its URLs .
406409func (n * Netlify ) WaitUntilDeployLive (ctx context.Context , d * models.Deploy ) (* models.Deploy , error ) {
407410 return n .waitForState (ctx , d , "ready" )
408411}
409412
410- func (n * Netlify ) uploadFiles (ctx context.Context , d * models.Deploy , files * deployFiles , observer DeployObserver , t uploadType , timeout time.Duration ) error {
413+ // WaitUntilDeployProcessed blocks until the deploy is in the "processed" state. At this point, the deploy is ready to receive traffic via its permalink.
414+ func (n * Netlify ) WaitUntilDeployProcessed (ctx context.Context , d * models.Deploy ) (* models.Deploy , error ) {
415+ return n .waitForState (ctx , d , "processed" )
416+ }
417+
418+ func (n * Netlify ) uploadFiles (ctx context.Context , d * models.Deploy , files * deployFiles , observer DeployObserver , t uploadType , timeout time.Duration , skipRetry bool ) error {
411419 sharedErr := & uploadError {err : nil , mutex : & sync.Mutex {}}
412420 sem := make (chan int , n .uploadLimit )
413421 wg := & sync.WaitGroup {}
@@ -437,7 +445,7 @@ func (n *Netlify) uploadFiles(ctx context.Context, d *models.Deploy, files *depl
437445 select {
438446 case sem <- 1 :
439447 wg .Add (1 )
440- go n .uploadFile (ctx , d , file , observer , t , timeout , wg , sem , sharedErr )
448+ go n .uploadFile (ctx , d , file , observer , t , timeout , wg , sem , sharedErr , skipRetry )
441449 case <- ctx .Done ():
442450 log .Info ("Context terminated, aborting file upload" )
443451 return errors .Wrap (ctx .Err (), "aborted file upload early" )
@@ -457,7 +465,7 @@ func (n *Netlify) uploadFiles(ctx context.Context, d *models.Deploy, files *depl
457465 return sharedErr .err
458466}
459467
460- func (n * Netlify ) uploadFile (ctx context.Context , d * models.Deploy , f * FileBundle , c DeployObserver , t uploadType , timeout time.Duration , wg * sync.WaitGroup , sem chan int , sharedErr * uploadError ) {
468+ func (n * Netlify ) uploadFile (ctx context.Context , d * models.Deploy , f * FileBundle , c DeployObserver , t uploadType , timeout time.Duration , wg * sync.WaitGroup , sem chan int , sharedErr * uploadError , skipRetry bool ) {
461469 defer func () {
462470 wg .Done ()
463471 <- sem
@@ -545,10 +553,16 @@ func (n *Netlify) uploadFile(ctx context.Context, d *models.Deploy, f *FileBundl
545553 context .GetLogger (ctx ).WithError (operationError ).Errorf ("Failed to upload file %v" , f .Name )
546554 apiErr , ok := operationError .(deployApiError )
547555
548- if ok && apiErr .Code () == 401 {
549- sharedErr .mutex .Lock ()
550- sharedErr .err = operationError
551- sharedErr .mutex .Unlock ()
556+ if ok {
557+ if apiErr .Code () == 401 {
558+ sharedErr .mutex .Lock ()
559+ sharedErr .err = operationError
560+ sharedErr .mutex .Unlock ()
561+ }
562+
563+ if skipRetry && (apiErr .Code () == 400 || apiErr .Code () == 422 ) {
564+ operationError = backoff .Permanent (operationError )
565+ }
552566 }
553567 }
554568
@@ -809,11 +823,12 @@ func bundleFromManifest(ctx context.Context, manifestFile *os.File, observer Dep
809823 }
810824 }
811825
812- if function .DisplayName != "" || function .Generator != "" || len (routes ) > 0 {
826+ if function .DisplayName != "" || function .Generator != "" || len (routes ) > 0 || len ( function . BuildData ) > 0 {
813827 functionsConfig [file .Name ] = models.FunctionConfig {
814828 DisplayName : function .DisplayName ,
815829 Generator : function .Generator ,
816830 Routes : routes ,
831+ BuildData : function .BuildData ,
817832 }
818833 }
819834
0 commit comments