Skip to content
Closed
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
7 changes: 7 additions & 0 deletions cmd/config_ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd
import (
"fmt"
"io"
"regexp"
"strings"

"github.com/ory/viper"
Expand All @@ -11,8 +12,13 @@ import (
"knative.dev/func/cmd/common"
"knative.dev/func/pkg/ci/github"
fn "knative.dev/func/pkg/functions"
"knative.dev/func/pkg/version"
)

// gitDescribeSuffix matches the "-N-gHASH" suffix produced by git describe
// on commits that are not exactly on a release tag.
var gitDescribeSuffix = regexp.MustCompile(`-\d+-g[0-9a-f]+$`)

// ciGeneratorFactory creates a CIGenerator from resolved CLI flag values.
// Using a factory allows tests to capture the resolved config and inject
// a mock generator without running the real implementation.
Expand Down Expand Up @@ -250,6 +256,7 @@ func newConfigAndLoadedFunc(
RegistryUserVar: viper.GetString(registryUserVariableNameFlag),
RegistryPassSecret: viper.GetString(registryPassSecretNameFlag),
RegistryUrlVar: viper.GetString(registryUrlVariableNameFlag),
FuncCliVersion: gitDescribeSuffix.ReplaceAllString(version.Kver, ""),
RegistryLogin: viper.GetBool(registryLoginFlag),
SelfHostedRunner: viper.GetBool(selfHostedRunnerFlag),
RemoteBuild: viper.GetBool(remoteBuildFlag),
Expand Down
2 changes: 1 addition & 1 deletion cmd/config_ci_int_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ func assertDefaultWorkflow(t *testing.T, actualGw string) {

assert.Assert(t, yamlContains(actualGw, "Install func cli"))
assert.Assert(t, yamlContains(actualGw, "functions-dev/action@main"))
assert.Assert(t, yamlContains(actualGw, "version: knative-v1.22.0"))
assert.Assert(t, yamlContains(actualGw, "version: "+github.DefaultFuncCliVersion))
assert.Assert(t, yamlContains(actualGw, "name: func"))

assert.Assert(t, yamlContains(actualGw, "Deploy function"))
Expand Down
24 changes: 22 additions & 2 deletions pkg/ci/github/common.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,28 @@
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}
}
return builder, nil
}

