Repository navigation
Conversation
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟢 APPROVE
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
7266f3c to
c41f97d
Compare
docker-agent
left a comment
There was a problem hiding this comment.
Assessment: 🟡 NEEDS ATTENTION
One medium-severity bug was found in the new internal/publish package.
| if xf == "" { | ||
| continue | ||
| } | ||
| if _, err = os.Stat(service.Extends.File); os.IsNotExist(err) { |
There was a problem hiding this comment.
[medium] os.Stat error on extends file silently ignored when error is not os.IsNotExist
In processFile, when os.Stat(service.Extends.File) returns a non-IsNotExist error (e.g. permission denied, a stale NFS mount, etc.), the error is silently swallowed. Because os.IsNotExist(err) is false, the continue is not taken, and execution falls through to:
hash := fmt.Sprintf("%x.yaml", sha256.Sum256([]byte(xf)))
extFiles[xf] = hash
f, err = transform.ReplaceExtendsFile(f, name, hash)The inaccessible file is treated as a valid local extends resource: its path is registered for upload and rewritten in the YAML — even though it cannot be read. This means the published OCI artifact will reference a layer that either fails to build or silently omits the extends content.
The fix is to add an explicit guard after the IsNotExist branch:
if _, err = os.Stat(service.Extends.File); os.IsNotExist(err) {
// No local file, while we loaded the project successfully: This is actually a remote resource
continue
} else if err != nil {
return nil, fmt.Errorf("checking extends file %s: %w", service.Extends.File, err)
}| Confidence | Score |
|---|---|
| 🟢 strong | 100/100 |
What this PR does, in one sentence
Moves
publishand its YAML-rewriting helpertransformout of the flatpkg/composepackage intointernal/publish(andinternal/publish/transform), behind a smallBackendinterface.Context
publishis a leaf of the engine: it pre-checks what an application would leak, builds the OCI layers and pushes them, and nothing else inpkg/composedepends on it. It still lives in the flat package, where it can reach anything oncomposeService, andpkg/compose/transformis an exported package that onlypublishuses.What the PR brings
internal/publishdeclares what it needs from the engine in seven methods (API client, registry credentials, events, dry-run flag, prompt, image digest resolution and push). The image digest resolution and the push stay inpkg/composeand go through theBackend, since pull and push will be extracted separately.composeServiceimplements that interface and keeps a one-linePublishforwarder, still wrapped in thepublishprogress bracket, so callers do not change.pkg/compose/transformmoves tointernal/publish/transform; this is the "movetransformunderinternal/" item of the public-surface list of the epic. The only exported symbols leaving the/v5API aretransform.ReplaceEnvFileandtransform.ReplaceExtendsFile; no code in the repository other thanpublishimported them.Backend; the real digest resolver stays covered by its own test inpkg/compose). Thepublishe2e tests pass in standalone and plugin modes.Why this is the right next brick
It is a self-contained extraction (about 1000 lines, 7-method
Backend) that does not depend on the other pending moves (images, build, logs, plan): the pull/push parts it uses are reached through theBackendand can move later without touching it.Part of #14396
🤖 Generated with Claude Code