feat: upgrade dependencies and migrate deprecated APIs to new ones#139
feat: upgrade dependencies and migrate deprecated APIs to new ones#139kezhenxu94 wants to merge 8 commits intomainfrom
Conversation
- Upgrade testcontainers-go from v0.11.1 to v0.40.0 - Upgrade docker/docker from v20.10.7 to v28.5.2 - Upgrade k8s.io/* packages from v0.22.2 to v0.35.1 - Upgrade sigs.k8s.io/kind from v0.27.0 to v0.31.0 - Migrate deprecated LocalDockerCompose API to new ComposeStack API - Replace deprecated types.EventsOptions with events.ListOptions - Replace deprecated types.Container* types with container.* types - Replace deprecated types.Network* types with network.* types - Update RESTMapper.NewShortcutExpander to use warning callback - Add parseComposeFile() to parse compose files directly with yaml.v3 - Add loadEnvFromFile() to load environment variables from files
There was a problem hiding this comment.
Pull request overview
This PR upgrades several core dependencies (testcontainers-go, docker client, Kubernetes libs, kind) and migrates the codebase off deprecated APIs, especially around docker-compose orchestration and Docker SDK type packages.
Changes:
- Migrates deprecated Testcontainers
LocalDockerComposeusage to themodules/composestack API. - Updates Docker SDK usages from deprecated
types.*to newercontainer.*,network.*,events.*, andimage.*packages. - Updates Kubernetes RESTMapper shortcut expander usage to the newer callback-enabled API.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/util/k8s.go | Updates RESTMapper shortcut expander to new signature with warning callback. |
| internal/components/setup/kind.go | Migrates Docker image list/pull to types/image option types. |
| internal/components/setup/compose_provider.go | Updates Docker container/network types and expands wait.StrategyTarget implementation surface. |
| internal/components/setup/compose_listener.go | Updates Docker events options/types and adjusts event message ID access. |
| internal/components/setup/compose.go | Reworks compose startup to use compose module stacks and adds compose/env parsing helpers. |
| internal/components/cleanup/compose.go | Migrates compose cleanup to compose module stack teardown. |
| go.mod | Upgrades module dependencies and adds replace directives for Docker archive compatibility. |
Comments suppressed due to low confidence (1)
internal/components/setup/compose_provider.go:185
inspectContainerduplicates the sameContainerInspectcall added inInspect. To reduce duplication and keep behavior consistent, consider implementinginspectContainerby callingInspect(or remove one of them if only one is needed).
func (c *DockerContainer) inspectContainer(ctx context.Context) (*container.InspectResponse, error) {
inspect, err := c.provider.client.ContainerInspect(ctx, c.ID)
if err != nil {
return nil, err
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| func (c *ComposeContainerListener) Listen(consumer func(container *ComposeContainer)) error { | ||
| containerEvents, errors := c.client.Events(c.ctx, types.EventsOptions{ | ||
| containerEvents, errors := c.client.Events(c.ctx, events.ListOptions{ | ||
| Filters: filters.NewArgs( | ||
| filters.Arg("type", "container"), | ||
| filters.Arg("event", "start"), |
There was a problem hiding this comment.
client.Events returns channels; downstream handling should not rely on len(errCh) to detect failures and should also handle channel closure (ok checks) to avoid spinning on closed channels. Consider restructuring Listen to propagate the first error deterministically (e.g., via select on errCh) and exit the goroutine when channels close.
| @@ -68,27 +69,43 @@ func ComposeSetup(e2eConfig *config.E2EConfig) error { | |||
| return err | |||
| } | |||
There was a problem hiding this comment.
The Docker client created here is never closed. The Docker SDK client holds underlying HTTP connections; please defer cli.Close() after successful creation (similar to pullImages in kind.go) to avoid leaking resources in long-running processes/tests.
| } | |
| } | |
| defer cli.Close() |
| envVars, err := loadEnvFromFile(profilePath) | ||
| if err != nil { | ||
| return fmt.Errorf("load env file error: %v", err) | ||
| } |
There was a problem hiding this comment.
Same as above: this returns a propagated error but uses %v instead of %w, which prevents callers from unwrapping the underlying error.
| // Compatibility fix for docker/cli which imports github.com/docker/docker/pkg/archive | ||
| // but the package has been moved to github.com/moby/go-archive | ||
| replace github.com/moby/go-archive => github.com/moby/go-archive v0.1.0 | ||
|
|
||
| replace github.com/docker/docker/pkg/archive => github.com/moby/go-archive v0.1.0 |
There was a problem hiding this comment.
This self-replace (replace X => X v...) is effectively a version pin but is non-idiomatic and easy to misread as a no-op. Prefer adding an explicit require github.com/moby/go-archive v0.1.0 (or letting go mod tidy select) and keep replace only for the actual path substitution that’s needed.
| // Listen container create | ||
| listener := NewComposeContainerListener(context.Background(), cli, services) |
There was a problem hiding this comment.
The callback passed to listener.Listen (below) mutates the outer err variable from another goroutine, which is a data race and can overwrite the function’s control-flow error value. Use a local variable inside the callback to handle/log errors without assigning to the outer err.
| composeServices, err := parseComposeFile(composeConfigPath) | ||
| if err != nil { | ||
| return fmt.Errorf("parse compose file error: %v", err) | ||
| } |
There was a problem hiding this comment.
These errors are formatted with %v, which loses wrapping semantics and makes errors.Is/As harder upstream. Prefer %w when returning an error you’re propagating (as done elsewhere in this file for other failures).
| } | ||
|
|
||
| // No networks found | ||
| return "", nil |
There was a problem hiding this comment.
When no networks are found, this returns an empty IP with a nil error. That can lead to confusing downstream failures (treating "" as a valid IP). Prefer returning a non-nil error when the container has no network/IP information available.
| return "", nil | |
| return "", fmt.Errorf("container has no network/IP information available") |
| func (c *DockerContainer) Exec(ctx context.Context, cmd []string, options ...exec.ProcessOption) (int, io.Reader, error) { | ||
| cli := c.provider.client | ||
| response, err := cli.ContainerExecCreate(ctx, c.ID, types.ExecConfig{ | ||
| Cmd: cmd, | ||
| Detach: false, | ||
| response, err := cli.ContainerExecCreate(ctx, c.ID, container.ExecOptions{ | ||
| Cmd: cmd, | ||
| Detach: false, |
There was a problem hiding this comment.
Exec accepts options ...exec.ProcessOption and returns an io.Reader, but the implementation currently ignores all options and never attaches to capture stdout/stderr (it later returns a dummy reader). This can break callers/strategies that rely on ProcessOption behavior or output content. Consider applying options to the exec configuration and using ContainerExecAttach (or otherwise documenting/removing the output return).
Summary
LocalDockerComposeAPI to newComposeStackAPItypes.*with newcontainer.*,network.*,events.*,image.*packagesRESTMapper.NewShortcutExpanderto use warning callbackTest plan
go build ./...passesgo test ./...passes