Skip to content

Commit 60dbeac

Browse files
authored
added git related flags for remote builds (#844)
* added git related flags for remote builds * fix dependency issues * remove context cancel * add # split for git url * account for the use of git args with local build type * fix error message for build type
1 parent 663fd29 commit 60dbeac

5 files changed

Lines changed: 216 additions & 10 deletions

File tree

client.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ func (c *Client) Deploy(ctx context.Context, path string) (err error) {
692692
}
693693

694694
// RunPipeline runs a Pipeline to Build and deploy the Function at path.
695-
func (c *Client) RunPipeline(ctx context.Context, path string) (err error) {
695+
func (c *Client) RunPipeline(ctx context.Context, path string, git Git) (err error) {
696696
go func() {
697697
<-ctx.Done()
698698
c.progressListener.Stopping()
@@ -702,6 +702,7 @@ func (c *Client) RunPipeline(ctx context.Context, path string) (err error) {
702702
if err != nil {
703703
return
704704
}
705+
f.Git = git
705706

706707
// Build and deploy function using Pipeline
707708
err = c.pipelinesProvider.Run(ctx, f)

cmd/deploy.go

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ kn func deploy --registry quay.io/myuser
5151
kn func deploy --image quay.io/myuser/myfunc -n myns
5252
`,
5353
SuggestFor: []string{"delpoy", "deplyo"},
54-
PreRunE: bindEnv("image", "namespace", "path", "registry", "confirm", "build", "push"),
54+
PreRunE: bindEnv("image", "namespace", "path", "registry", "confirm", "build", "push", "git-url", "git-branch", "git-dir"),
5555
}
5656

5757
cmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options (Env: $FUNC_CONFIRM)")
5858
cmd.Flags().StringArrayP("env", "e", []string{}, "Environment variable to set in the form NAME=VALUE. "+
5959
"You may provide this flag multiple times for setting multiple environment variables. "+
6060
"To unset, specify the environment variable name followed by a \"-\" (e.g., NAME-).")
61+
cmd.Flags().StringP("git-url", "g", "", "Repo url to push the code to be built (Env: $FUNC_GIT_URL)")
62+
cmd.Flags().StringP("git-branch", "t", "", "Git branch to be used for remote builds (Env: $FUNC_GIT_BRANCH)")
63+
cmd.Flags().StringP("git-dir", "d", "", "Directory in the repo where the function is located (Env: $FUNC_GIT_DIR)")
6164
cmd.Flags().StringP("image", "i", "", "Full image name in the form [registry]/[namespace]/[name]:[tag] (optional). This option takes precedence over --registry (Env: $FUNC_IMAGE)")
6265
cmd.Flags().StringP("registry", "r", GetDefaultRegistry(), "Registry + namespace part of the image to build, ex 'quay.io/myuser'. The full image name is automatically determined based on the local directory name. If not provided the registry will be taken from func.yaml (Env: $FUNC_REGISTRY)")
6366
cmd.Flags().StringP("build", "b", fn.DefaultBuildType, fmt.Sprintf("Build specifies the way the function should be built. Supported types are %s (Env: $FUNC_BUILD)", fn.SupportedBuildTypes(true)))
@@ -108,13 +111,6 @@ func runDeploy(cmd *cobra.Command, _ []string, newClient ClientFactory) (err err
108111
if err != nil {
109112
return err
110113
}
111-
112-
// update function config if build type has been changed
113-
// don't store type `disabled` as it should be used only as a parameter in `func deploy`
114-
// and not stored in function config
115-
if function.BuildType != config.BuildType && config.BuildType != fn.BuildTypeDisabled {
116-
function.BuildType = config.BuildType
117-
}
118114
} else {
119115
currentBuildType = function.BuildType
120116
}
@@ -169,11 +165,33 @@ func runDeploy(cmd *cobra.Command, _ []string, newClient ClientFactory) (err err
169165

170166
switch currentBuildType {
171167
case fn.BuildTypeLocal, "":
168+
if config.GitURL != "" || config.GitDir != "" || config.GitBranch != "" {
169+
return fmt.Errorf("remote git arguments require the --build=git flag")
170+
}
172171
if err := client.Build(cmd.Context(), config.Path); err != nil {
173172
return err
174173
}
175174
case fn.BuildTypeGit:
176-
return client.RunPipeline(cmd.Context(), config.Path)
175+
git := function.Git
176+
177+
if config.GitURL != "" {
178+
git.URL = &config.GitURL
179+
if strings.Contains(config.GitURL, "#") {
180+
parts := strings.Split(config.GitURL, "#")
181+
git.URL = &parts[0]
182+
git.Revision = &parts[1]
183+
}
184+
}
185+
186+
if config.GitBranch != "" {
187+
git.Revision = &config.GitBranch
188+
}
189+
190+
if config.GitDir != "" {
191+
git.ContextDir = &config.GitDir
192+
}
193+
194+
return client.RunPipeline(cmd.Context(), config.Path, git)
177195
case fn.BuildTypeDisabled:
178196
// nothing needed to be done for `build=disabled`
179197
default:
@@ -282,6 +300,15 @@ type deployConfig struct {
282300

283301
// Envs passed via cmd to removed
284302
EnvToRemove []string
303+
304+
// Git repo url for remote builds
305+
GitURL string
306+
307+
// Git branch for remote builds
308+
GitBranch string
309+
310+
// Directory in the git repo where the function is located
311+
GitDir string
285312
}
286313

287314
// newDeployConfig creates a buildConfig populated from command flags and
@@ -309,6 +336,9 @@ func newDeployConfig(cmd *cobra.Command) (deployConfig, error) {
309336
Push: viper.GetBool("push"),
310337
EnvToUpdate: envToUpdate,
311338
EnvToRemove: envToRemove,
339+
GitURL: viper.GetString("git-url"),
340+
GitBranch: viper.GetString("git-branch"),
341+
GitDir: viper.GetString("git-dir"),
312342
}, nil
313343
}
314344

cmd/deploy_test.go

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
package cmd
2+
3+
import (
4+
"context"
5+
"os"
6+
"testing"
7+
8+
"github.com/ory/viper"
9+
"k8s.io/utils/pointer"
10+
fn "knative.dev/kn-plugin-func"
11+
"knative.dev/kn-plugin-func/mock"
12+
)
13+
14+
func Test_runDeploy(t *testing.T) {
15+
tests := []struct {
16+
name string
17+
gitURL string
18+
gitBranch string
19+
gitDir string
20+
buildType string
21+
funcFile string
22+
expectFileURL *string
23+
expectFileBranch *string
24+
expectFileContextDir *string
25+
expectCallURL *string
26+
expectCallBranch *string
27+
expectCallContextDir *string
28+
errString string
29+
}{
30+
{
31+
name: "Git arguments don't get saved to func.yaml but are used in the pipeline invocation",
32+
gitURL: "git@github.com:knative-sandbox/kn-plugin-func.git",
33+
gitBranch: "main",
34+
gitDir: "func",
35+
buildType: fn.BuildTypeGit,
36+
funcFile: `name: test-func
37+
runtime: go
38+
created: 2009-11-10 23:00:00`,
39+
expectCallURL: pointer.StringPtr("git@github.com:knative-sandbox/kn-plugin-func.git"),
40+
expectCallBranch: pointer.StringPtr("main"),
41+
expectCallContextDir: pointer.StringPtr("func"),
42+
},
43+
{
44+
name: "Git url gets split when in the format url#branch",
45+
gitURL: "git@github.com:knative-sandbox/kn-plugin-func.git#main",
46+
gitDir: "func",
47+
buildType: fn.BuildTypeGit,
48+
funcFile: `name: test-func
49+
runtime: go
50+
created: 2009-11-10 23:00:00`,
51+
expectCallURL: pointer.StringPtr("git@github.com:knative-sandbox/kn-plugin-func.git"),
52+
expectCallBranch: pointer.StringPtr("main"),
53+
expectCallContextDir: pointer.StringPtr("func"),
54+
},
55+
{
56+
name: "Git arguments override func.yaml but don't get saved",
57+
gitURL: "git@github.com:knative-sandbox/kn-plugin-func.git",
58+
gitBranch: "main",
59+
gitDir: "func",
60+
funcFile: `name: test-func
61+
runtime: go
62+
created: 2009-11-10 23:00:00
63+
build: git
64+
git:
65+
url: git@github.com:my-repo/my-function.git
66+
revision: master
67+
contextDir: pwd`,
68+
expectCallURL: pointer.StringPtr("git@github.com:knative-sandbox/kn-plugin-func.git"),
69+
expectCallBranch: pointer.StringPtr("main"),
70+
expectCallContextDir: pointer.StringPtr("func"),
71+
expectFileURL: pointer.StringPtr("git@github.com:my-repo/my-function.git"),
72+
expectFileBranch: pointer.StringPtr("master"),
73+
expectFileContextDir: pointer.StringPtr("pwd"),
74+
},
75+
{
76+
name: "Git properties work without arguments",
77+
funcFile: `name: test-func
78+
runtime: go
79+
created: 2009-11-10 23:00:00
80+
build: git
81+
git:
82+
url: git@github.com:my-repo/my-function.git
83+
revision: master
84+
contextDir: pwd`,
85+
expectFileURL: pointer.StringPtr("git@github.com:my-repo/my-function.git"),
86+
expectFileBranch: pointer.StringPtr("master"),
87+
expectFileContextDir: pointer.StringPtr("pwd"),
88+
expectCallURL: pointer.StringPtr("git@github.com:my-repo/my-function.git"),
89+
expectCallBranch: pointer.StringPtr("master"),
90+
expectCallContextDir: pointer.StringPtr("pwd"),
91+
},
92+
{
93+
name: "check error when providing git flags with buildType local",
94+
gitURL: "git@github.com:my-repo/my-function.git",
95+
buildType: "local",
96+
funcFile: `name: test-func
97+
runtime: go
98+
created: 2009-11-10 23:00:00`,
99+
errString: "remote git arguments require the --build=git flag",
100+
},
101+
}
102+
for _, tt := range tests {
103+
t.Run(tt.name, func(t *testing.T) {
104+
var captureFn fn.Function
105+
pipeline := &mock.PipelinesProvider{
106+
RunFn: func(f fn.Function) error {
107+
captureFn = f
108+
return nil
109+
},
110+
}
111+
deployer := mock.NewDeployer()
112+
defer fromTempDir(t)()
113+
cmd := NewDeployCmd(func(opts ClientOptions) *fn.Client {
114+
return fn.New(
115+
fn.WithPipelinesProvider(pipeline),
116+
fn.WithDeployer(deployer),
117+
)
118+
})
119+
120+
viper.SetDefault("git-url", tt.gitURL)
121+
viper.SetDefault("git-branch", tt.gitBranch)
122+
viper.SetDefault("git-dir", tt.gitDir)
123+
viper.SetDefault("build", tt.buildType)
124+
viper.SetDefault("registry", "docker.io/tigerteam")
125+
126+
// set test case's func.yaml
127+
if err := os.WriteFile("func.yaml", []byte(tt.funcFile), os.ModePerm); err != nil {
128+
t.Fatal(err)
129+
}
130+
131+
ctx := context.TODO()
132+
133+
_, err := cmd.ExecuteContextC(ctx)
134+
if err != nil {
135+
if tt.errString == "" {
136+
t.Fatalf("Problem executing command: %v", err)
137+
} else if err := err.Error(); tt.errString != err {
138+
t.Fatalf("Error expected to be %v but was %v", tt.errString, err)
139+
}
140+
}
141+
142+
fileFunction, err := fn.NewFunction(".")
143+
144+
if err != nil {
145+
t.Fatalf("problem creating function: %v", err)
146+
}
147+
148+
{
149+
if fileURL, expectedURL := pointer.StringPtrDerefOr(fileFunction.Git.URL, ""), pointer.StringPtrDerefOr(tt.expectFileURL, ""); fileURL != expectedURL {
150+
t.Fatalf("file Git URL expected to be (%v) but was (%v)", expectedURL, fileURL)
151+
}
152+
if fileBranch, expectedBranch := pointer.StringPtrDerefOr(fileFunction.Git.Revision, ""), pointer.StringPtrDerefOr(tt.expectFileBranch, ""); fileBranch != expectedBranch {
153+
t.Fatalf("file Git branch expected to be (%v) but was (%v)", expectedBranch, fileBranch)
154+
}
155+
if fileDir, expectedDir := pointer.StringPtrDerefOr(fileFunction.Git.ContextDir, ""), pointer.StringPtrDerefOr(tt.expectFileContextDir, ""); fileDir != expectedDir {
156+
t.Fatalf("file Git contextDir expected to be (%v) but was (%v)", expectedDir, fileDir)
157+
}
158+
}
159+
160+
{
161+
if caputureURL, expectedURL := pointer.StringPtrDerefOr(captureFn.Git.URL, ""), pointer.StringPtrDerefOr(tt.expectCallURL, ""); caputureURL != expectedURL {
162+
t.Fatalf("call Git URL expected to be (%v) but was (%v)", expectedURL, caputureURL)
163+
}
164+
if captureBranch, expectedBranch := pointer.StringPtrDerefOr(captureFn.Git.Revision, ""), pointer.StringPtrDerefOr(tt.expectCallBranch, ""); captureBranch != expectedBranch {
165+
t.Fatalf("call Git Branch expected to be (%v) but was (%v)", expectedBranch, captureBranch)
166+
}
167+
if captureDir, expectedDir := pointer.StringPtrDerefOr(captureFn.Git.ContextDir, ""), pointer.StringPtrDerefOr(tt.expectCallContextDir, ""); captureDir != expectedDir {
168+
t.Fatalf("call Git Dir expected to be (%v) but was (%v)", expectedDir, captureDir)
169+
}
170+
}
171+
})
172+
}
173+
}

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ require (
3737
k8s.io/api v0.22.5
3838
k8s.io/apimachinery v0.22.5
3939
k8s.io/client-go v0.22.5
40+
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a
4041
knative.dev/client v0.27.0
4142
knative.dev/eventing v0.27.2
4243
knative.dev/hack v0.0.0-20220216040439-0456e8bf6547

vendor/modules.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,7 @@ k8s.io/kube-openapi/pkg/common
12571257
k8s.io/kube-openapi/pkg/util/proto
12581258
k8s.io/kube-openapi/pkg/validation/spec
12591259
# k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a
1260+
## explicit
12601261
k8s.io/utils/buffer
12611262
k8s.io/utils/integer
12621263
k8s.io/utils/pointer

0 commit comments

Comments
 (0)