Skip to content

Commit ebda635

Browse files
committed
feat: generate github workflow file in config ci
Add functionality to create GitHub Actions workflow directory and file when running config ci command. Includes CIConfig struct for managing workflow paths and permissions, with comprehensive test coverage. Also fixes typo and refactors config tests to use helper functions. Issue SRVOCF-744 Signed-off-by: Stanislav Jakuschevskij <[email protected]>
1 parent 26099be commit ebda635

File tree

6 files changed

+119
-38
lines changed

6 files changed

+119
-38
lines changed

cmd/config.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import (
1212
fn "knative.dev/func/pkg/functions"
1313
)
1414

15-
func NewConfigCmd(loadSaver common.FunctionLoaderSaver, newClient ClientFactory) *cobra.Command {
15+
// TODO(twoGiants): move CIConfig later to a different place, probably to ./pkg/ci/*
16+
func NewConfigCmd(loadSaver common.FunctionLoaderSaver, newClient ClientFactory, TEMP_ciConfig CIConfig) *cobra.Command {
1617
cmd := &cobra.Command{
1718
Use: "config",
1819
Short: "Configure a function",
@@ -38,7 +39,7 @@ or from the directory specified with --path.
3839
cmd.AddCommand(NewConfigLabelsCmd(loadSaver))
3940
cmd.AddCommand(NewConfigEnvsCmd(loadSaver))
4041
cmd.AddCommand(NewConfigVolumesCmd())
41-
cmd.AddCommand(NewConfigCICmd(loadSaver))
42+
cmd.AddCommand(NewConfigCICmd(loadSaver, TEMP_ciConfig))
4243

4344
return cmd
4445
}

cmd/config_ci.go

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
package cmd
22

33
import (
4+
"os"
5+
"path/filepath"
6+
47
"github.com/spf13/cobra"
58
"knative.dev/func/cmd/common"
69
)
710

8-
func NewConfigCICmd(loaderSaver common.FunctionLoaderSaver) *cobra.Command {
11+
func NewConfigCICmd(loaderSaver common.FunctionLoaderSaver, ciConfig CIConfig) *cobra.Command {
912
cmd := &cobra.Command{
1013
Use: "ci",
1114
RunE: func(cmd *cobra.Command, args []string) (err error) {
12-
return runConfigCIGithub(loaderSaver)
15+
return runConfigCIGithub(loaderSaver, ciConfig)
1316
},
1417
}
1518

@@ -18,10 +21,46 @@ func NewConfigCICmd(loaderSaver common.FunctionLoaderSaver) *cobra.Command {
1821
return cmd
1922
}
2023

24+
type CIConfig struct {
25+
GithubWorkflowDir,
26+
GithubWorkflowFile string
27+
dirPerm,
28+
filePerm os.FileMode
29+
}
30+
31+
func NewDefaultCIConfig() CIConfig {
32+
return newCIConfig(
33+
".github/workflows",
34+
"local-build-remote-deploy.yaml",
35+
)
36+
}
37+
38+
func newCIConfig(workflowDir, workflowFile string) CIConfig {
39+
return CIConfig{
40+
workflowDir,
41+
workflowFile,
42+
0755, // o: rwx, g|u: r-x
43+
0644, // o: rw, g|u: r
44+
}
45+
}
46+
2147
func runConfigCIGithub(
2248
loaderSaver common.FunctionLoaderSaver,
49+
ciConfig CIConfig,
2350
) error {
24-
if _, err := initConfigCommand(loaderSaver); err != nil {
51+
f, err := initConfigCommand(loaderSaver)
52+
if err != nil {
53+
return err
54+
}
55+
56+
fnWorkflowDirPath := filepath.Join(f.Root, ciConfig.GithubWorkflowDir)
57+
if err := os.MkdirAll(fnWorkflowDirPath, ciConfig.dirPerm); err != nil {
58+
return err
59+
}
60+
61+
workflowYamlContent := "hello world"
62+
fnWorkflowYamlPath := filepath.Join(fnWorkflowDirPath, ciConfig.GithubWorkflowFile)
63+
if err := os.WriteFile(fnWorkflowYamlPath, []byte(workflowYamlContent), ciConfig.filePerm); err != nil {
2564
return err
2665
}
2766

cmd/config_ci_test.go

Lines changed: 61 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package cmd_test
22

33
import (
4+
"os"
5+
"path/filepath"
46
"testing"
57

68
"github.com/spf13/cobra"
@@ -12,62 +14,98 @@ import (
1214
fnTest "knative.dev/func/pkg/testing"
1315
)
1416

15-
func TestNewConfigCICmd_CommandExists(t *testing.T) {
16-
opts := ciOpts{withMockLoaderSaver: true, args: []string{"ci", "--github"}}
17-
cmd := configCIGithubCmd(t, opts)
17+
func TestNewConfigCICmd_CISubcommandAndGithubOptionExist(t *testing.T) {
18+
// leave 'ci --github' to make this test explicitly use this subcommand
19+
opts := opts{withFuncInTempDir: true, args: []string{"ci", "--github"}}
20+
cmd, _ := setupConfigCmd(t, opts)
1821

19-
err := cmd.Execute()
20-
21-
assert.NilError(t, err)
22+
executeSuccess(t, cmd)
2223
}
2324

2425
func TestNewConfigCICmd_FailsWhenNotInitialized(t *testing.T) {
2526
expectedErrMsg := fn.NewErrNotInitialized(fnTest.Cwd()).Error()
26-
cmd := configCIGithubCmd(t, ciOpts{})
27+
cmd, _ := setupConfigCmd(t, opts{})
2728

2829
err := cmd.Execute()
2930

3031
assert.Error(t, err, expectedErrMsg)
3132
}
3233

3334
func TestNewConfigCICmd_SuccessWhenInitialized(t *testing.T) {
34-
cmd := configCIGithubCmd(t, ciOpts{withFuncInTempDir: true})
35+
cmd, _ := setupConfigCmd(t, opts{withFuncInTempDir: true})
3536

36-
err := cmd.Execute()
37+
executeSuccess(t, cmd)
38+
}
39+
40+
func TestNewConfigCICmd_CreatesGithubWorkflowDirectory(t *testing.T) {
41+
cmd, ta := setupConfigCmd(t, opts{withFuncInTempDir: true})
42+
expectedWorkflowPath := filepath.Join(ta.f.Root, ta.ciConfig.GithubWorkflowDir)
43+
44+
executeSuccess(t, cmd)
45+
46+
_, err := os.Stat(expectedWorkflowPath)
47+
assert.NilError(t, err)
48+
}
49+
50+
func TestNewConfigCICmd_GeneratesLocalWorkflowFile(t *testing.T) {
51+
cmd, ta := setupConfigCmd(t, opts{withFuncInTempDir: true})
52+
expectedWorkflowPath := filepath.Join(ta.f.Root, ta.ciConfig.GithubWorkflowDir)
53+
expectedWorkflowFile := filepath.Join(expectedWorkflowPath, ta.ciConfig.GithubWorkflowFile)
54+
55+
executeSuccess(t, cmd)
3756

57+
_, err := os.Stat(expectedWorkflowPath)
58+
assert.NilError(t, err)
59+
60+
_, err = os.Stat(expectedWorkflowFile)
3861
assert.NilError(t, err)
3962
}
4063

4164
// START: Testing Framework
4265
// ------------------------
43-
type ciOpts struct {
44-
withMockLoaderSaver bool // default: false
45-
withFuncInTempDir bool // default: false
46-
args []string // default: ci --github
66+
type opts struct {
67+
withFuncInTempDir bool
68+
args []string // default: ci --github
69+
}
70+
71+
type testArtifacts struct {
72+
f fn.Function
73+
ciConfig fnCmd.CIConfig
4774
}
4875

49-
func configCIGithubCmd(
76+
func setupConfigCmd(
5077
t *testing.T,
51-
opts ciOpts,
52-
) *cobra.Command {
78+
opts opts,
79+
) (*cobra.Command, testArtifacts) {
5380
t.Helper()
5481

55-
if opts.withFuncInTempDir {
56-
_ = cmdTest.CreateFuncInTempDir(t, "github-ci-func")
82+
ta := testArtifacts{
83+
fn.Function{},
84+
fnCmd.NewDefaultCIConfig(),
5785
}
5886

59-
var loaderSaver common.FunctionLoaderSaver = common.DefaultLoaderSaver
60-
if opts.withMockLoaderSaver {
61-
loaderSaver = newMockLoaderSaver()
87+
if opts.withFuncInTempDir {
88+
ta.f = cmdTest.CreateFuncInTempDir(t, "github-ci-func")
6289
}
6390

6491
args := opts.args
6592
if len(opts.args) == 0 {
6693
args = []string{"ci", "--github"}
6794
}
6895

69-
result := fnCmd.NewConfigCmd(loaderSaver, fnCmd.NewClient)
96+
result := fnCmd.NewConfigCmd(
97+
common.DefaultLoaderSaver,
98+
fnCmd.NewClient,
99+
ta.ciConfig,
100+
)
70101
result.SetArgs(args)
71102

72-
return result
103+
return result, ta
104+
}
105+
106+
func executeSuccess(t *testing.T, cmd *cobra.Command) {
107+
t.Helper()
108+
109+
err := cmd.Execute()
110+
assert.NilError(t, err)
73111
}

cmd/config_git_set.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func (c configGitSetConfig) Configure(f fn.Function) (fn.Function, error) {
263263

264264
// Bubble configure request
265265
//
266-
// The member values on the config object now take absolute precidence
266+
// The member values on the config object now take absolute precedence
267267
// because they include 1) static config 2) user's global config
268268
// 3) Environment variables and 4) flag values (which were set with their
269269
// default being 1-3).

cmd/config_test.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010

1111
"github.com/ory/viper"
12+
"github.com/spf13/cobra"
1213
fnCmd "knative.dev/func/cmd"
1314
fn "knative.dev/func/pkg/functions"
1415
)
@@ -25,8 +26,7 @@ func TestListEnvs(t *testing.T) {
2526
return fn.Function{Run: fn.RunSpec{Envs: envs}}, nil
2627
}
2728

28-
cmd := fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
29-
cmd.SetArgs([]string{"envs", "-o=json", "--path=<path>"})
29+
cmd := setupConfigEnvCmd(mock, "-o=json", "--path=<path>")
3030

3131
var buff bytes.Buffer
3232
cmd.SetOut(&buff)
@@ -47,6 +47,12 @@ func TestListEnvs(t *testing.T) {
4747
}
4848
}
4949

50+
func setupConfigEnvCmd(mock *mockLoaderSaver, args ...string) *cobra.Command {
51+
cmd := fnCmd.NewConfigCmd(mock, fnCmd.NewClient, fnCmd.NewDefaultCIConfig())
52+
cmd.SetArgs(append([]string{"envs"}, args...))
53+
return cmd
54+
}
55+
5056
func TestListEnvAdd(t *testing.T) {
5157
// strings as vars so we can take address of them
5258
foo := "foo"
@@ -68,8 +74,7 @@ func TestListEnvAdd(t *testing.T) {
6874
}
6975

7076
expectedEnvs = []fn.Env{{Name: &foo, Value: &bar}, {Name: &answer, Value: &fortyTwo}}
71-
cmd := fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
72-
cmd.SetArgs([]string{"envs", "add", "--name=answer", "--value=42"})
77+
cmd := setupConfigEnvCmd(mock, "add", "--name=answer", "--value=42")
7378
cmd.SetOut(io.Discard)
7479
cmd.SetErr(io.Discard)
7580

@@ -80,8 +85,7 @@ func TestListEnvAdd(t *testing.T) {
8085

8186
viper.Reset()
8287
expectedEnvs = []fn.Env{{Name: &foo, Value: &bar}, {Name: nil, Value: &configMapExpression}}
83-
cmd = fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
84-
cmd.SetArgs([]string{"envs", "add", "--value={{ configMap:myMap }}"})
88+
cmd = setupConfigEnvCmd(mock, "add", "--value={{ configMap:myMap }}")
8589
cmd.SetOut(io.Discard)
8690
cmd.SetErr(io.Discard)
8791

@@ -91,8 +95,7 @@ func TestListEnvAdd(t *testing.T) {
9195
}
9296

9397
viper.Reset()
94-
cmd = fnCmd.NewConfigCmd(mock, fnCmd.NewClient)
95-
cmd.SetArgs([]string{"envs", "add", "--name=1", "--value=abc"})
98+
cmd = setupConfigEnvCmd(mock, "add", "--name=1", "--value=abc")
9699
cmd.SetOut(io.Discard)
97100
cmd.SetErr(io.Discard)
98101

cmd/root.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ Learn more about Knative at: https://knative.dev`, cfg.Name),
101101
{
102102
Header: "System Commands:",
103103
Commands: []*cobra.Command{
104-
NewConfigCmd(common.DefaultLoaderSaver, newClient),
104+
NewConfigCmd(common.DefaultLoaderSaver, newClient, NewDefaultCIConfig()),
105105
NewLanguagesCmd(newClient),
106106
NewTemplatesCmd(newClient),
107107
NewRepositoryCmd(newClient),

0 commit comments

Comments
 (0)