@@ -79,11 +79,11 @@ func SyncToR2(ctx context.Context, cfg config.R2Config, buildDir, buildID, previ
7979 return fmt .Errorf ("walking build files: %w" , err )
8080 }
8181
82- // Check if the current R2 root already uses the shared p/ prefix layout.
83- // If not (first deploy after upgrade from old release-prefixed layout),
84- // we must upload all shared files — they don't exist at the top level yet.
82+ // Check if the current R2 root already uses the shared layout.
83+ // If not, we must upload all files — they don't exist at the top level yet.
8584 previousShared := collectSharedFiles (previousBuildDir )
86- if len (previousShared ) > 0 {
85+ skipUnchangedP2 := previousBuildDir != ""
86+ if previousBuildDir != "" {
8787 live , err := fetchLiveRelease (ctx , client , cfg .Bucket )
8888 if err != nil {
8989 return fmt .Errorf ("checking R2 layout: %w" , err )
@@ -92,6 +92,10 @@ func SyncToR2(ctx context.Context, cfg config.R2Config, buildDir, buildID, previ
9292 logger .Info ("R2 sync: shared p/ prefix not yet on R2, uploading all shared files" )
9393 previousShared = nil
9494 }
95+ if ! live .hasSharedP2 {
96+ logger .Info ("R2 sync: shared p2/ prefix not yet on R2, uploading all p2/ files" )
97+ skipUnchangedP2 = false
98+ }
9599 }
96100
97101 sortBuildFiles2 (filePaths )
@@ -126,8 +130,9 @@ func SyncToR2(ctx context.Context, cfg config.R2Config, buildDir, buildID, previ
126130 return fmt .Errorf ("R2 sync: %w" , err )
127131 }
128132 } else if strings .HasPrefix (relPath , "p2/" ) {
129- // Mutable p2/ file — skip if unchanged from previous build.
130- if fileUnchanged (previousBuildDir , buildDir , relPath ) {
133+ // Mutable p2/ file — skip if unchanged from previous build
134+ // and p2/ files already exist at top level on R2.
135+ if skipUnchangedP2 && fileUnchanged (previousBuildDir , buildDir , relPath ) {
131136 skipped .Add (1 )
132137 return nil
133138 }
@@ -464,6 +469,9 @@ type liveReleaseResult struct {
464469 // prefix (new layout). False means the old layout where p/ files lived under
465470 // releases/<id>/p/... — shared files have not been uploaded to the top level yet.
466471 hasSharedPrefix bool
472+ // hasSharedP2 is true when metadata-url points at the shared top-level p2/
473+ // prefix. False means p2/ files still live under releases/<id>/p2/.
474+ hasSharedP2 bool
467475 // exists is true when a root packages.json was found on R2.
468476 exists bool
469477}
@@ -518,6 +526,14 @@ func fetchLiveRelease(ctx context.Context, client r2API, bucket string) (liveRel
518526 result .hasSharedPrefix = ! strings .HasPrefix (pu , "releases/" )
519527 }
520528
529+ // Detect whether p2/ files are at the shared top-level prefix.
530+ // Old layout: metadata-url = "/releases/<id>/p2/%package%.json"
531+ // New layout: metadata-url = "/p2/%package%.json"
532+ if mu , ok := pkg ["metadata-url" ].(string ); ok {
533+ mu = strings .TrimPrefix (mu , "/" )
534+ result .hasSharedP2 = ! strings .HasPrefix (mu , "releases/" )
535+ }
536+
521537 return result , nil
522538}
523539
0 commit comments