fix(watch): exclude Dockerfile and compose files from initial sync

Signed-off-by: hiroto.toyoda <[email protected]>
This commit is contained in:
hiroto.toyoda
2026-08-24 14:48:22 +02:00
committed by Guillaume Lours
parent f729794270
commit 11d4aadf4f
2 changed files with 36 additions and 1 deletions
+9 -1
View File
@@ -784,11 +784,19 @@ func (s *composeService) initialSync(ctx context.Context, service types.ServiceC
if err != nil {
return err
}
// FIXME .dockerignore
// the Dockerfile and compose files drive the build/orchestration, not the
// application: never copy them into the container on initial sync
dockerFileIgnore, err := watch.NewDockerPatternMatcher("/", []string{"Dockerfile", "*compose*.y*ml"})
if err != nil {
return err
}
ignoreInitialSync := watch.NewCompositeMatcher(
dockerIgnores,
watch.EphemeralPathMatcher(),
dotGitIgnore,
dockerFileIgnore,
triggerIgnore)
pathsToCopy, err := s.initialSyncFiles(service, trigger, ignoreInitialSync)
+27
View File
@@ -241,6 +241,33 @@ func TestInitialSyncFilesRegularFile(t *testing.T) {
}})
}
// initialSync's doc comment promises the Dockerfile and compose files are
// never copied into the container, but a refactor (ed10804e0) dropped the
// matcher enforcing it without replacement — neither the .dockerignore-derived
// matcher nor EphemeralPathMatcher cover this.
func TestInitialSync_ExcludesDockerfileAndComposeFiles(t *testing.T) {
hostDir := t.TempDir()
for _, name := range []string{"Dockerfile", "compose.yaml", "compose.override.yml", "app.go"} {
assert.NilError(t, os.WriteFile(filepath.Join(hostDir, name), []byte("content"), 0o600))
}
syncer := &fakeSyncer{synced: make(chan []*sync.PathMapping, 1)}
err := (&composeService{}).initialSync(t.Context(), types.ServiceConfig{
Name: "svc",
Build: &types.BuildConfig{Context: hostDir},
}, types.Trigger{
Path: hostDir,
Target: "/app",
}, syncer)
assert.NilError(t, err)
paths := <-syncer.synced
assert.DeepEqual(t, paths, []*sync.PathMapping{{
HostPath: filepath.Join(hostDir, "app.go"),
ContainerPath: "/app/app.go",
}})
}
// TestPruneDanglingImagesOnRebuild verifies the post-rebuild prune only
// removes superseded dangling images: a dangling image whose ID matches one
// of the freshly built images must be spared. The lookup used to probe the