Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion pkg/compose/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This restates the existing doc comment on initialSync a few lines above; consider dropping it or shortening it to just the new detail.

dockerFileIgnore, err := watch.NewDockerPatternMatcher("/", []string{"Dockerfile", "*compose*.y*ml"})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*compose*.y*ml matches any basename containing "compose" plus a .y…ml suffix (e.g. my-compose-notes.yaml, recompose.yml), silently dropping unrelated files from the sync. Consider matching literal names from:
compose-go/v2/cli.DefaultFileNames/DefaultOverrideFileNames.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only excludes the literal Dockerfile, so a custom-named one (build.dockerfile: Dockerfile.prod) still gets copied into the container, the same bug this PR fixes, just for non-default names.
Add service.Build.Dockerfile (nil-checked) to the pattern list.

if err != nil {
return err
}

ignoreInitialSync := watch.NewCompositeMatcher(
dockerIgnores,
watch.EphemeralPathMatcher(),
dotGitIgnore,
dockerFileIgnore,
triggerIgnore)

pathsToCopy, err := s.initialSyncFiles(service, trigger, ignoreInitialSync)
Expand Down
27 changes: 27 additions & 0 deletions pkg/compose/watch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"} {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compose.yaml and compose.override.yml both hit the same glob branch with an empty prefix, so the second file adds no coverage.
Swap it for docker-compose.yml instead, it exercises the wildcard matching a non-empty prefix, which thecurrent fixtures don't test.

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
Expand Down