func runtimeDefaultBuilder(runtime string, remote bool) (string, error) {
switch runtime {
case "go":
if remote {
Expand Down
4 changes: 2 additions & 2 deletions pkg/ci/github/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ 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)
githubWorkflow, err := newGitHubWorkflow(g.cfg, f.Runtime, f.Build.Builder, g.messageWriter)
if err != nil {
return err
}
Expand All @@ -89,7 +89,7 @@ func (g *workflowGenerator) Generate(ctx context.Context, f fn.Function) error {

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

Expand Down
70 changes: 68 additions & 2 deletions pkg/ci/github/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,46 @@ 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_BuilderForRuntimeError(t *testing.T) {
// GIVEN
opts := defaultOpts()
Expand All @@ -530,6 +570,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 Expand Up @@ -566,6 +631,7 @@ func defaultOpts() opts {
RegistryUserVar: github.DefaultRegistryUserVariableName,
RegistryPassSecret: github.DefaultRegistryPassSecretName,
RegistryUrlVar: github.DefaultRegistryUrlVariableName,
FuncCliVersion: github.DefaultFuncCliVersion,
RegistryLogin: github.DefaultRegistryLogin,
SelfHostedRunner: github.DefaultSelfHostedRunner,
RemoteBuild: github.DefaultRemoteBuild,
Expand Down Expand Up @@ -643,7 +709,7 @@ func assertDefaultWorkflow(t *testing.T, actualGw string) {

assert.Assert(t, yamlContains(actualGw, "Install func cli"))
assert.Assert(t, yamlContains(actualGw, "functions-dev/action@main"))
assert.Assert(t, yamlContains(actualGw, "version: knative-v1.22.0"))
assert.Assert(t, yamlContains(actualGw, "version: "+github.DefaultFuncCliVersion))
assert.Assert(t, yamlContains(actualGw, "name: func"))

assert.Assert(t, yamlContains(actualGw, "Deploy function"))
Expand Down Expand Up @@ -676,7 +742,7 @@ func assertSemiDefaultWorkflow(t *testing.T, actualGw string) {

assert.Assert(t, yamlContains(actualGw, "Install func cli"))
assert.Assert(t, yamlContains(actualGw, "functions-dev/action@main"))
assert.Assert(t, yamlContains(actualGw, "version: knative-v1.22.0"))
assert.Assert(t, yamlContains(actualGw, "version: "+github.DefaultFuncCliVersion))
assert.Assert(t, yamlContains(actualGw, "name: func"))

assert.Assert(t, yamlContains(actualGw, "Deploy function"))
Expand Down
4 changes: 2 additions & 2 deletions pkg/ci/github/printer.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Create the following Secret on github.com: %s
`
)

func PrintConfiguration(cfg WorkflowConfig, runtime string, w io.Writer) error {
builder, err := determineBuilder(runtime, cfg.RemoteBuild)
func PrintConfiguration(cfg WorkflowConfig, runtime, builder string, w io.Writer) error {
builder, err := determineBuilder(runtime, builder, cfg.RemoteBuild)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/ci/github/printer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func TestPrintConfigurationFail(t *testing.T) {
t.Run("main layout write fails", func(t *testing.T) {
w := &failWriter{failOnCall: 1, err: errWrite}

err := PrintConfiguration(WorkflowConfig{}, "go", w)
err := PrintConfiguration(WorkflowConfig{}, "go", "", w)

assert.Error(t, err, errWrite.Error())
})
Expand All @@ -38,7 +38,7 @@ func TestPrintConfigurationFail(t *testing.T) {
w := &failWriter{failOnCall: 2, err: errWrite}
opts := WorkflowConfig{RegistryLogin: true}

err := PrintConfiguration(opts, "go", w)
err := PrintConfiguration(opts, "go", "", w)

assert.Error(t, err, errWrite.Error())
})
Expand All @@ -47,7 +47,7 @@ func TestPrintConfigurationFail(t *testing.T) {
w := &failWriter{failOnCall: 2, err: errWrite}
opts := WorkflowConfig{RegistryLogin: false}

err := PrintConfiguration(opts, "go", w)
err := PrintConfiguration(opts, "go", "", w)

assert.Error(t, err, errWrite.Error())
})
Expand All @@ -56,7 +56,7 @@ func TestPrintConfigurationFail(t *testing.T) {
runtime := "ruby"
expectedErr := fmt.Errorf("no builder support for runtime: %s", runtime)

err := PrintConfiguration(WorkflowConfig{}, runtime, &bytes.Buffer{})
err := PrintConfiguration(WorkflowConfig{}, runtime, "", &bytes.Buffer{})

assert.Error(t, err, expectedErr.Error())
})
Expand Down
23 changes: 14 additions & 9 deletions pkg/ci/github/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
var ErrWorkflowExists = errors.New("existing GitHub workflow detected, overwrite using the --force option")

const (
defaultFuncCliVersion = "knative-v1.22.0"
DefaultFuncCliVersion = "knative-v1.23.0"
DefaultPlatform = "github"
DefaultGitHubWorkflowDir = ".github/workflows"
DefaultGitHubWorkflowFilename = "func-deploy.yaml"
Expand Down Expand Up @@ -45,7 +45,8 @@ type WorkflowConfig struct {
RegistryLoginUrlVar,
RegistryUserVar,
RegistryPassSecret,
RegistryUrlVar string
RegistryUrlVar,
FuncCliVersion string
RegistryLogin,
SelfHostedRunner,
RemoteBuild,
Expand Down Expand Up @@ -74,6 +75,7 @@ func defaultWorkflowConfig() WorkflowConfig {
RegistryUserVar: DefaultRegistryUserVariableName,
RegistryPassSecret: DefaultRegistryPassSecretName,
RegistryUrlVar: DefaultRegistryUrlVariableName,
FuncCliVersion: DefaultFuncCliVersion,
RegistryLogin: DefaultRegistryLogin,
SelfHostedRunner: DefaultSelfHostedRunner,
RemoteBuild: DefaultRemoteBuild,
Expand Down Expand Up @@ -111,6 +113,9 @@ func setEmptyFieldsToDefaults(defaults WorkflowConfig) WorkflowConfig {
if defaults.RegistryUrlVar == "" {
defaults.RegistryUrlVar = DefaultRegistryUrlVariableName
}
if defaults.FuncCliVersion == "" {
defaults.FuncCliVersion = DefaultFuncCliVersion
}

return defaults
}
Expand Down Expand Up @@ -143,15 +148,15 @@ type step struct {
With map[string]string `yaml:"with,omitempty"`
}

func newGitHubWorkflow(cfg WorkflowConfig, runtime string, messageWriter io.Writer) (*workflow, error) {
func newGitHubWorkflow(cfg WorkflowConfig, runtime, builder string, messageWriter io.Writer) (*workflow, error) {
var steps []step
steps = createCheckoutStep(steps)
steps = createRuntimeTestStep(cfg, runtime, messageWriter, steps)
steps = createK8ContextStep(cfg, steps)
steps = createRegistryLoginStep(cfg, steps)
steps = createFuncCLIInstallStep(steps)
steps = createFuncCLIInstallStep(cfg, steps)

steps, err := createFuncDeployStep(cfg, runtime, steps)
steps, err := createFuncDeployStep(cfg, runtime, builder, steps)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -223,20 +228,20 @@ func createRegistryLoginStep(opts WorkflowConfig, steps []step) []step {
return append(steps, *loginToContainerRegistry)
}

func createFuncCLIInstallStep(steps []step) []step {
func createFuncCLIInstallStep(cfg WorkflowConfig, steps []step) []step {
installFuncCli := newStep("Install func cli").
withUses("functions-dev/action@main").
withActionConfig("version", defaultFuncCliVersion).
withActionConfig("version", cfg.FuncCliVersion).
withActionConfig("name", "func")

return append(steps, *installFuncCli)
}

func createFuncDeployStep(opts WorkflowConfig, runtime string, steps []step) ([]step, error) {
func createFuncDeployStep(opts WorkflowConfig, runtime, builder string, steps []step) ([]step, error) {
deployFuncStep := newStep("Deploy function").
withEnv("FUNC_VERBOSE", "true")

builder, err := determineBuilder(runtime, opts.RemoteBuild)
builder, err := determineBuilder(runtime, builder, opts.RemoteBuild)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/ci/github/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestGitHubWorkflow_Export(t *testing.T) {
// WHEN
opts := WorkflowConfig{}

gw, workflowErr := newGitHubWorkflow(WorkflowConfig{}, "go", &bytes.Buffer{})
gw, workflowErr := newGitHubWorkflow(WorkflowConfig{}, "go", "", &bytes.Buffer{})
assert.NilError(t, workflowErr, "unexpected error when creating GitHub Workflow")

exportErr := gw.Export(opts.fnGitHubWorkflowFilepath("path/to/functions"), bufferWriter, true, &bytes.Buffer{})
Expand Down
Loading