feat(release): detect Containerfile for Docker publishing

This commit is contained in:
Virgil 2026-04-02 01:56:18 +00:00
parent 555ac20eb9
commit 5a16139e7a
3 changed files with 35 additions and 17 deletions

View file

@ -6,6 +6,8 @@ import (
"dappco.re/go/core"
"dappco.re/go/core/build/internal/ax"
"dappco.re/go/core/build/pkg/build"
"dappco.re/go/core/io"
coreerr "dappco.re/go/core/log"
)
@ -51,7 +53,7 @@ func (p *DockerPublisher) Name() string {
// err := pub.Publish(ctx, rel, pubCfg, relCfg, false)
func (p *DockerPublisher) Publish(ctx context.Context, release *Release, pubCfg PublisherConfig, relCfg ReleaseConfig, dryRun bool) error {
// Parse Docker-specific config from publisher config
dockerCfg := p.parseConfig(pubCfg, relCfg, release.ProjectDir)
dockerCfg := p.parseConfig(release.FS, pubCfg, relCfg, release.ProjectDir)
// Validate Dockerfile exists
if !release.FS.Exists(dockerCfg.Dockerfile) {
@ -72,14 +74,19 @@ func (p *DockerPublisher) Publish(ctx context.Context, release *Release, pubCfg
}
// parseConfig extracts Docker-specific configuration.
func (p *DockerPublisher) parseConfig(pubCfg PublisherConfig, relCfg ReleaseConfig, projectDir string) DockerConfig {
func (p *DockerPublisher) parseConfig(fs io.Medium, pubCfg PublisherConfig, relCfg ReleaseConfig, projectDir string) DockerConfig {
cfg := DockerConfig{
Registry: "ghcr.io",
Image: "",
Dockerfile: ax.Join(projectDir, "Dockerfile"),
Platforms: []string{"linux/amd64", "linux/arm64"},
Tags: []string{"latest", "{{.Version}}"},
BuildArgs: make(map[string]string),
Registry: "ghcr.io",
Image: "",
Platforms: []string{"linux/amd64", "linux/arm64"},
Tags: []string{"latest", "{{.Version}}"},
BuildArgs: make(map[string]string),
}
if dockerfile := build.ResolveDockerfilePath(fs, projectDir); dockerfile != "" {
cfg.Dockerfile = dockerfile
} else {
cfg.Dockerfile = ax.Join(projectDir, "Dockerfile")
}
// Try to get image from repository config

View file

@ -23,7 +23,7 @@ func TestDocker_DockerPublisherParseConfig_Good(t *testing.T) {
t.Run("uses defaults when no extended config", func(t *testing.T) {
pubCfg := PublisherConfig{Type: "docker"}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "ghcr.io", cfg.Registry)
assert.Equal(t, "owner/repo", cfg.Image)
@ -47,7 +47,7 @@ func TestDocker_DockerPublisherParseConfig_Good(t *testing.T) {
},
}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "docker.io", cfg.Registry)
assert.Equal(t, "myorg/myimage", cfg.Image)
@ -65,10 +65,21 @@ func TestDocker_DockerPublisherParseConfig_Good(t *testing.T) {
},
}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "/absolute/path/Dockerfile", cfg.Dockerfile)
})
t.Run("detects Containerfile when Dockerfile is absent", func(t *testing.T) {
projectDir := t.TempDir()
require.NoError(t, ax.WriteFile(ax.Join(projectDir, "Containerfile"), []byte("FROM alpine\n"), 0o644))
pubCfg := PublisherConfig{Type: "docker"}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(io.Local, pubCfg, relCfg, projectDir)
assert.Equal(t, ax.Join(projectDir, "Containerfile"), cfg.Dockerfile)
})
}
func TestDocker_DockerPublisherResolveTags_Good(t *testing.T) {
@ -259,7 +270,7 @@ func TestDocker_DockerConfigDefaults_Good(t *testing.T) {
pubCfg := PublisherConfig{Type: "docker"}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
// Verify defaults
assert.Equal(t, "ghcr.io", cfg.Registry)
@ -375,7 +386,7 @@ func TestDocker_DockerPublisherParseConfigEdgeCases_Good(t *testing.T) {
},
}
cfg := p.parseConfig(pubCfg, nil, "/project")
cfg := p.parseConfig(io.Local, pubCfg, nil, "/project")
assert.Equal(t, "custom/image", cfg.Image)
assert.Equal(t, "ghcr.io", cfg.Registry)
@ -390,7 +401,7 @@ func TestDocker_DockerPublisherParseConfigEdgeCases_Good(t *testing.T) {
}
relCfg := &mockReleaseConfig{repository: ""}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "fallback/image", cfg.Image)
})
@ -404,7 +415,7 @@ func TestDocker_DockerPublisherParseConfigEdgeCases_Good(t *testing.T) {
}
relCfg := &mockReleaseConfig{repository: "original/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "override/image", cfg.Image)
})
@ -421,7 +432,7 @@ func TestDocker_DockerPublisherParseConfigEdgeCases_Good(t *testing.T) {
}
relCfg := &mockReleaseConfig{repository: "owner/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/project")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/project")
assert.Equal(t, "value", cfg.BuildArgs["STRING_ARG"])
_, exists := cfg.BuildArgs["INT_ARG"]

View file

@ -371,7 +371,7 @@ func TestIntegration_DockerPublisherIntegrationConfigParsing_Good(t *testing.T)
}
relCfg := &mockReleaseConfig{repository: "fallback/repo"}
cfg := p.parseConfig(pubCfg, relCfg, "/myproject")
cfg := p.parseConfig(io.Local, pubCfg, relCfg, "/myproject")
assert.Equal(t, "registry.example.com", cfg.Registry)
assert.Equal(t, "myteam/myservice", cfg.Image)