diff --git a/.gitignore b/.gitignore index f25991ab63..62019b2741 100644 --- a/.gitignore +++ b/.gitignore @@ -34,7 +34,7 @@ __pycache__ # E2E Tests /e2e/testdata/default_home/go /e2e/testdata/default_home/.cache - + # Editors .vscode .idea diff --git a/cmd/ci/config.go b/cmd/ci/config.go index 8b559b784a..e778c0f333 100644 --- a/cmd/ci/config.go +++ b/cmd/ci/config.go @@ -38,6 +38,12 @@ const ( UseRegistryLoginFlag = "use-registry-login" DefaultUseRegistryLogin = true + WorkflowDispatchFlag = "workflow-dispatch" + DefaultWorkflowDispatch = false + + UseRemoteBuildFlag = "remote" + DefaultUseRemoteBuild = false + UseSelfHostedRunnerFlag = "self-hosted-runner" DefaultUseSelfHostedRunner = false ) @@ -55,7 +61,9 @@ type CIConfig struct { registryPassSecret, registryUrlVar string useRegistryLogin, - useSelfHostedRunner bool + useSelfHostedRunner, + useRemoteBuild, + useWorkflowDispatch bool } func NewCIGitHubConfig() CIConfig { @@ -72,6 +80,8 @@ func NewCIGitHubConfig() CIConfig { registryUrlVar: viper.GetString(RegistryUrlVariableNameFlag), useRegistryLogin: viper.GetBool(UseRegistryLoginFlag), useSelfHostedRunner: viper.GetBool(UseSelfHostedRunnerFlag), + useRemoteBuild: viper.GetBool(UseRemoteBuildFlag), + useWorkflowDispatch: viper.GetBool(WorkflowDispatchFlag), } } @@ -103,6 +113,14 @@ func (cc *CIConfig) UseSelfHostedRunner() bool { return cc.useSelfHostedRunner } +func (cc *CIConfig) UseRemoteBuild() bool { + return cc.useRemoteBuild +} + +func (cc *CIConfig) UseWorkflowDispatch() bool { + return cc.useWorkflowDispatch +} + func (cc *CIConfig) KubeconfigSecret() string { return cc.kubeconfigSecret } diff --git a/cmd/ci/workflow.go b/cmd/ci/workflow.go index 2e707f125d..22513e657c 100644 --- a/cmd/ci/workflow.go +++ b/cmd/ci/workflow.go @@ -14,7 +14,8 @@ type githubWorkflow struct { } type workflowTriggers struct { - Push *pushTrigger `yaml:"push,omitempty"` + Push *pushTrigger `yaml:"push,omitempty"` + WorkflowDispatch *struct{} `yaml:"workflow_dispatch,omitempty"` } type pushTrigger struct { @@ -34,8 +35,9 @@ type step struct { } func NewGitHubWorkflow(conf CIConfig) *githubWorkflow { - runsOn := createRunsOn(conf.UseSelfHostedRunner()) - pushTrigger := createPushTrigger(conf.Branch()) + name := createWorkflowName(conf) + runsOn := createRunsOn(conf) + pushTrigger := createPushTrigger(conf) var steps []step steps = createCheckoutStep(steps) @@ -45,7 +47,7 @@ func NewGitHubWorkflow(conf CIConfig) *githubWorkflow { steps = createFuncDeployStep(conf, steps) return &githubWorkflow{ - Name: conf.WorkflowName(), + Name: name, On: pushTrigger, Jobs: map[string]job{ "deploy": { @@ -56,17 +58,30 @@ func NewGitHubWorkflow(conf CIConfig) *githubWorkflow { } } -func createRunsOn(useSelfHostedRunner bool) string { +func createWorkflowName(conf CIConfig) string { + result := conf.WorkflowName() + if conf.UseRemoteBuild() { + result = "Remote Func Deploy" + } + + return result +} + +func createRunsOn(conf CIConfig) string { runsOn := "ubuntu-latest" - if useSelfHostedRunner { + if conf.UseSelfHostedRunner() { runsOn = "self-hosted" } return runsOn } -func createPushTrigger(branch string) workflowTriggers { +func createPushTrigger(conf CIConfig) workflowTriggers { result := workflowTriggers{ - Push: &pushTrigger{Branches: []string{branch}}, + Push: &pushTrigger{Branches: []string{conf.Branch()}}, + } + + if conf.UseWorkflowDispatch() { + result.WorkflowDispatch = &struct{}{} } return result @@ -102,26 +117,31 @@ func createRegistryLoginStep(conf CIConfig, steps []step) []step { return append(steps, *loginToContainerRegistry) } +func createFuncCLIInstallStep(steps []step) []step { + installFuncCli := newStep("Install func cli"). + withUses("functions-dev/action@main"). + withActionConfig("version", "knative-v1.20.1"). + withActionConfig("name", "func") + + return append(steps, *installFuncCli) +} + func createFuncDeployStep(conf CIConfig, steps []step) []step { + runFuncDeploy := "func deploy" + if conf.UseRemoteBuild() { + runFuncDeploy += " --remote" + } + registryUrl := newVariable(conf.RegistryUrlVar()) if conf.UseRegistryLogin() { registryUrl = newVariable(conf.RegistryLoginUrlVar()) + "/" + newVariable(conf.RegistryUserVar()) } deployFunc := newStep("Deploy function"). - withRun("func deploy --registry=" + registryUrl + " -v") + withRun(runFuncDeploy + " --registry=" + registryUrl + " -v") return append(steps, *deployFunc) } -func createFuncCLIInstallStep(steps []step) []step { - installFuncCli := newStep("Install func cli"). - withUses("gauron99/knative-func-action@main"). - withActionConfig("version", "knative-v1.19.1"). - withActionConfig("name", "func") - - return append(steps, *installFuncCli) -} - func newStep(name string) *step { return &step{Name: name} } diff --git a/cmd/config_ci.go b/cmd/config_ci.go index f37bd28997..e28b98c728 100644 --- a/cmd/config_ci.go +++ b/cmd/config_ci.go @@ -16,6 +16,8 @@ func NewConfigCICmd(loaderSaver common.FunctionLoaderSaver, writer ci.WorkflowWr PreRunE: bindEnv( ci.PathFlag, ci.UseRegistryLoginFlag, + ci.WorkflowDispatchFlag, + ci.UseRemoteBuildFlag, ci.UseSelfHostedRunnerFlag, ci.WorkflowNameFlag, ci.BranchFlag, @@ -38,6 +40,19 @@ func NewConfigCICmd(loaderSaver common.FunctionLoaderSaver, writer ci.WorkflowWr "Add a registry login step in the github workflow", ) + cmd.Flags().Bool( + ci.WorkflowDispatchFlag, + ci.DefaultWorkflowDispatch, + "Add a workflow dispatch trigger for manual workflow execution", + ) + _ = cmd.Flags().MarkHidden(ci.WorkflowDispatchFlag) + + cmd.Flags().Bool( + ci.UseRemoteBuildFlag, + ci.DefaultUseRemoteBuild, + "Build the function on a Tekton-enabled cluster", + ) + cmd.Flags().Bool( ci.UseSelfHostedRunnerFlag, ci.DefaultUseSelfHostedRunner, diff --git a/cmd/config_ci_test.go b/cmd/config_ci_test.go index dacdc58924..be6f683cfb 100644 --- a/cmd/config_ci_test.go +++ b/cmd/config_ci_test.go @@ -93,6 +93,33 @@ func TestNewConfigCICmd_WorkflowHasNoRegistryLogin(t *testing.T) { assert.Assert(t, yamlContains(result.gwYamlString, "--registry=${{ vars.REGISTRY_URL }}")) } +func TestNewConfigCICmd_RemoteBuildAndDeployWorkflow(t *testing.T) { + // GIVEN + opts := unitTestOpts() + opts.args = append(opts.args, "--remote") + + // WHEN + result := runConfigCiCmd(t, opts) + + // THEN + assert.NilError(t, result.executeErr) + assert.Assert(t, yamlContains(result.gwYamlString, "Remote Func Deploy")) + assert.Assert(t, yamlContains(result.gwYamlString, "func deploy --remote")) +} + +func TestNewConfigCICmd_HasWorkflowDispatch(t *testing.T) { + // GIVEN + opts := unitTestOpts() + opts.args = append(opts.args, "--workflow-dispatch") + + // WHEN + result := runConfigCiCmd(t, opts) + + // THEN + assert.NilError(t, result.executeErr) + assert.Assert(t, yamlContains(result.gwYamlString, "workflow_dispatch")) +} + // --------------------- // END: Broad Unit Tests @@ -303,8 +330,8 @@ func assertDefaultWorkflow(t *testing.T, actualGw string) { assert.Assert(t, yamlContains(actualGw, "password: ${{ secrets.REGISTRY_PASSWORD }}")) assert.Assert(t, yamlContains(actualGw, "Install func cli")) - assert.Assert(t, yamlContains(actualGw, "gauron99/knative-func-action@main")) - assert.Assert(t, yamlContains(actualGw, "version: knative-v1.19.1")) + assert.Assert(t, yamlContains(actualGw, "functions-dev/action@main")) + assert.Assert(t, yamlContains(actualGw, "version: knative-v1.20.1")) assert.Assert(t, yamlContains(actualGw, "name: func")) assert.Assert(t, yamlContains(actualGw, "Deploy function")) diff --git a/docs/reference/func_config_ci.md b/docs/reference/func_config_ci.md index 06595ce8cf..1c87a5fbd0 100644 --- a/docs/reference/func_config_ci.md +++ b/docs/reference/func_config_ci.md @@ -1,6 +1,6 @@ ## func config ci -Generate a Github Workflow for function deployment +Generate a GitHub Workflow for function deployment ``` func config ci @@ -9,9 +9,18 @@ func config ci ### Options ``` - -h, --help help for ci - -p, --path string Path to the function. Default is current directory ($FUNC_PATH) - --workflow-name string Use a custom workflow name (default "Func Deploy") + --branch string Use a custom branch name in the workflow (default "main") + -h, --help help for ci + --kubeconfig-secret-name string Use a custom secret name in the workflow, e.g. secret.YOUR_CUSTOM_KUBECONFIG (default "KUBECONFIG") + -p, --path string Path to the function. Default is current directory ($FUNC_PATH) + --registry-login-url-variable-name string Use a custom registry login url variable name in the workflow, e.g. vars.YOUR_REGISTRY_LOGIN_URL (default "REGISTRY_LOGIN_URL") + --registry-pass-secret-name string Use a custom registry pass secret name in the workflow, e.g. secret.YOUR_REGISTRY_PASSWORD (default "REGISTRY_PASSWORD") + --registry-url-variable-name string Use a custom registry url variable name in the workflow, e.g. vars.YOUR_REGISTRY_URL (default "REGISTRY_URL") + --registry-user-variable-name string Use a custom registry user variable name in the workflow, e.g. vars.YOUR_REGISTRY_USER (default "REGISTRY_USERNAME") + --remote Build the function on a Tekton-enabled cluster + --self-hosted-runner Use a 'self-hosted' runner instead of the default 'ubuntu-latest' for local runner execution + --use-registry-login Add a registry login step in the github workflow (default true) + --workflow-name string Use a custom workflow name (default "Func Deploy") ``` ### SEE ALSO