diff --git a/pkg/release/release.go b/pkg/release/release.go index 858a80c..83100c9 100644 --- a/pkg/release/release.go +++ b/pkg/release/release.go @@ -272,8 +272,8 @@ func buildArtifacts(ctx context.Context, filesystem io.Medium, cfg *Config, proj // Determine output directory outputDir := ax.Join(projectDir, "dist") - // Get builder (detect project type) - projectType, err := projectdetect.DetectProjectType(filesystem, projectDir) + // Get builder, respecting an explicit build type override when configured. + projectType, err := resolveProjectType(filesystem, projectDir, buildConfig.Build.Type) if err != nil { return nil, coreerr.E("release.buildArtifacts", "failed to detect project type", err) } @@ -346,11 +346,27 @@ func getBuilder(projectType build.ProjectType) (build.Builder, error) { return builders.NewDocsBuilder(), nil case build.ProjectTypeCPP: return builders.NewCPPBuilder(), nil + case build.ProjectTypeDocker: + return builders.NewDockerBuilder(), nil + case build.ProjectTypeLinuxKit: + return builders.NewLinuxKitBuilder(), nil + case build.ProjectTypeTaskfile: + return builders.NewTaskfileBuilder(), nil default: return nil, coreerr.E("release.getBuilder", "unsupported project type: "+string(projectType), nil) } } +// resolveProjectType determines which builder type to use for release builds. +// An explicit build type in .core/build.yaml takes precedence over marker-based detection. +func resolveProjectType(filesystem io.Medium, projectDir, buildType string) (build.ProjectType, error) { + if buildType != "" { + return build.ProjectType(buildType), nil + } + + return projectdetect.DetectProjectType(filesystem, projectDir) +} + // getPublisher returns the publisher for the given type. func getPublisher(publisherType string) (publishers.Publisher, error) { switch publisherType { diff --git a/pkg/release/release_test.go b/pkg/release/release_test.go index 888184c..85393d7 100644 --- a/pkg/release/release_test.go +++ b/pkg/release/release_test.go @@ -220,6 +220,27 @@ func TestRelease_GetBuilder_Good(t *testing.T) { assert.NotNil(t, builder) assert.Equal(t, "cpp", builder.Name()) }) + + t.Run("returns Docker builder for docker project type", func(t *testing.T) { + builder, err := getBuilder(build.ProjectTypeDocker) + require.NoError(t, err) + assert.NotNil(t, builder) + assert.Equal(t, "docker", builder.Name()) + }) + + t.Run("returns LinuxKit builder for linuxkit project type", func(t *testing.T) { + builder, err := getBuilder(build.ProjectTypeLinuxKit) + require.NoError(t, err) + assert.NotNil(t, builder) + assert.Equal(t, "linuxkit", builder.Name()) + }) + + t.Run("returns Taskfile builder for taskfile project type", func(t *testing.T) { + builder, err := getBuilder(build.ProjectTypeTaskfile) + require.NoError(t, err) + assert.NotNil(t, builder) + assert.Equal(t, "taskfile", builder.Name()) + }) } func TestRelease_GetBuilder_Bad(t *testing.T) { @@ -269,6 +290,25 @@ func TestRelease_GetPublisher_Bad(t *testing.T) { }) } +func TestRelease_ResolveProjectType_Good(t *testing.T) { + t.Run("honours explicit build type override", func(t *testing.T) { + dir := t.TempDir() + + projectType, err := resolveProjectType(io.Local, dir, "docker") + require.NoError(t, err) + assert.Equal(t, build.ProjectTypeDocker, projectType) + }) + + t.Run("falls back to marker detection when build type is empty", func(t *testing.T) { + dir := t.TempDir() + require.NoError(t, ax.WriteFile(ax.Join(dir, "go.mod"), []byte("module example.com/test"), 0644)) + + projectType, err := resolveProjectType(io.Local, dir, "") + require.NoError(t, err) + assert.Equal(t, build.ProjectTypeGo, projectType) + }) +} + func TestRelease_BuildExtendedConfig_Good(t *testing.T) { t.Run("returns empty map for minimal config", func(t *testing.T) { cfg := PublisherConfig{