Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
27 changes: 25 additions & 2 deletions pkg/ci/github/common.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,31 @@
package github

import "fmt"
import (
"fmt"
"slices"

func determineBuilder(runtime string, remote bool) (string, error) {
"knative.dev/func/pkg/builders"
)

func determineBuilder(runtime, builder string, remote bool) (string, error) {
defaultBuilder, err := runtimeDefaultBuilder(runtime, remote)
if err != nil {
return "", err
}
if builder == "" {
return defaultBuilder, nil
}
all := builders.All()
if !slices.Contains(all, builder) {
return "", builders.ErrUnknownBuilder{Name: builder, Known: all}
}
if remote && builder == builders.Host {
return "", fmt.Errorf("builder %q is incompatible with remote builds", builders.Host)
}
return builder, nil
}

func runtimeDefaultBuilder(runtime string, remote bool) (string, error) {
switch runtime {
case "go":
if remote {
Expand Down
13 changes: 9 additions & 4 deletions pkg/ci/github/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,28 @@ func (g *workflowGenerator) Generate(ctx context.Context, f fn.Function) error {
return fmt.Errorf("function root path can not be empty")
}

githubWorkflow, err := newGitHubWorkflow(g.cfg, f.Runtime, g.messageWriter)
cfg := g.cfg
if cfg.Builder == "" {
cfg.Builder = f.Build.Builder
}

githubWorkflow, err := newGitHubWorkflow(cfg, f.Runtime, g.messageWriter)
if err != nil {
return err
}

if err := githubWorkflow.Export(g.cfg.fnGitHubWorkflowFilepath(f.Root), g.workflowWriter, g.cfg.Force, g.messageWriter); err != nil {
if err := githubWorkflow.Export(cfg.fnGitHubWorkflowFilepath(f.Root), g.workflowWriter, cfg.Force, g.messageWriter); err != nil {
return err
}

if g.verbose {
// best-effort user message; errors are non-critical
_ = PrintConfiguration(g.cfg, f.Runtime, g.messageWriter)
_ = PrintConfiguration(cfg, f.Runtime, g.messageWriter)
return nil
}

// best-effort user message; errors are non-critical
_ = PrintPostExportMessage(g.cfg, g.messageWriter)
_ = PrintPostExportMessage(cfg, g.messageWriter)
return nil
}

Expand Down
94 changes: 94 additions & 0 deletions pkg/ci/github/generator_test.go
Comment thread
pmeida marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"gotest.tools/v3/assert"
"gotest.tools/v3/assert/cmp"
"knative.dev/func/pkg/builders"
"knative.dev/func/pkg/ci/github"
fn "knative.dev/func/pkg/functions"
)
Expand Down Expand Up @@ -518,6 +519,74 @@ func TestCIGenerator_BuilderForRuntime(t *testing.T) {
}
}

func TestCIGenerator_BuilderConfiguredInFuncYaml(t *testing.T) {
testCases := []struct {
name string
runtime string
builder string
}{
{
name: "node function with s2i builder configured",
runtime: "node",
builder: "s2i",
},
{
name: "python function with pack builder configured",
runtime: "python",
builder: "pack",
},
{
name: "quarkus function with s2i builder configured",
runtime: "quarkus",
builder: "s2i",
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// GIVEN
opts := defaultOpts()
opts.goFn.Runtime = tc.runtime
opts.goFn.Build.Builder = tc.builder

// WHEN
result := runGenerateWorkflow(t, opts)

// THEN
assert.NilError(t, result.executeErr)
assert.Assert(t, strings.Contains(result.gwYamlString, "FUNC_BUILDER: "+tc.builder))
})
}
}

func TestCIGenerator_WorkflowConfigBuilderTakesPriorityOverFuncYaml(t *testing.T) {
// GIVEN
opts := defaultOpts()
opts.goFn.Runtime = "node"
opts.goFn.Build.Builder = "s2i"
opts.cfg.Builder = "pack"

// WHEN
result := runGenerateWorkflow(t, opts)

// THEN
assert.NilError(t, result.executeErr)
assert.Assert(t, strings.Contains(result.gwYamlString, "FUNC_BUILDER: "+opts.cfg.Builder))
}

func TestCIGenerator_HostBuilderWithRemoteErrors(t *testing.T) {
// GIVEN
opts := defaultOpts()
opts.cfg.Builder = builders.Host
opts.cfg.RemoteBuild = true

// WHEN
result := runGenerateWorkflow(t, opts)

// THEN
assert.Error(t, result.executeErr, `builder "host" is incompatible with remote builds`)
}

func TestCIGenerator_BuilderForRuntimeError(t *testing.T) {
// GIVEN
opts := defaultOpts()
Expand All @@ -530,6 +599,31 @@ func TestCIGenerator_BuilderForRuntimeError(t *testing.T) {
assert.Error(t, result.executeErr, "no builder support for runtime: zig")
}

func TestCIGenerator_UnsupportedRuntimeErrorsEvenWithExplicitBuilder(t *testing.T) {
// GIVEN
opts := defaultOpts()
opts.goFn.Runtime = "zig"
opts.goFn.Build.Builder = "pack"

// WHEN
result := runGenerateWorkflow(t, opts)

// THEN
assert.Error(t, result.executeErr, "no builder support for runtime: zig")
}

func TestCIGenerator_InvalidBuilderErrors(t *testing.T) {
// GIVEN
opts := defaultOpts()
opts.goFn.Build.Builder = "pakc"

// WHEN
result := runGenerateWorkflow(t, opts)

// THEN
assert.Error(t, result.executeErr, `"pakc" is not a known builder. Available builders are "host", "pack" and "s2i"`)
}

// ---------------------
// END: Broad Unit Tests

Expand Down
2 changes: 1 addition & 1 deletion pkg/ci/github/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Create the following Secret on github.com: %s
)

func PrintConfiguration(cfg WorkflowConfig, runtime string, w io.Writer) error {
builder, err := determineBuilder(runtime, cfg.RemoteBuild)
builder, err := determineBuilder(runtime, cfg.Builder, cfg.RemoteBuild)
if err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/ci/github/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ type WorkflowConfig struct {
RegistryUserVar,
RegistryPassSecret,
RegistryUrlVar,
FuncCliVersion string
FuncCliVersion,
Builder string
RegistryLogin,
SelfHostedRunner,
RemoteBuild,
Expand Down Expand Up @@ -241,7 +242,7 @@ func createFuncDeployStep(opts WorkflowConfig, runtime string, steps []step) ([]
deployFuncStep := newStep("Deploy function").
withEnv("FUNC_VERBOSE", "true")

builder, err := determineBuilder(runtime, opts.RemoteBuild)
builder, err := determineBuilder(runtime, opts.Builder, opts.RemoteBuild)
if err != nil {
return nil, err
}
Expand Down
Loading